-
-
[原创]利用钩子函数来注入DLL的一个具体应用:点击桌面不同图标,播放相应音符
-
发表于:
2011-6-27 21:17
18017
-
[原创]利用钩子函数来注入DLL的一个具体应用:点击桌面不同图标,播放相应音符
最近看核心编程,看到DLL注入这一章,有一个Desktop Item Positon Saver(DIPS)的例子,这个例子是使用窗口挂钩来将一个DLL注入到Explorer.exe的地址空间中,来保存和恢复图标位置。
于是便想根据这个例子自己改造一下,正好前段时间看到在 Google 的首页上,谷歌为了纪念电吉他之父莱斯·保罗 96 周年诞辰,特意做了一个很有意思的Doodle,这个 谷歌电吉他Logo可以让用户在其上面弹奏吉他,于是便想利用桌面图标来编一个类似的程序,点击不同的图标,发出不同的吉他音色的音符。
下面把编程的大概思路说一下:
首先就是找到桌面ListView控件的窗口句柄,刚开始在这里就遇到了问题。
核心编程这本书上讲到Windows外壳有一个类别为ProgMan的窗口,这个ProgMan窗口有且只有一个类别为SHELLDLL_DefView的子窗口。这个子窗口同样有且只有一个子窗口,子窗口的类别为SysListView32,这个SysListView32窗口就是桌面的ListView控件窗口。
于是我便利用了它的代码:
HWND hWndLV =GetFirstChild(GetFirstChild(
FindWindow(TEXT("ProgMan"), NULL)));
但发现运行不正确,于是便使用spy++查看,发现我的SysListView32窗口是位于类为WorkerW的窗口下。难道这是win7系统更改的?我也不清楚。因此,如果大家下载下来我的源代码后,如果运行不成功,最好用spy++查看一下窗口信息,看一看SysListView32控件到底是谁的子窗口,如果是ProgMan的子窗口,那么大家需要把MouseHookApp.cpp文件中的
HWND hWndLV;
EnumWindows(EnumWindowsProc,(LPARAM)&hWndLV);
和
EnumWindowsProc函数注释掉,
取消HWND hWndLV =GetFirstChild(GetFirstChild(
FindWindow(TEXT("ProgMan"), NULL)));这一代码的注释。
我发现类名为WorkerW的窗口不是唯一的,因此不能使用FindWindows了,改用了EnumWindows函数。
HWND hWndLV;
EnumWindows(EnumWindowsProc,(LPARAM)&hWndLV);
其中的EnumWindowsProc函数实现如下:
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam){
if(hwnd)
{
TCHAR classname[128];
GetClassName(hwnd, classname, 128);
if(!_tcscmp(classname, _T("WorkerW") ) )
{
HWND &hWndLV = *(HWND *)lParam;
TCHAR childClassName[128];
HWND hChildWnd = GetWindow(hwnd, GW_CHILD);
while(hChildWnd)
{
GetClassName(hChildWnd, childClassName, 128);
if(!_tcscmp(childClassName, _T("SHELLDLL_DefView")))
hWndLV = GetFirstChild(hChildWnd);
chASSERT(IsWindow(hWndLV));
return false;
}
}
}
return true;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!