我想使用 2 个 C# 应用程序通过内存相互通信。对于我使用的主机端:
int* ptr = &level;
对于我想使用的客户端:
ReadProcessMemory((int)_handle, <returned result of int* ptr>, _buffer, 2, ref bytesRead);
但是 ReadProcessMemory 不起作用。例如:级别设置为 3,但 ReadProcessMemory 返回 0。这到底是怎么回事? (注意:“级别”字段不会从内存中清除)
我尝试了 int* ptr 很多次,因为很多网站都告诉我这样做,但这对 ReadProcessMemory 来说效果不佳。
我设置了 level = 3 但 ReadProcessMemory 的结果为 level = 0
最佳答案
你问的问题,以你问的方式是非常危险的,因为这个过程完全由 CLR 管理。根据您想要共享的内容和方式,您可以考虑套接字或管道。 或者,您可以使用互操作,但我认为它需要一定的专业知识和修修补补。
两个 C# 应用程序通过内存进行通信的最简洁方法是使用内存映射文件。在托管进程中弄乱内存可能会出现微妙的问题。内存映射文件是一种共享信息的方式。
请记住,每个内存映射文件都加载到不同的内存地址,因此您需要在不使用绝对指针的情况下构建它。
编辑: 直接原始内存访问需要知道要访问的确切物理地址,因为在目标进程中分配的虚拟地址不同并且可能与源进程的虚拟地址重叠。 C# 应用程序由公共(public)语言运行时托管,它控制着一切,包括内存分配。特别是,标准的 C# 应用程序不会管理它自己的内存:随着运行时将对象作为正常应用程序生命周期的一部分移动,此类地址会随着时间而改变。
如果你控制了目标应用程序,你可以通过GC
类固定对象以禁止移动,那么你必须获取对象的地址,并将其传递给其他人过程。然后另一个进程必须打开目标进程进行读取,映射内存段,通过转换虚拟地址来计算要读取的内存位置。
您所要求的需要协作进程和大量低级知识,最后,您也可能永远无法读取更新的内存更改,因为 CLR 可能不会将值写回内存(看看volatile
为此)。
编写这样的软件显然令人兴奋,但是当您控制这两个应用程序时,就会有更简洁、更可靠的方法来实现您的目标。
附带说明一下,此技术被培训师、黑客工具和病毒使用,因此防病毒软件在看到此类行为时会发出危险信号。
关于c# - 如何获取另一个 C# 应用程序读取的内存地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54376723/