在Windows 64位上,我有一个32位进程读取其他32位进程的内存,我希望它能够读取64位进程。
ReadProcessMemory用于读取内存,但它有32位的限制。有没有办法在64位进程上执行相当于ReadProcessMemory的操作?
我知道我可以编写一个64位进程并从我的32位进程启动它来完成工作,但我想知道是否还有其他选项,这样我就不需要编写64位进程。 / p>
感谢。
答案 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。有人可能会说它没有文档,而且更像是黑客 - 但它只是没有正式记录。例如,NtWow64ReadVirtualMemory64
,Unlocker
或ProcessHacker
之类的软件会使用这些未记录的功能(以及更多功能),当然,由您决定。
答案 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指针。