2008-11-11 105 views
0

我想读取另一个进程拥有的Win32 ListView中的数据。不幸的是,我的WriteProcessMemory()调用失败,并显示错误“此系统不支持此功能”。当我在我的VirtualAlloc()调用中为基地址指定“NULL”时。但是,如果我通过一些我感到幸运的“魔术”值来抵消该VirtualAlloc()地址,并在沮丧的时刻随机挑选,则该调用在我的系统上运行,但在其他系统上失败。 (见下面的代码)Win32 WriteProcessMemory()魔术补偿值

有人可以建议这个神奇的胶印是为我做的吗?通过试验和错误,我可以找到适用于特定系统的值,但是我无法找到解决此问题的通用解决方案。

感谢, 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); 

澄清(镉人加入):这是Windows Mobile平台上,大概非x86架构。所以情况可能会有所不同(ARM处理器中是否有单独的地址空间?)。

回答

3

而不是尝试在另一个进程中分配内存,而不是使用命名的共享内存。本文将带您通过shared memory的基本设置,并且我进行了快速检查以确保这些功能得到Windows Mobile 5的支持。

+0

这似乎很好地工作。我无法相信我对这个话题的所有研究都从未改变过。 非常感谢 – PaulH 2008-11-11 19:20:20

2

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

你只是越来越幸运,当它工作时随意涂抹一些随机内存。

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

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

0

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

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

在我的系统,可执行文件通常被装载周围00400000或01000000从可执行文件变成可执行文件,我相信Windows有,甚至在同一个可执行文件的连续运行更改此地址的能力。

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

这是什么意思,如果您的可执行文件的基数为00400000,并且其数据段的偏移量为+ 2000,数据的第一个字节将在00402000.为了读写这个字节,你必须指定一个基地址00402000,而不是2000,绝对不是0.

试着打印一个指针。如果指向的对象具有静态生存期,它可能会驻留在数据部分,您将得到类似00402000的地址。然后,如果您将WriteProcessMemory添加到该地址,则将修改该对象。

各种Win32可执行格式都包含这个“0040000”基地址以及各个部分的偏移量,但是因为读取另一个进程的内存的这种黑客可能会针对特定可执行文件的特定版本,你可能会更好,只需保留幻数即可。