读取其他进程的数据

来源:互联网 发布:阿里巴巴云计算张北 编辑:程序博客网 时间:2024/05/25 20:00

假设需要读取的进程为Exe可执行程序A

1、根据A的实际打开程序名:A.exe,来找到这个程序的窗口句柄(和进程句柄不同)

typedef struct tagWNDINFO{    DWORD dwProcessId;    HWND hWnd;} WNDINFO, *LPWNDINFO;BOOL CALLBACK MyEnumProc(HWND hWnd,LPARAM lParam)//枚举所有进程{    DWORD dwProcId;    GetWindowThreadProcessId(hWnd, &dwProcId);    LPWNDINFO pInfo=(LPWNDINFO)lParam;    if(dwProcId==pInfo->dwProcessId)    {        // 在此添加更多限制条件        CString strTmp;        GetClassName(hWnd, strTmp.GetBuffer(200), 200);        strTmp.ReleaseBuffer();        if (!strTmp.Compare("LButton")) // 按钮, 编辑框TEdit等, 具体可使用Spy++查看        {            pInfo->hWnd = hWnd;            return FALSE;        }        if (IsWindowVisible(hWnd)) // 当前窗口是否可见        {            pInfo->hWnd = hWnd;     // 获取到第一个窗口句柄            return FALSE;        }    }    return TRUE;}HWND GetProcessHwnd(DWORD proccessId){    WNDINFO wi;    wi.dwProcessId = proccessId;    wi.hWnd = NULL;    EnumWindows(MyEnumProc,(LPARAM)&wi);    EnumChildWindows(wi.hWnd, MyEnumProc, (LPARAM)&wi); // 枚举窗口的子窗口句柄, MFC中的控作等    return wi.hWnd;}void GetProcessInfo(CString processName){    //创建进程快照(TH32CS_SNAPPROCESS表示创建所有进程的快照)    HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);    //PROCESSENTRY32进程快照的结构体           PROCESSENTRY32 pe;              //实例化后使用Process32First获取第一个快照的进程前必做的初始化操作    pe.dwSize = sizeof(PROCESSENTRY32);     //下面的IF效果同:           //if(hProcessSnap == INVALID_HANDLE_VALUE)   无效的句柄      if(!Process32First(hSnapShot,&pe))      {                  return;        }              processName.MakeLower();      BOOL clearprocess = FALSE;    //如果句柄有效  则一直获取下一个句柄循环下去     while (Process32Next(hSnapShot,&pe))      {                       //pe.szExeFile获取当前进程的可执行文件名称         CString scTmp = pe.szExeFile;            scTmp.MakeLower();                     char modPath[MAX_PATH] = {0};        if(!scTmp.Compare(processName))            {                               //从快照进程中获取该进程的PID(即任务管理器中的PID)            DWORD dwProcessID = pe.th32ProcessID;               //获取进程的句柄            HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE,FALSE,dwProcessID);               //获取第一个可视窗口的句柄            HWND hWnd = GetProcessHwnd(dwProcessID);        }     }          ::CloseHandle(hSnapShot);}

上面的这一段代码可以完美获取程序的主窗口句柄和子窗口句柄!再一次强调不是进程句柄哦!

2、通过窗口句柄,获取窗口的内容(主文档标题,编辑框内容,静态框内容)。但是如果要获取比较复杂的窗口的文本内容,就会麻烦一些。

//获取简单窗口的内容GetWindowText(hWnd,strText.GetBuffer(256), 256);

比如获取一个TreeView的内容,就比较麻烦。总体思路就是通过发消息获取。

//从快照进程中获取该进程的PID(即任务管理器中的PID)DWORD dwProcessID = pe.th32ProcessID;  //获取第一个可视窗口的句柄HWND hWnd = GetProcessHwnd(dwProcessID);//获取进程的句柄HANDLE hProcess = ::OpenProcess(PROCESS_VM_OPERATION |PROCESS_VM_READ | PROCESS_VM_WRITE |PROCESS_QUERY_INFORMATION,FALSE,dwProcessID);//----------------//给_lvi,_item分配进程级的虚拟内存空间TVITEM tvi, *_tvi;char *_item; char item[256];CTreeCtrl* pTreeCtrl = ((CTreeCtrl*)CWnd::FromHandle((HWND)hWnd));int nItemNum = pTreeCtrl->GetCount();HTREEITEM Testitem1;Testitem1=pTreeCtrl->GetRootItem();long ret = (long)Testitem1;_tvi=(TVITEM*)VirtualAllocEx(hProcess, NULL, sizeof(TVITEM), MEM_COMMIT, PAGE_READWRITE); _item=(char*)VirtualAllocEx(hProcess, NULL, 256, MEM_COMMIT, PAGE_READWRITE); tvi.cchTextMax=256;tvi.hItem=(HTREEITEM)ret;tvi.mask=TVIF_TEXT;tvi.pszText=_item;//把_lvi 写入进程WriteProcessMemory(hProcess, _tvi, &tvi, sizeof(TVITEM), NULL);//发消息得到数据::SendMessage(hWnd, TVM_GETITEM, 0 , (LPARAM)_tvi); //从进程中读出数据BOOL bRead = ReadProcessMemory(hProcess, _item, item, 256, NULL);char filestr[256];//copy datamemcpy(filestr,item,256);strTitle.Format("%s",filestr);//free memoryVirtualFreeEx(hProcess, _tvi, 0, MEM_RELEASE); VirtualFreeEx(hProcess, _item, 0, MEM_RELEASE);

执行这段代码的前提是已经获取了该程序进程的ID和对应窗口的句柄。网上也有很多这样的内容,也可查看其它文章,对照理解。

3、至此,就完成了从其他进程中读取文本内容的方法。但是有个注意事项,本篇文章所给出的方法只针对于32位程序。如果你要读取的程序是64位的,可将里面的一些函数和变量换成64位的。可能替换过程还需要再进行一些查阅资料。但实现的整理思路是想通的。本文的实现也是经过验证的。

4、spy++是对这种分析极为有效的工具。是微软编译工具的其中一个,善加利用。我的资源里有下载,需要的可以去看看。

附spy++ 下载链接:
SPY++下载

0 0