如何获取另一个C#应用程序要读取的内存地址?

时间:2019-01-26 08:10:57

标签: c#

我想使用2个C#应用程序通过内存相互通信。对于主机端,我使用了:

int* ptr = &level;

对于客户端,我想使用:

ReadProcessMemory((int)_handle, <returned result of int* ptr>, _buffer, 2, ref bytesRead);

但是ReadProcessMemory不起作用。例如:level设置为3,但ReadProcessMemory返回0。这到底是什么? (注意:“级别”字段不会从内存中清除)

我尝试过多次int * ptr,因为很多网站都告诉我要这样做,但是在ReadProcessMemory上效果不佳。

我将级别设置为3,但将ReadProcessMemory的级别设置为0

1 个答案:

答案 0 :(得分:3)

以您的方式提出的要求非常危险,因为该过程完全由CLR管理。根据您要共享的内容以及共享方式,可以考虑使用套接字或管道。 另外,您可以使用互操作,但我认为这需要一定的专业知识和技巧。

两个C#应用程序通过内存进行通信的最干净方法是使用内存映射文件。在托管进程中处理内存可能会引起一些细微的问题。内存映射文件是一种共享信息的方式。

请记住,每个内存映射文件都加载到不同的内存地址,因此您需要在不使用绝对指针的情况下对其进行结构化。

编辑: 直接原始内存访问需要知道要访问的确切物理地址,因为目标进程中分配的虚拟地址是不同的,并且可能与源进程的虚拟地址重叠。 C#应用程序由公共语言运行时托管,该运行时控制一切,包括内存分配。特别是,标准的c#应用程序无法管理自己的内存:随着运行时对象在正常应用程序生命周期中移动对象,此类地址会随着时间变化。

如果您控制目标应用程序,则可以通过GC类将对象固定以禁止移动,然后必须获取对象的地址,并将其传递给其他进程。然后,另一个进程必须打开要读取的目标进程,映射内存段,并通过转换虚拟地址来计算要读取的内存位置。

您要求的内容需要协作过程和大量底层知识,最后,您可能永远也无法读取更新的内存更改,因为CLR可能不会将值写回到内存中(请参阅volatile

编写此类软件显然令人兴奋,但是当您同时控制这两个应用程序时,就会有更简洁,更可靠的方法来实现目标。

请注意,培训人员,黑客工具和病毒使用了此技术,因此防病毒软件在看到此类行为时会发出红旗。