看流星社区

 找回密码
 注册账号
查看: 2334|回复: 0

关于在DLL中获取主调用窗口的句柄

[复制链接]

该用户从未签到

发表于 2012-10-17 21:09:08 | 显示全部楼层 |阅读模式
近来在弄远程DLL注入,在DLL中创建了窗口,因某种需要,需获取宿主窗口的句柄,找了n多资料都没有很好的解决办法,然后找到如下一篇文章:

通过进程ID获得该进程主窗口的句柄
     一个进程可以拥有很多主窗口,也可以不拥有主窗口,所以这样的函数是不存在的,所幸的是,相反的函数是有的。所以我们可以调用EnumWindows来判断所有的窗口是否属于这个进程。
typedef struct tagWNDINFO
...{
DWORD dwProcessId;
HWND hWnd;
} WNDINFO, *LPWNDINFO;

BOOL CALLBACK YourEnumProc(HWND hWnd,LPARAM lParam)
...{
DWORD dwProcessId;
GetWindowThreadProcessId(hWnd, &dwProcessId);
LPWNDINFO pInfo = (LPWNDINFO)lParam;
if(dwProcessId == pInfo->dwProcessId)
...{
pInfo->hWnd = hWnd;
return FALSE;
}
return TRUE;
}
HWND GetProcessMainWnd(DWORD dwProcessId)
...{
WNDINFO wi;
wi.dwProcessId = dwProcessId;
wi.hWnd = NULL;
EnumWindows(YourEnumProc,(LPARAM)&wi);
return wi.hWnd;
}
如果这个进程没有窗口,函数返回NULL

经试验,在宿主窗口中调用GetProcessMainWnd( GetCurrentProcessId() )后得到的窗口句柄有时确实是该窗口的句柄,但有时得到的却是DLL的窗口的句柄,而在DLL的窗口过程中调用GetProcessMainWnd( GetCurrentProcessId() )只得到DLL窗口的句柄,并不能得到宿主窗口的句柄。【将dll直接注入执行注入代码的exe中进行测试】

将该代码做如下修改后,能得到正确的宿主窗口句柄:

typedef struct tagWNDINFO
...{
    DWORD dwProcessId;
    HWND hWnd;
    HWND Dll_hwnd;
} WNDINFO, *LPWNDINFO;
BOOL CALLBACK YourEnumProc(HWND hWnd, LPARAM lParam)
...{
    DWORD dwProcessId;
    GetWindowThreadProcessId(hWnd, &dwProcessId);
    LPWNDINFO pInfo = (LPWNDINFO)lParam;
    if( (dwProcessId == pInfo->dwProcessId) && (hWnd != pInfo->Dll_hwnd) )
    //确认找到的句柄不是DLL窗口的句柄
    //如果找到的是DLL窗口的句柄则返回FALSE以便继续查找宿主的窗口句柄
    ...{
        pInfo->hWnd = hWnd;
        return FALSE;
    }
    return TRUE;
}
HWND GetProcessMainWnd(DWORD dwProcessId, HWND Dll_hwnd)
//将DLL窗口的句柄传入,以便识别找到的句柄不是DLL窗口的句柄
...{
    WNDINFO wi;
    wi.dwProcessId = dwProcessId;
    wi.hWnd = NULL;
    wi.Dll_hwnd = Dll_hwnd;
    EnumWindows(YourEnumProc,(LPARAM)&wi);
    HWND re_hwnd = wi.hWnd;
    while( GetParent(re_hwnd) != NULL )
    //循环查找父窗口,以便保证返回的句柄是最顶层的窗口句柄
    ...{
        re_hwnd = GetParent( re_hwnd );
    }
    return re_hwnd;
}
在DLL的窗口过程中调用GetProcessMainWnd( GetCurrentProcessId(), this->m_hWnd )即可获得宿主窗口的句柄。
【备注】如果宿主进程已经调用了其它DLL并且该DLL也创建有窗口,那么,我想这个代码并不能保证得到的句柄不是其它DLL的窗口句柄,要做进一步的识别,我想,靠这个方法还是难以实现的了,或许可以考虑在注入DLL时(或注入之后?)传递该宿主窗口的句柄给DLL。
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-27 16:03

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表