2

我希望能够选择在另一个程序的列表视图中选择了哪个项目(我无权访问它的代码)。实际上,它是一个 SysListView32,我认为它是相同的。我已经有以下代码,不幸的是,尽管编译,但似乎什么也没做(尽管 SendMessage() 返回 1)。

process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, 0xD14); 

 _lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE); 

 lvi.state = LVIS_SELECTED | LVIS_FOCUSED;
 lvi.stateMask = LVIS_SELECTED | LVIS_FOCUSED; 

 WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL); 
 int abc = ::SendMessage((HWND)0x00050D30, LVM_SETITEMSTATE, (WPARAM)2, (LPARAM)_lvi); 
 VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
4

4 回答 4

1

以下代码对我来说就像一个魅力:

HANDLE hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, 0x0000c130);
LPVOID epLvi = VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

LVITEM lvi;
lvi.state = LVIS_FOCUSED | LVIS_SELECTED;
lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
SIZE_T cbWritten = 0;
WriteProcessMemory(hProcess, epLvi, &lvi, sizeof(lvi), &cbWritten);
DWORD dw = SendMessage((HWND)0x00020C4C, LVM_SETITEMSTATE, 1, (LPARAM)epLvi);

VirtualFreeEx(hProcess, epLvi, 4096, MEM_DECOMMIT | MEM_RELEASE);
CloseHandle(hProcess);

您的代码可能无法正常工作的原因有多种:

  • 正如 Michael Dunn 所提到的,您需要保留并提交地址空间。有趣的是,您的示例仅尝试MEM_COMMIT记忆,但仅此MEM_RELEASE而已(与 相对MEM_RESERVE);
  • 您可能对拥有该窗口的进程没有足够的权限;
  • 您的进程和目标进程可能具有不同的位数。在这种情况下,可能需要一些结构大小技巧。

如果这一切都不起作用,我建议尝试不同的方法:IAccessible在这里可能会有所帮助。这里通常的免责声明:弄乱其他进程窗口和地址空间需要谨慎处理,如果可能的话应该避免。

于 2009-07-01T06:57:48.947 回答
0

If you get stuck, there is an open source project called AutoHotKey that can create scripts that can easily select items in lists, etc.

于 2009-06-12T21:17:13.863 回答
0

您必须在提交内存之前保留地址空间。您可以通过更改MEM_COMMITMEM_RESERVE|MEM_COMMIT

于 2009-06-24T06:11:02.050 回答
0

您如何初始化正在复制到目标进程内存中的源 LV_ITEM 的其余成员?您是否在源 LV_ITEM 的“掩码”成员中包含 LVIF_STATE 标志?如果不是,则 ListView 将忽略您尝试指定的“状态”和“状态掩码”值。

于 2009-06-10T20:59:36.113 回答