【问题标题】:Persistent shared memory post process-termination winapi持久共享内存后处理终止 winapi
【发布时间】:2018-09-29 08:04:44
【问题描述】:

我想做一些类似映射共享内存 (CreateFileMapping()) 的事情,但我希望虚拟文件在进程终止后继续存在,并且在我明确删除它之前可以被其他进程读取。

该应用程序与存储密码有关,因此我不想使用物理文件或其他易于读取的持久方法(如注册表)。我想将数据泵入内存,保留在那里直到被删除,并在需要时从中读取。它应该会在重新启动时消失。

【问题讨论】:

  • 这会给您一种安全的错觉,但会增加您的复杂性。
  • 听起来你在重新发明轮子。您也可以使用 PasswordCredential 类来存储您的密码,并从专业级安全性中受益,而无需尝试自己动手。
  • 是的……实际上那是我(没有意识到我)正在重新发明的轮子。谢谢你指点我。不过,讨论确实很棒,因为很高兴知道还有其他方法可以使用永久句柄将数据插入持久共享内存。谢谢大家,指导。设置 SeCreatePermanentPrivilege 后,我能够得到这个工作
  • 句柄是对Section对象的引用。您没有使手柄永久化。您正在使 Section 永久化,这是可能的,因为它在对象命名空间中命名。永久标志防止内核的对象管理器删除名称,从而保持对象被引用。
  • 仅供参考,如果您没有在会话 0 中的服务或任务中创建部分,请使用“全局”链接,例如L"Global\\SectionName"(仅限反斜杠;正斜杠是名称字符)。 Windows 为会话的命名对象目录“\Sessions\[会话标识符]\BaseNamedObjects”创建相对于RootDirectory 句柄的命名内核对象,并且“全局”是该目录中的一个 SymbolicLink 对象,它重新解析为会话 0“\ BaseNamedObjects" 全局对象目录。

标签: winapi shared-memory


【解决方案1】:

当一个进程终止时,它仍然打开的任何内核句柄都会被操作系统自动关闭。因此,内存映射对象能够继续存在的唯一方法是,如果另一个进程拥有同一个映射对象的打开句柄。当所有进程都关闭了映射对象的句柄时,它就完全消失了。

您可以考虑创建一个单独的服务应用程序在后台运行并分配实际的内存对象,然后让进程在服务运行时共享内存对象。

否则,要真正分配一块持续到重新启动的内存块,无论是谁分配的,您都可以使用 RAM 磁盘并将数据存储在 RAM 中的“文件”中,每个进程都可以打开“文件”需要的时候。当机器重新启动时,RAM 被清除干净。

不过,将数据放入内存并不比将其存储在文件或注册表中更安全。如果您担心安全性,只需加密数据并在需要时解密即可。

【讨论】:

  • 是的......我考虑过分叉一个新进程并让它保存文件映射,但我不想仅仅为了保持共享内存而持有一个进程。共享内存比注册表更安全,因为 regedit 比检查映射文件或共享内存的工具更容易访问(对于最终用户)。是否有用于创建 ramfile 的 Win32API?我不想只加密和解密的原因是我正在传递给一个需要命令行密码的外部程序。
  • 这在文档化的 Windows API 中是正确的。但是,如果调用者拥有 SeCreatePermanentPrivilege(通常是系统服务),NT 对象管理器确实允许创建永久对象。通常它通过OBJ_PERMANENT 标志在创建时应用。现有对象可以通过未记录的调用 NtMakePermanentObject(HANDLE Handle) 变为永久对象,然后通过 NtMakeTemporaryObject 再次变为临时对象。
  • "有创建 ramfile 的 Win32API 吗?" - 没有,但是有很多可用的 3rd 方 RAM 磁盘驱动程序,安装后,您可以使用标准文件输入/输出功能。 “我不想只是加密和解密的原因是我正在传递给需要命令行密码的外部程序” - 那么是什么阻止你简单地解密密码在准备命令行字符串之前?
  • 所以,@eryksun - 这是一个很棒的技巧!很难找到 NtMakePermanentObject 的 lib 入口点,所以我只是从 NTDLL.DLL 加载它。 DLL 内的调用没有失败,但也没有使句柄永久化(hMapFile 是 CreateFileMapping() 返回的句柄。code HANDLE hLibrary; FARPROC foo; hLibrary = LoadLibrary("ntdll.dll"); if(!hLibrary) printf("bad lib"); foo = GetProcAddress(hLibrary, "NtMakePermanentObject"); if(!foo) printf("bad address"); foo(hMapFile); printf("%s", GetLastError ());
  • @ShnorW.,我不怀疑您的代码已编译并运行,但调用可能因STATUS_PRIVILEGE_NOT_HELD (0xC0000061) 而失败,因为您不是从具有SeCreatePermanentPrivilege 已启用。默认情况下,此权限不会授予管理员或普通用户——尽管管理员模拟系统登录并不难(例如,从 csrss.exe,以有限查询访问权限打开)。
猜你喜欢
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
  • 2021-10-15
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多