我试图创建一个C / C ++程序,尽可能多地转储未初始化的内存。 该程序必须由本地用户运行,即以用户模式运行。
使用malloc不起作用: Why does malloc initialize the values to 0 in gcc?
目标不是将此数据用作随机种子。
操作系统是否始终确保您无法看到剩余的"从其他过程?
如果可能,我想参考实施或进一步解释。
答案 0 :(得分:11)
最常见的多用户操作系统(现代Windows,Linux,其他Unix变体,VMS - 可能是所有具有虚拟内存概念的操作系统)都试图将进程彼此隔离以确保安全性。如果进程A可以读取进程B的剩余内存,则它可以访问它不应该具有的用户数据,因此这些操作系统将在它们可用于新进程之前清除内存页面。您可能必须具有提升的权限才能获得未初始化的RAM,解决方案可能取决于它是哪个操作系统。
嵌入式操作系统,DOS和Windows的古老版本通常没有保护内存的工具。但他们也没有虚拟内存或强大的进程隔离概念。在这些方面,只需通过常用方法(例如malloc
)分配内存就可以在不需要做任何特殊操作的情况下为您提供未初始化的内存。
有关Windows的更多信息,您可以搜索Windows zero page thread
以了解操作系统线程,其唯一的工作是在未使用的页面中写入零,以便可以再次发送它们。此外,Windows还有一个名为superfetch
的功能,可以使用Windows预测您即将打开的文件填充未使用的RAM。如果您分配了内存并且Windows决定为您提供超级抓取页面,则您可能会看到您无法读取的文件内容。这是在将页面分配给进程之前必须清除页面的另一个原因。
答案 1 :(得分:6)
你有未初始化的记忆。它包含不确定的值。在你的情况下,这些值都是0.没有任何意外。如果你想要伪随机数,请使用PRNG。如果您需要真正的随机数/熵,请使用合法的随机源,例如操作系统的随机数设备(例如/dev/urandom
)或API。
答案 2 :(得分:3)
正确的操作系统不会为进程提供未初始化的内存。
你最接近的是堆栈。当映射到进程时,该内存将被初始化,但其中大部分将被覆盖。
答案 3 :(得分:2)
这是常识。我们也不需要记录1 + 1 = 2。
在进程之间泄漏机密的操作系统对许多应用程序来说都是无用的。因此,如果想要成为通用的通用操作系统,它将隔离进程。跟踪哪些页面可能包含秘密以及哪些页面是安全的将是太多的工作并且太容易出错,所以我们假设每个曾经使用过的页面都是脏的并且包含秘密。使用垃圾初始化新页面比仅使用一个值初始化它们要慢,因此不使用随机垃圾。最有用的值为零(例如,对于calloc
或bss),因此将新页面清零以清除它们。
没有其他办法可以做到。
可能有专门的操作系统没有这样做,并且在进程之间泄漏秘密(例如,可能需要实时要求)。一些较旧的操作系统没有良好的内存管理和权限隔离。此外,malloc
将在同一进程中重用以前释放的内存。因此,malloc
将被记录为包含未初始化的垃圾。但这并不意味着您将能够从通用操作系统上的其他进程获得未初始化的内存。
我想一个简单的经验法则是:如果您的操作系统曾要求您输入密码,则不会向进程提供未初始化的页面,并且由于清零是初始化页面的唯一合理方式,因此它们将归零。