windows核心编程之DIPS工具学习总结
任务定义:进程DIPS和进程Explorer,前者使用窗口HOOK将DIPSLib.dll注入到后者的进程地址空间中,于是两个进程中都有同一个DIPSLib.dll,因此可以让两个dll共享一些数据,从而方便以DIPS作为客户端,以注入到Explorer的DIPSLib.dll为服务器端进行通信,完成对Explorer的一些操作。
具体分析:
DIPS中的函数:_tWinMain();Dlg_Proc();Dlg_OnCommand();Dlg_OnInitDialog();
DIPSLib中的函数:DllMain();SetDIPSHook();GetMsgProc();Dlg_OnClose();SaveListViewItemPositions(); RestoreListViewItemPositions();Dlg_Proc();
DIPSLib中的共享数据:g_hhook(标识设置在Explorer中的钩子);g_dwThreadIdDIPS(标识设置HOOK的线程,也就是DIPS中的主线程);全局数据:g_hinstDll(标识当前dll实例,在DIPS或者在Explorer)
流程::_tWinMain()中建立DIPS的主窗口,然后根据用户的选择记录SAVE或者RESTORE状态,接着找到Explorer的目标子窗口ListView的窗口句柄hwndLV,继而由此句柄找到创建它的线程ID,线程ID在系统中是唯一的,可以对此句柄设置HOOK,调用SetDIPSHook()函数(*这个函数会最终使得服务器建立好),此时调用的是映射在DIPS地址空间中的dll中的函数,此函数在内部先把当前线程ID保存到g_dwThreadIdDIPS,以便目标进程Explorer中的dll可以和当前进程通信,然后对调用SetWindowsHookEx真正对前面所说的目标线程ID设置HOOK,并向它发送一个消息,引起系统调用目标线程的HOOK函数,在这里是GetMsgProc(),此函数如果是第一次被调用的话,会创建一个隐藏的窗口,这个窗口作为服务器来和客户端(也就是DIPS)通信,然后发送一个信息给客户端(根据g_dwThreadIdDIPS找到客户端线程),告诉客户端服务器已经准备好;当服务器准备好了,回到前面SetDIPSHook()这个位置,此函数返回,客服端接收到服务器刚才发送的信息(本来服务器在SetDIPSHook()之后会调用GetMessage()进入阻塞),于是被唤醒,然后找到隐藏的窗口(也就是服务器窗口),根据用户保存的SAVE或者RESTORE状态向服务器发送相应的消息,服务器根据消息调用自己的对话框处理函数Dlg_Proc(),如果是SAVE则调用SaveListViewItemPositions(),如果是RESTORE则调用RestoreListViewItemPositions();最后客户端发送CLOSE信息让服务器窗口关闭,然后unhook,这里要注意的是unhook是通过调用SetDIPSHook(),并且参数为0,虽然是调用自己进程中的SetDIPSHook(),但是由于和目标进程中dll共享了g_hhook,因此可以真正调用UnhookWindowsHookEx()来unhook这个hook。
精华:此程序最大的精华是两个共享变量以及几个标识变量的使用,值得借鉴。