Win32 WriteProcessMemory()魔法偏移值

时间:2008-11-11 14:45:01

标签: c++ winapi visual-c++ virtualalloc

我正在尝试读取另一个进程拥有的Win32 ListView中的数据。不幸的是,我的WriteProcessMemory()调用失败,并显示错误“此系统不支持此功能”。当我在VirtualAlloc()调用中为基地址指定“NULL”时。但是,如果我将VirtualAlloc()地址偏移一些“魔术”值,我很幸运,并且在挫折时刻随机挑选,那么这个调用在我的系统上运行,但在其他情况下失败。 (见下面的代码)

有人能说出这个神奇的偏移对我有什么影响吗?通过反复试验,我可以找到适用于特定系统的值,但我无法找到解决此问题的一般方法。

谢谢, PaulH

#define MAGIC_OFFSET (DWORD)0x01020000

LVHITTESTINFO hti   = { 0 };
hti.pt              = clientPoint;

LPVOID lpBuffer = ::VirtualAlloc( NULL, 1, MEM_RESERVE, PAGE_READWRITE );
::VirtualFree( lpBuffer, 0, MEM_RELEASE );

lpBuffer = ::VirtualAlloc( (LPVOID)((DWORD)lpBuffer + MAGIC_OFFSET), sizeof( hti ), MEM_RESERVER, PAGE_READWRITE );
DWORD dwBuffer = (DWORD)lpBuffer + MAGIC_OFFSET - sizeof( hti );

if( !::WriteProcessMemory( hProcess, (LPVOID)dwBuffer, (LPVOID)&hti, sizeof( hti ), NULL ) )
    return 0;

if( ListView_HitTest( hWndListView, (LPVOID)dwBuffer ) < 0 )
    return 0;

if( !::ReadProcessMemory( hProcess, (LPVOID)dwBuffer, (LPVOID)&hti, sizeof( hti ), NULL ) )
    return 0;

::VirtualFree( lpBuffer, 0, MEM_RELEASE );

澄清(由Cd-MaN添加):这是在Windows Mobile平台上,可能是非x86架构。所以情况可能会有所不同(ARM处理器中是否有单独的地址空间?)。

3 个答案:

答案 0 :(得分:3)

为什么不使用命名共享内存,而不是尝试在另一个进程中分配内存。本文将引导您完成shared memory的基本设置,并进行了快速检查,以确保Windows Mobile 5支持这些功能。

答案 1 :(得分:2)

VirtualAlloc在您的地址空间中分配内存。在写入另一个进程的内存空间时,使用该地址绝对无效。您应该使用VirualAllocEx代替并传入hProcess。

当你工作时,你只是幸运地在一些随机的记忆中涂鸦。

如果在查询另一个进程时不支持为VirtualAllocEx的第一个参数指定NULL(不知道是否存在)...那么您可以使用VirtualQueryEx来映射寻址其他进程的空间并找到一个有效的空闲区域传递给VirtualAlloc。

您可能不得不将其置于重试循环中,因为在您寻找空位时,其他进程地址空间的状态可能会发生变化。

答案 2 :(得分:0)

您必须记住,您正在写入程序的虚拟地址空间。在Windows上,它通常从您的幻数开始。

你有没有调试过一个程序?地址是什么样的?

在我的系统上,可执行文件通常在00400000或01000000左右加载。它从可执行文件更改为可执行文件,我相信即使连续运行相同的可执行文件,Windows也可以更改此地址。

此外,可执行文件的部分具有自己的(和相对较小的)偏移量。例如,代码部分通常大约为+1000,然后是数据,零数据部分等等。

这一切意味着如果您的可执行文件的基数为00400000且其数据部分的偏移量为+2000,则数据的第一个字节将为00402000.为了读/写此字节,您将必须指定基地址00402000,而不是2000,绝对不是0.

尝试打印指针的值。如果指向的对象具有静态生存期,它可能会驻留在数据部分中,您将获得类似00402000的地址。然后,如果您将WriteProcessMemory写入该地址,则您将修改该对象。

各种Win32可执行格式都包含这个“0040000”基地址以及各个部分的偏移量,但是因为这样的hack读取另一个进程的内存可能会针对特定可执行文件的特定版本,无论如何离开神奇数字可能会更好。