【问题标题】:Clear stdin buffer (memory footprint)清除标准输入缓冲区(内存占用)
【发布时间】:2013-07-31 01:02:52
【问题描述】:

在我的情况下,我的应用程序的用户被要求输入密码才能启动它。要获取密码,我只需使用:

char c;  
std::string password;
while ...  // until the end of entry
{
    c = fgetc(stdin);
    password += c;
}

检查密码后,我会销毁该变量,因此无法使用我的程序的核心映像检索它。例如,如果有人使用“gcore”命令,然后在生成的核心中搜索密码,它不会找到它。

但就我而言,我仍然可以检索密码值,因为它似乎仍在标准输入缓冲区中。

所以我的问题是如何清除标准输入缓冲区以使用户键入的值不再在内存中可用?

对于我已经尝试过的信息:fflush、__fpurge、fwrite(从标准输入流的开始位置开始)......似乎没有任何效果。

提前谢谢你。

【问题讨论】:

  • 不要尝试fflush(stdin),这可能是未定义的行为。首先使用int c 而不是char
  • stdin 中是否存在完整密码 我认为没有。
  • 简短的回答是,其中有足够的内容超出了您的控制范围,您可能无法保证,至少在可移植代码中是这样。为了接近,您可能必须(至少)指定您关心的编译器、库和操作系统。
  • 如果这对您很重要,您可能不应该将密码存储在 std::string 中(您无法直接控制是否复制其内部缓冲区或是否将其内存归零在它被释放之前)。
  • 老实说,如果你不相信你的地址空间是安全的,那么无论如何你都会被吓到。因为即使您清除缓冲区,它也可能仍在内核缓冲区中。

标签: c++ c memory stdin core


【解决方案1】:

我的回答是:不要使用标准 I/O 流 - 改用原始文件 I/O:

read(STDIN_FILENO, ...)

您必须自己进行行缓冲,但您可以保证库中没有任何内容保留您输入的缓冲区。

【讨论】:

    【解决方案2】:

    你检查过这个吗? How do I flush the cin buffer?

    试试:

    cin.clear();
    

    【讨论】:

    • 这也不会从输入缓冲区中删除内容。
    【解决方案3】:

    既然您使用的是 C++,为什么不直接使用 std::string 类并直接使用 cin>>password。这将消除在键入每个字符时使用单独的变量来保存每个字符的需要。如果在那之后,您仍然担心stdin 的内容是否可用,请使用:

    fseek(stdin,0,SEEK_END);
    

    在阅读结束时。在我看来,这比编写旧的(在我看来,不太安全的)C 方法更容易使用,并且允许您更好地使用 C++ 库。

    编写 C++ 时的一般经验法则:除非绝对必须,否则不要使用 C。

    【讨论】:

    • stdin,当它连接到控制台或管道时,不可搜索。所以这实际上不太可能有太大帮助。
    • @MatsPetersson 确实如此,因为使用 C++ 类改变了输入和输出的完成方式。而不是scanf("%s", password);,您现在可以简单地使用cin>>password;,它更清洁并充分刷新缓冲区。刷新输入缓冲区的唯一真正原因是在使用 getline(password); 时,因为它使用 '\n' 作为其分隔符,并且大多数输入函数通常将其留在缓冲区中。
    • 绝对不能保证作为缓冲区内容的密码不仍然存在,但(或在系统中某一层或另一层的其他缓冲区中)。当然,除非您碰巧知道密码是什么(在这种情况下,密码是无用的)或知道这些缓冲区的位置,否则找到它会非常棘手。
    • @MatsPetersson 好吧,既然我们现在谈论的是监控缓冲区内容,我想现在说任何熟练的黑客都可以对控制台进行键盘记录,然后再安全就无关紧要了。你的程序是或者它对其他程序隐藏了它的内存,因为键盘记录器会在那里有密码!
    【解决方案4】:

    我对 C++ 完全一无所知,但我在 C 中所做的要么是 DoxyLover 建议的,要么,如果你想坚持使用标准库......使用它而不缓冲,谷歌搜索“c++ cin unbuffered”毕竟确实给出了一些结果

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多