是否可以从32位应用程序读取64位进程的进程内存?

时间:2011-04-19 09:29:30

标签: windows 32bit-64bit

在Windows 64位上,我有一个32位进程读取其他32位进程的内存,我希望它能够读取64位进程。

ReadProcessMemory用于读取内存,但它有32位的限制。有没有办法在64位进程上执行相当于ReadProcessMemory的操作?

我知道我可以编写一个64位进程并从我的32位进程启动它来完成工作,但我想知道是否还有其他选项,这样我就不需要编写64位进程。 / p>

感谢。

5 个答案:

答案 0 :(得分:12)

这是可能的。

举个例子,您可以参考 tofucoder 答案中的优秀样本。 您还可以参考to this link

为了解释为什么它确实有用,请check this thread

可能会找到另一个示例here

整个技巧是调用64位版本的ReadProcessMemory函数。直观地说,它不是32位进程的选项,但上面的链接解释:x64版本的ntdll.dll也作为Windows WOW64模拟器中32位进程的一部分加载。它有一个名为NtReadVirtualMemory的函数,其原型与ReadProcessMemory64相同:

__declspec(SPEC)BOOL __cdecl ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);

地址长度为64位,因此可以引用64位进程的整个虚拟地址空间。

您可能想知道如何获取此功能的地址。这时ntdll.dll中的另一个函数派上用场了:LdrGetProcedureAddress。它的原型与GetProcAddress

相同
__declspec(SPEC)DWORD64 __cdecl GetProcAddress64(DWORD64 hModule, char* funcName);

我们要检查x64 ntdll.dll的导出目录并手动找到此函数的条目。然后我们可以获得任何其他函数的地址。

到目前为止还没有发现另一个问题:如何获取x64 ntdll.dll的起始地址?我们需要手动遍历我们进程的x64 PEB结构并遍历已加载模块的列表 - 作为其中一个变体。以及如何获得PEB地址?请参阅上面的链接,不要在这篇文章中包含太多细节。

所有这些都包含在第一个链接的样本中。 使用NtReadVirtualMemory&的替代变体NtWow64ReadVirtualMemory64功能在第二个&第三个链接(以及获取PEB地址的替代方法)。

摘要:可以从x86进程与x64进程交互。它可以通过直接调用x64版本的函数(来自x64 ntdll.dll,它作为WOW64进程的一部分加载)或者调用特定的x86函数来完成,该函数用于x64进程(即{ {1}})。

P.S。有人可能会说它没有文档,而且更像是黑客 - 但它只是没有正式记录。例如,NtWow64ReadVirtualMemory64UnlockerProcessHacker之类的软件会使用这些未记录的功能(以及更多功能),当然,由您决定。

答案 1 :(得分:3)

wow64ext似乎已经解决了这个问题并提供了一个函数ReadProcessMemory64 Visual Studio Extension VSDebugTool似乎使用了这个库并且可以使用64位进程。

无论如何,它不应该是不可能的,因为(32位)Visual Studio Debugger可以很好地处理64位调试对象。<​​/ p>

答案 2 :(得分:-1)

答案 3 :(得分:-3)

没有办法解决这个问题。一种解决方案是停止使用WOW64仿真器并编写64位进程。另一种解决方案是使用IPC而不是直接读取内存。

答案 4 :(得分:-3)

ReadProcessMemory可以读取任何大小的内存,包括读取x64进程的x86进程。

您可以毫无问题地在x86程序中执行以下操作:

DWORD64 test = 0;
ReadProcessMemory(hProcess, (LPCVOID)lpBaseAddress, &test, sizeof(DWORD64), NULL);

这将允许您从x86进程中取消引用x64指针。