因为我还没有找到答案 对于之前在这里提出的问题 我正在尝试一种不同的方法。

有没有办法在两个进程之间共享内存?

第二个进程从注入中获取信息,因为它是一个不再受支持的遗留程序。

我的想法是在那里注入一些代码,在我传递给注入程序的结构中,将地址(或其他内容)传递到我需要运行的数据所在的共享内存。一旦获得数据,我将在注入的线程中填充我自己的变量。

这可能吗?如何?

代码受到赞赏。

编辑:

我认为这还不清楚,所以我会澄清。我确实知道如何注射。我已经在这么做了。这里的问题是将动态数据传递给注入。

有帮助吗?

解决方案

您可以尝试内存映射文件

会逐步提供更多内容细节。

其他提示

尽管 Windows 通过其支持共享内存 文件映射API, ,您不能轻松地将共享内存映射直接注入另一个进程,因为 文件扩展视图 不接受进程参数。

但是,您可以通过在另一个进程中分配内存来注入一些数据 虚拟分配器写进程内存. 。如果您要使用复制句柄 重复句柄, ,然后注入一个调用的存根 文件扩展视图, ,您可以在另一个进程中建立共享内存映射。因为听起来您无论如何都会注入代码,所以这应该对您很有效。

总而言之,您需要:

  • 通过调用创建匿名共享内存段句柄 创建文件映射 hFile 为 INVALID_HANDLE_VALUE,lpName 为 NULL。
  • 将此句柄复制到目标进程中 重复句柄
  • 为代码分配一些内存 虚拟分配器, ,使用FlallocationType = mem_commit | mem_reserve and flprotect = page_execute_readwrite
  • 使用以下命令将存根代码写入此内存 写进程内存. 。该存根可能需要用汇编程序编写。通过将 DuplicateHandle 中的 HANDLE 写入此处的某处来传递它。
  • 使用执行你的存根 创建远程线程. 。然后存根必须使用它获得的 HANDLE 来调用 文件扩展视图. 。然后,进程将拥有一个公共的共享内存段。

如果您的存根加载外部库,您可能会发现它会更容易一些 - 也就是说,只需调用 LoadLibrary(找到 LoadLibrary 的地址留给读者作为练习)并从库的 dllmain 入口点完成您的工作。在这种情况下,使用命名共享内存可能比使用 DuplicateHandle 更简单。请参阅 MSDN 文章 创建文件映射 有关更多详细信息,但本质上,传递 hFile 的 INVALID_HANDLE_VALUE 和 lpName 的名称。

编辑: :由于您的问题是传递数据而不是实际的代码注入,因此这里有一些选项。

  1. 使用可变大小的共享内存。您的存根获取共享内存的大小以及名称或句柄。如果您只需要交换一次数据,那么这是合适的。 请注意,共享内存段的大小在创建后不能轻易更改。
  2. 用一个 命名管道. 。您的存根获取管道的名称或句柄。然后,您可以使用适当的协议来交换可变大小的块 - 例如,写入长度的 size_t,后跟实际消息。或者使用 PIPE_TYPE_MESSAGE 和 PIPE_READMODE_MESSAGE,并观察 ERROR_MORE_DATA 以确定消息结束的位置。如果您需要多次交换数据,则这是合适的。

编辑2: :下面是如何为存根实现句柄或指针存储的草图:

.db B8            ;; mov eax, imm32
.dl handle_value  ;; fill this in (located at the start of the image + one byte)
;; handle value is now in eax, do with it as you will
;; more code follows...

您也可以只使用固定名称,这可能更简单。

您是否尝试使用管道(用于内存)甚至序列化(用于对象)?您可以使用文件来管理进程之间的内存。套接字也很适合在进程之间进行通信。

内存映射是要走的路,你甚至不需要创建一个永久的内存空间,当共享它的所有进程都关闭时,内存扇区会超出范围。还有其他方法。将数据从一个C应用程序传递到另一个应用程序的快速而肮脏的方法就是使用操作系统。在命令行输入 app1 | APP2 。这会导致app2成为app1的输出目标,或者来自app1的printf命令会将其发送到app2(这称为管道)。

您可以尝试使用 Boost.Interprocess 在两个进程之间进行通信。但是要将代码注入以前存在的,不受支持的软件中,您可能必须使用@ bdonlan的方式使用 WriteProcessMemory

如果您正在谈论Windows,那么主要障碍就是将每个流程都存储在自己的虚拟地址空间中。遗憾的是,您无法从进程到进程传递正常的内存地址并获得您期望的结果。 (另一方面,线程都存在于相同的地址空间中,这就是线程可以以相同的方式查看内存的原因。)

但是,Windows确实有共享内存空间,您必须非常小心才能正确管理。在共享内存空间中分配空间的任何进程都负责显式释放该内存。这与本地存储器形成对比,本地存储器在处理过程中或多或少地消失。

有关如何使用共享内存空间的一些想法,请参阅此MSDN示例文章接管世界。呃,与传统软件的接口。或者其他:)祝你好运,无论你最终做什么!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top