问题
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.
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?
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.
Thanks.
回答1:
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.
回答2:
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.
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
:
__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.
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
:
__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.
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.
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).
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
).
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.
回答3:
The library wow64ext seems to have solved this problem and offers a function ReadProcessMemory64
The Visual Studio Extension VSDebugTool seems to use this library and works for me with 64 bit processes.
Anyway, it shouldn't be impossibe because the (32 bit) Visual Studio Debugger handles 64 bit Debuggees very well.
回答4:
No: http://blogs.msdn.com/b/oldnewthing/archive/2008/10/20/9006720.aspx
回答5:
ReadProcessMemory can read any size of memory including from x86 processes reading x64 processes.
You can without a problem, in an x86 program, do the following:
DWORD64 test = 0;
ReadProcessMemory(hProcess, (LPCVOID)lpBaseAddress, &test, sizeof(DWORD64), NULL);
Which would allow you to dereference an x64 pointer from a x86 process.
来源:https://stackoverflow.com/questions/5714297/is-it-possible-to-read-process-memory-of-a-64-bit-process-from-a-32bit-app