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

问题描述 投票:0回答:5

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

ReadProcessMemory 用于读取内存,但它有 32 位限制。有什么方法可以在 64 位进程上执行相当于 ReadProcessMemory 的操作吗?

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

谢谢。

windows 32bit-64bit
5个回答
16
投票

这是可能的。

例如,您可以参考tofucoder的答案中的优秀示例。 如需更多示例,您可以参考此链接

要了解其实际工作原理的解释,请检查此线程

可以在此处找到另一个样本。

整个技巧是调用 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 版本的函数(来自作为 WOW64 进程的一部分加载的 x64

ntdll.dll
)或调用旨在与 x64 进程配合使用的特定 x86 函数(即
NtWow64ReadVirtualMemory64
)来完成).

附注有人可能会说它没有记录,更像是黑客攻击 - 但它只是没有正式记录。例如,像

Unlocker
ProcessHacker
ProcessExplorer
这样的软件会利用这些未记录的功能(以及更多),当然,这取决于您的决定。


4
投票

wow64ext 似乎已经解决了这个问题并提供了一个功能

ReadProcessMemory64
Visual Studio 扩展 VSDebugTool 似乎使用这个库并适用于我的 64 位进程。

无论如何,这不应该是不可能的,因为(32 位)Visual Studio 调试器可以很好地处理 64 位调试器。



-4
投票

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

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

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

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


-5
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.