VC 如何读取第三方软件ListView控件(外挂篇之一)
来源:互联网 发布:java线程与进程的 编辑:程序博客网 时间:2024/05/18 03:57
一、VC 如何读取第三方软件ListView控件
写下这篇文章前,我想先对我的导师崔Sir说声:感谢!因为没有他的指导,其中一个Bug我是很难解决的。
因项目需要,需要开发外挂对第三方软件进行操作并获取ListView控件内的内容。
一般来说,要解决此问题大家肯定跟我初始想法一样,直接发送 LVM_GETITEM 消息给第三方软件ListView控件。事实上,有些消息直接发送可以获取到想要的结果,如 LVM_GETITEMCOUNT。但是,并不是所有的消息直接发送后都可以获取到对应的结果,譬如,LVM_GETITEM。
查阅各种资料,解决办法详细步骤如下:
1. 根据窗口句柄获取该窗口的进程 ID:GetWindowThreadProcessId
2. 打开指定 ID 的进程:OpenProcess
3. 在该进程空间分配:VirtualAllocEx
4. 写入数据:WriteProcessMemory
5. ListView 相关消息 / 宏:LVM_GETITEM、LVM_GETITEMTEXT (ListView_GetItemText)
6.读取数据:ReadProcessMemory
7.在该进程空间释放内存:VirtualFreeEx
8.关闭进程句柄
结合上面的步骤,我以获取任务管理器进程ListView控件内进程信息为例,并使用VS2010写下如下代码:
#define _AFXDLL#include <afx.h>#include <iostream>#include <iomanip>#include <Windows.h>#include <string>int main(){//获取窗口句柄HWND hTaskMsgWnd = ::FindWindow("#32770", "Windows 任务管理器");HWND hProcWnd = ::FindWindowEx(hTaskMsgWnd, NULL, "#32770", "Processes");HWND hProcListView = ::FindWindowEx(hProcWnd, NULL, "SysListView32", NULL);HWND hHeaderWnd = (HWND)::SendMessage(hProcListView, LVM_GETHEADER, 0, 0);//获取行数与列数int rows = (int)::SendMessage(hProcListView, LVM_GETITEMCOUNT, 0, 0);int cols = (int)::SendMessage(hHeaderWnd, HDM_GETITEMCOUNT, 0, 0);//获取窗口线程与进程IDDWORD dwProcID = 0;::GetWindowThreadProcessId(hProcListView, &dwProcID);//打开进程//注意, 如果你的电脑是64位系统, 那么"任务管理器"进程则是64位的, 使用OpenProcess实际返回的是一个64位的句柄值//如果, 你的程序是采用W32编译器, 那么定义的进程句柄变量实际上是一个32位的句柄变量//现在, 如果你用32位的句柄变量来保存64位的句柄值, 它实际上是保存了一个被截取后的64位的句柄值, 这个值是错误的//这时, 你必须把编译器也调整为64位, 使句柄值内存长度统一HANDLE hProcess = NULL;hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcID);//进程空间的虚拟内存分配void* pVirBuf = ::VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);for (int iRowIdx = 0; iRowIdx < rows; iRowIdx++){for (int iColIdx = 0; iColIdx < cols; iColIdx++){//填充单个子项的相关参数LVITEM item;item.mask = LVIF_TEXT;item.iItem = iRowIdx;item.iSubItem = iColIdx;item.cchTextMax = 256;item.pszText = (LPSTR)((int)pVirBuf + sizeof(LVITEM));//将单个子项的数据写入至进程虚拟内存空间pVirBuf内//注意, X64位下不要使用DWORD, DWORD=4BYTE, SIZE_T=8BYTE//如果使用DWORD, 会报错 "Run-Time Check Failure #2 - Stack around the variable 'xxx' was corrupted.", 一般由变量越界导致LONGLONG dwWriteByte = 0;::WriteProcessMemory(hProcess, pVirBuf, &item, sizeof(LVITEM), (SIZE_T*)&dwWriteByte);//发送获取项目的Windows消息::SendMessage(hProcListView, LVM_GETITEM, 0, (LPARAM)pVirBuf);//将虚拟内存第sizeof(LVITEM)之后的数据读出, 保存至变量内LONGLONG dwReadByte = 0;std::string content(256, '\0');::ReadProcessMemory(hProcess, (LPCVOID)((int)pVirBuf + sizeof(LVITEM)), const_cast<char*>(content.c_str()), 255, (SIZE_T*)&dwReadByte);//输出std::cout << content.c_str() << " ";}std::cout << std::endl;}//释放虚拟内存::VirtualFreeEx(hProcess, pVirBuf, 4096, MEM_RELEASE);::CloseHandle(hProcess);return 0;}
然而,我遇到2个问题:(以上代码是在X32下编译的,我的操作系统是X64的)
1.不管我怎么修改我的代码,都没办法获取到ListView控件内的值?
因为我的电脑是64位系统, 那么"任务管理器"进程则是64位的, 使用OpenProcess实际返回的是一个64位的句柄值。如果, 你的程序是采用W32编译器, 那么定义的进程句柄变量实际上是一个32位的句柄变量。现在, 如果你用32位的句柄变量来保存64位的句柄值, 它实际上是保存了一个被截取后的64位的句柄值, 这个值是错误的。由于保存了一个被截取后的64位的句柄值而不是NULL,所以没办法检查出句柄值是错误的。这时, 你必须把编译器也调整为64位, 或者使用其他方法使句柄值内存长度统一。
2.程序结束时,会报错"Run-Time Check Failure #2 - Stack around the variable 'xxx' was corrupted."
A.造成此报错的原因一般是内存越界
B.这里造成的原因是:WriteProcessMemory/ReadProcessMemory第5个参数在X32下要传入DWORD类型,在X64下要传入SIZE_T类型。DWORD无论在X32/X64下均占用4BYTE,而SIZE_T在X64下占用8BYTE。如果,在X64下你传入DWORD,所以会报内存越界的错误,即使用强制转换。X64下解决办法即是考虑与SIZE_T占相同内存的LONGLONG类型或其他类型代替即可。
二、附录
int main() { int i = 0; i = sizeof(int); // x86:4 x64:4 i = sizeof(long); // x86:4 x64:4 i = sizeof(void*); // x86:4 x64:8 i = sizeof(short); // x86:2 x64:2 i = sizeof(float); // x86:4 x64:4 i = sizeof(double); // x86:8 x64:8 i = sizeof(int*); // x86:4 x64:8 i = sizeof(WORD); // x86:2 x64:2 i = sizeof(DWORD); // x86:4 x64:4 i = sizeof(LONGLONG); // x86:8 x64:8 i = sizeof(HANDLE); // x86:4 x64:8 i = sizeof(HWND); // x86:4 x64:8 i = sizeof(bool); // x86:1 x64:1 i = sizeof(char); // x86:1 x64:1 return 0; }
- VC 如何读取第三方软件ListView控件(外挂篇之一)
- ListView下拉刷新【第三方控件实现】
- 如何判断是否为第三方软件
- 如何使用FreeTextBox3.1.6第三方控件
- delphi中的第三方控件如何安装
- delphi中的第三方控件如何安装
- Android软件开发之制作第三方数据库与读取文件中数据库详解(三十四)
- NPOI 2.1.1 binary-第三方控件读取execl
- VB中利用第三方控件实现软件在线升级
- Delphi第三方控件大比拼(免费篇)
- Delphi第三方控件大比拼(收费篇)
- 第三方软件安装
- 第三方软件简介
- VS2005第三方控件地址(转)
- 第三方控件使用方法(转)
- TC第三方控件(官网)
- 第三方控件使用方法
- 第三方控件使用方法
- UI设计
- 文件下载
- 一个从jsp页面直接下载当前表格的方法
- js实现表单实时验证,显示提示
- angularjs onload事件
- VC 如何读取第三方软件ListView控件(外挂篇之一)
- Java线程的基本运用
- 查询sql语句执行消耗的时间
- bzoj1014: [JSOI2008]火星人prefix
- centOS 7 设置固定IP,无法上外网
- List.toArray的使用
- 排列组合
- 详细解读Jquery各Ajax函数:$.get(),$.post(),$.ajax(),$.getJSON()《转载》
- C++调用外部应用程序的方法的整理总结