我用VC写了一个console程序,用来读“设备管理器”中那个systreeview control下的各条Item的文本值,找出我想要的一条。目前是能够在Win2000和WinXP上实现,而Win98上不行。问题出在Win98不支持VirtualAllocEx()这个API。我的代码:
/////////////////////////////////////////////////////////////////////////////////////
// Allocate memory in the remote process's address space
TVITEMEX* plvi = (TVITEMEX*) VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
long children = 0; TVITEMEX item;
item.hItem = hItem;
item.mask = TVIF_TEXT | TVIF_CHILDREN;
item.pszText = (LPTSTR) (plvi + 1);
item.cchTextMax = buffer_size; // Write the local LV_ITEM structure to the remote memory block
WriteProcessMemory(hProcess, plvi, &item, sizeof(item), NULL); if (!TreeView_GetItem(hWnd, plvi))
{
fprintf(stderr, "Error calling SendMessage(TVIF_TEXT)\n");
} // Read the remote text string into the end of our clipboard buffer
ReadProcessMemory(hProcess, plvi + 1, buffer, buffer_size, NULL);
ReadProcessMemory(hProcess, &plvi->cChildren, &children, sizeof(plvi->cChildren), NULL); // Free the memory in the remote process's address space
VirtualFreeEx(hProcess, plvi, 0, MEM_RELEASE);/////////////////////////////////////////////////////////////////////////////////////后来我试了用Win98线性地址的2G-3G共享空间,具体是条用在console中用VirtualAlloc(),将flAllocationType补上|VA_SHARED (注:#define VA_SHARED 0x8000000 这个一个未公开的FLAG,用于指定分配共享内存)。结果在运行到TreeView_GetItem(hWnd, plvi)时,提示RUNDLL32.EXE错误:COMMCTRL.DLL常规保护错误。
经查:TreeView_GetItem(hWnd, plvi)是宏,它其实是调用SendMessage(hWnd, TVM_GETITEM, 0, (LPARAM)(TV_ITEM*)pitem)来实现的。
是不是说sendmessage无法读/写那块共享空间plvi?
后来我也拾了CreateFileMapping+MapViewOfFile方法创建共享内存,结果还是与上面一样。请问:
1。 有没有一种方法可以在Win98实现类似VirtualAllocEx()的功能?
2。 如果用共享内存的方法,上面的问题出在哪?
3。 或者能否给我一种可以实现目的(获得Item的值)的其它方法?请多多指教,谢谢!
/////////////////////////////////////////////////////////////////////////////////////
// Allocate memory in the remote process's address space
TVITEMEX* plvi = (TVITEMEX*) VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
long children = 0; TVITEMEX item;
item.hItem = hItem;
item.mask = TVIF_TEXT | TVIF_CHILDREN;
item.pszText = (LPTSTR) (plvi + 1);
item.cchTextMax = buffer_size; // Write the local LV_ITEM structure to the remote memory block
WriteProcessMemory(hProcess, plvi, &item, sizeof(item), NULL); if (!TreeView_GetItem(hWnd, plvi))
{
fprintf(stderr, "Error calling SendMessage(TVIF_TEXT)\n");
} // Read the remote text string into the end of our clipboard buffer
ReadProcessMemory(hProcess, plvi + 1, buffer, buffer_size, NULL);
ReadProcessMemory(hProcess, &plvi->cChildren, &children, sizeof(plvi->cChildren), NULL); // Free the memory in the remote process's address space
VirtualFreeEx(hProcess, plvi, 0, MEM_RELEASE);/////////////////////////////////////////////////////////////////////////////////////后来我试了用Win98线性地址的2G-3G共享空间,具体是条用在console中用VirtualAlloc(),将flAllocationType补上|VA_SHARED (注:#define VA_SHARED 0x8000000 这个一个未公开的FLAG,用于指定分配共享内存)。结果在运行到TreeView_GetItem(hWnd, plvi)时,提示RUNDLL32.EXE错误:COMMCTRL.DLL常规保护错误。
经查:TreeView_GetItem(hWnd, plvi)是宏,它其实是调用SendMessage(hWnd, TVM_GETITEM, 0, (LPARAM)(TV_ITEM*)pitem)来实现的。
是不是说sendmessage无法读/写那块共享空间plvi?
后来我也拾了CreateFileMapping+MapViewOfFile方法创建共享内存,结果还是与上面一样。请问:
1。 有没有一种方法可以在Win98实现类似VirtualAllocEx()的功能?
2。 如果用共享内存的方法,上面的问题出在哪?
3。 或者能否给我一种可以实现目的(获得Item的值)的其它方法?请多多指教,谢谢!
谢谢指教。
有个问题,我在2000和XP中用上述方法没有问题,只不过相应用了VirtualAllocEx函数,但是SendMessage函数还是在console那个进程中调用的啊,而hWnd当然是目标进程(设备管理器)的一个HWND参数了。
为什么98就不行?我只是吧PLVI这个 TVITEMEX结构放到共享内存中去,在Win98的其它进程中应该期地址也是一样的,这样SendMessage可以读写这个lparam参数了问题出在哪呢?
你这里的错误,我觉得问题不在于读写lparam参数,而在于访问HWND关联的数据结构时出现GP。
正确的实现应该是code injection。