【问题标题】:Does VirtualLock really do what it say?VirtualLock 真的如其所言吗?
【发布时间】:2018-04-05 15:44:22
【问题描述】:

出于安全考虑,我目前正在研究如何避免在程序执行期间交换某些数据块。

据我搜索,我在 Linux 上找到了 mlock,这似乎正是我需要的工具,在 Windows 上找到了 VirtualLock。

对于后者,我发现了不同的意见。 the documentation 表示

进程已锁定的页面保留在物理内存中,直到进程解锁或终止。

但是,人们似乎不同意并声称VirtualLock only lock the memory in the working set of the process,因此只要程序的至少一个线程正在运行,内存就不会被交换。这意味着,无论出于何种原因,每个线程都被阻塞,数据可能会被换出。

谁能为我澄清这一点? 如果文档确实有误,这只是理论上的风险,还是我应该认真考虑?我可以使用什么解决方案真正将内存锁定在 RAM 中?

如果有帮助,我的目标是确定在加密应用程序中擦除内存的好做法和坏做法

编辑this article 回答问题,肯定是锁在内存中。然而它提出了另一个问题:如何摆脱缓存问题?我最终可能会得到多个数据副本...

【问题讨论】:

  • 我认为这可以解释:每个版本的 Windows 对进程可以锁定的最大页面数都有限制。这个限制是故意很小的,以避免严重的性能下降。需要锁定大量页面的应用程序必须首先调用 SetProcessWorkingSetSize 函数来增加它们的最小和最大工作集大小。进程可以锁定的最大页数等于其最小工作集中的页数减去一个小开销。
  • 除了交换之外,您还需要担心休眠或混合睡眠会将 RAM 内容保存到磁盘。
  • 你为什么要打扰?在用户模式下,anything 会延迟您的进程,而不仅仅是内存页面被换出。如果您需要实时性能,则需要进入内核模式。
  • @drescherjm 它并没有真正回答我的问题,我知道这个限制,但是我的阅读(我在我的帖子中添加了一个链接),但这不是我的意思。我担心 VirtualLock 在“锁定”内存时会做什么。
  • @IanAbbott 我知道休眠问题,我一定会检查混合睡眠,感谢您指出这一点。

标签: c++ c windows


【解决方案1】:

如果您需要安全性,您实际上有两种选择:

  1. 移至内核模式
  2. 使用CryptProtectMemory加密内存中的数据

问题在于,即使您将 ram 锁定在适当的位置,如果其他进程具有正确的访问权限,它们也可以读取它。有一些方法可以使用进程隔离来防止这种情况发生,但它们需要访问 MS 限制为 DRM 开发人员的 SDK。

请记住,当您使用完内存后,您需要使用 SecureZeroMemory 将其清除,编译器不会优化掉它。

【讨论】:

  • 您可以设置进程的自主安全性,以防止非管理员用户获得 VM 读取访问权限。我不会担心具有调试权限的管理员和用户。除了“知识产权”问题之外,他们拥有合法权利。
  • @eryksun 你有一个如何做到这一点的例子的链接吗?我会把它合并到答案中
【解决方案2】:

使用飞地怎么样? https://openenclave.io/sdk/ Tldr:它使用了一个新的 CPU 特性,允许将一定范围的内存与内核模式代码隔离开来:

“飞地应用程序将自身划分为两个组件(1)一个不受信任的组件(称为主机)和(2)一个受信任的组件(称为飞地)。飞地是一个安全容器,其内存受到保护,不受外部实体的影响。 enclave。这些保护允许 enclave 执行安全计算,并保证机密不会被泄露。"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 2012-08-08
    • 2010-09-17
    • 2013-10-13
    • 1970-01-01
    相关资源
    最近更新 更多