Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 是否可以从32位应用程序读取64位进程的进程内存?_Windows_32bit 64bit - Fatal编程技术网

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

Windows 是否可以从32位应用程序读取64位进程的进程内存?,windows,32bit-64bit,Windows,32bit 64bit,在windows 64位上,我有一个32位进程可以读取其他32位进程的内存,我希望它也能够读取64位进程 ReadProcessMemory用于读取内存,但有32位限制。有没有办法在64位进程上实现ReadProcessMemory的等效功能 我知道我可以写一个64位进程,然后从我的32位进程启动它来完成这项工作,但我想知道是否还有其他选择,这样我就不需要写一个64位进程了 谢谢。这是无法回避的。一种解决方案是停止使用WOW64仿真器并编写一个64位进程。另一种解决方案是使用IPC而不是直接读取

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

ReadProcessMemory用于读取内存,但有32位限制。有没有办法在64位进程上实现ReadProcessMemory的等效功能

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


谢谢。

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

否:

该库似乎已经解决了这个问题,并提供了一个函数
ReadProcessMemory64
Visual Studio扩展似乎使用了该库,并为我提供了64位进程

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

这是可能的

例如,您可以参考tofucoder答案中的优秀样本。 有关更多示例,请参考

请解释一下为什么它真的有效

可能会找到另一个样本

整个技巧是调用64位版本的ReadProcessMemory函数。直观地说,它不是32位进程的选项,但是上面的链接解释了:x64版本的
ntdll.dll
也作为32位进程的一部分加载到Windows WOW64 emulator中。它有一个名为
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
NTWOW64READVirtualMemory 64
功能的替代变体(以及获取PEB地址的替代方法)

概要:可以从x86 one与x64进程交互。可以通过直接调用x64版本的函数(从作为WOW64进程一部分加载的x64
ntdll.dll
)或调用特定的x86函数(即
NtWow64ReadVirtualMemory64
)来完成


另外,有人可能会说这是没有文件记录的,更像是黑客——但它只是没有正式的文件记录。例如,像
Unlocker
ProcessHacker
ProcessExplorer
这样的软件利用了这些未记录的功能(以及更多),当然,这取决于您的决定。

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

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

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

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

您可以编写执行此操作的驱动程序,但考虑到其他替代方案,这样做有些过头了。只需编写一个64位助手进程。实际上,有一种方法是使用WOW64系统。nSize指定要从目标进程读取的字节数,而不是指针的大小,参见@hillu I从未说过这一点。在32位应用程序中,像
LPCVOID
这样的指针的最大大小为32位。如果将目标64位地址存储在
DWORD64
变量中并不重要,当类型转换为32位指针时,它将被截断。因此,您无法使用32位版本的
ReadProcessMemory()
,从32位应用程序中读取高于0xFFFFFFFF的64位目标内存地址,因为它不适合32位指针。