windows 是否可以从 32 位应用程序读取 64 位进程的进程内存?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5714297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to read process memory of a 64 bit process from a 32bit app?
提问by Scott Langham
On windows 64 bit, I've got a 32 bit process that reads the memory of other 32 bit processes, and I'd like it to be able to read 64 bit processes too.
在 Windows 64 位上,我有一个 32 位进程可以读取其他 32 位进程的内存,我希望它也能够读取 64 位进程。
ReadProcessMemory is being used to read the memory, but it has a 32 bit limitation. Is there any way of doing the equivalent of a ReadProcessMemory on a 64 bit process?
ReadProcessMemory 用于读取内存,但它有 32 位限制。有什么方法可以在 64 位进程上做等效的 ReadProcessMemory 吗?
I know I could write a 64 bit process and launch that from my 32 bit process to do the work, but I'm wondering if there's some other option so that I don't need to write a 64 bit process.
我知道我可以编写一个 64 位进程并从我的 32 位进程启动它来完成这项工作,但我想知道是否还有其他选择,这样我就不需要编写 64 位进程。
Thanks.
谢谢。
采纳答案by David Heffernan
There's no way to get around this. One solution is to stop using the WOW64 emulator and write a 64 bit process. Another solution is to use IPC rather than direct memory reading.
没有办法解决这个问题。一种解决方案是停止使用 WOW64 模拟器并编写 64 位进程。另一种解决方案是使用 IPC 而不是直接读取内存。
回答by greenpiece
It's possible.
这是可能的。
For an example you may refer to the excellent sample in the answer of tofucoder. For one more sample you may refer to this link.
例如,您可以参考tofucoder答案中的优秀示例。有关更多示例,您可以参考此链接。
For explanation why it actually works please check this thread.
有关为什么它实际有效的解释,请检查此线程。
Another sample may be found here.
可以在此处找到另一个示例。
The whole trick is to call 64-bit version of ReadProcessMemory function. Intuitively it's not an option from 32-bit process however the link above explains: x64 version of ntdll.dll
is also loaded as a part of 32-bit process in Windows WOW64 emulator. It has a function called NtReadVirtualMemory
with the same prototype as ReadProcessMemory64
:
整个技巧是调用 ReadProcessMemory 函数的 64 位版本。直观地说,它不是 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);
The address is 64-bit long and thus the whole virtual address space of 64-bit process may be referred.
该地址为 64 位长,因此可以引用 64 位进程的整个虚拟地址空间。
You may wonder how to get the address of this function. It's when another function in ntdll.dll comes in handy: LdrGetProcedureAddress
. Its prototype is the same as of GetProcAddress
:
您可能想知道如何获取此函数的地址。这是 ntdll.dll 中的另一个函数派上用场的时候:LdrGetProcedureAddress
. 它的原型与以下相同GetProcAddress
:
__declspec(SPEC)DWORD64 __cdecl GetProcAddress64(DWORD64 hModule, char* funcName);
We are to examine export directory of x64 ntdll.dll
and manually found this function's entry. Then we can obtain address of any other function.
我们要检查 x64 的导出目录ntdll.dll
并手动找到该函数的条目。然后我们可以获取任何其他函数的地址。
Another question is left uncovered so far: how to obtain start address of x64 ntdll.dll
? We need to manually walk through x64 PEB
structure of our process and traverse loaded modules' list - as one of the variants. And how to get PEB address? Please refer to the links above, not to overflow this post with too many details.
到目前为止,还有一个问题没有解决:如何获取 x64 的起始地址ntdll.dll
?我们需要手动PEB
遍历进程的x64结构并遍历加载的模块列表 - 作为变体之一。以及如何获得PEB地址?请参考上面的链接,不要用太多细节溢出这篇文章。
All this is covered in sample from the first link.
Alternative variants with usage of NtReadVirtualMemory
& NtWow64ReadVirtualMemory64
functions are provided in second & third links (as well as alternative ways to get PEB address).
所有这些都包含在第一个链接的示例中。在第二个和第三个链接中提供了使用NtReadVirtualMemory
&NtWow64ReadVirtualMemory64
函数的替代变体(以及获取 PEB 地址的替代方法)。
Summary: it is possible to interact with x64 process from x86 one. It can be done either with direct call to x64 version of function (from x64 ntdll.dll
which is loaded as a part of WOW64 process) or with the call of specific x86 function which is intended to work with x64 process (namely NtWow64ReadVirtualMemory64
).
总结:可以从 x86 开始与 x64 进程交互。它可以通过直接调用 x64 版本的函数(从ntdll.dll
作为 WOW64 进程的一部分加载的x64 )或通过调用旨在与 x64 进程一起工作的特定 x86 函数(即NtWow64ReadVirtualMemory64
)来完成。
P.S. One may say it's undocumented and is more like hack - but it's just not officially documented. Soft like Unlocker
, ProcessHacker
or ProcessExplorer
, for example, makes use of these undocumented features (and many more), and it's up to you to decide, of course.
PS One 可能会说它是无证的,更像是 hack - 但它只是没有正式记录。Soft like Unlocker
,ProcessHacker
或者ProcessExplorer
,例如,利用这些未记录的功能(以及更多),当然,这由您来决定。
回答by tofucoder
The library wow64extseems to have solved this problem and offers a function ReadProcessMemory64
The Visual Studio Extension VSDebugToolseems to use this library and works for me with 64 bit processes.
库wow64ext似乎已经解决了这个问题并提供了一个函数ReadProcessMemory64
Visual Studio 扩展VSDebugTool似乎使用了这个库并且适用于我的 64 位进程。
Anyway, it shouldn't be impossibe because the (32 bit) Visual Studio Debugger handles 64 bit Debuggees very well.
无论如何,它不应该是不可能的,因为(32 位)Visual Studio 调试器可以很好地处理 64 位调试器。
回答by Jonesome Reinstate Monica
回答by Pierre Ciholas
ReadProcessMemory can read any size of memory including from x86 processes reading x64 processes.
ReadProcessMemory 可以读取任何大小的内存,包括从 x86 进程读取 x64 进程。
You can without a problem, in an x86 program, do the following:
您可以毫无问题地在 x86 程序中执行以下操作:
DWORD64 test = 0;
ReadProcessMemory(hProcess, (LPCVOID)lpBaseAddress, &test, sizeof(DWORD64), NULL);
Which would allow you to dereference an x64 pointer from a x86 process.
这将允许您从 x86 进程中取消引用 x64 指针。