读取其他进程的数据

假设需要读取的进程为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 data
memcpy(filestr,item,256);

strTitle.Format("%s",filestr);


//free memory
VirtualFreeEx(hProcess, _tvi, 0, MEM_RELEASE); 
VirtualFreeEx(hProcess, _item, 0, MEM_RELEASE);

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

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

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

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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值