这篇文章主要介绍“如何调试HookMain.exe”,在日常操作中,相信很多人在如何调试HookMain.exe问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何调试HookMain.exe”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
在泰州等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站设计、网站建设 网站设计制作按需设计网站,公司网站建设,企业网站建设,成都品牌网站建设,成都全网营销,外贸网站制作,泰州网站建设费用合理。
在装好了工具的Windows XP中打开HookMain.exe,然后打开记事本,这时向键盘中键入任何消息都不会在记事本中出现,因为HookMain.exe已经让KeyHook.dll在记事本打开的时候加载进到记事本的进程当中了。在process explorer中可以看到
上面是notepad.exe这个进程,下面是加载的一部分动态链接库,可以看到在倒数第三行该库被加载了
#include#include #include #define DEF_DLL_NAME "KeyHook.dll" #define DEF_HOOKSTART "HookStart" #define DEF_HOOKSTOP "HookStop" typedef void(*PFN_HOOKSTART)(); typedef void(*PFN_HOOKSTOP)(); void main(){ HMODULE hDll = NULL; PFN_HOOKSTART HookStart = NULL; PFN_HOOKSTOP HookStop = NULL; char ch=0; //加载dll hDll = LoadLibraryA(Dll_NAME); //获取导出函数的地址 HookStart =(PFN_HOOKSTART)GetProcAddress(hDll,HOOK_START); HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll,HOOK_STOP); //开始hook HookStart(); //输入Q退出hook printf("输入Q退出hook!\n"); while(1) { char h = getch(); putch(h); if(h == 'Q'); break; } //结束hook HookStop(); //卸载dll FreeLibrary(hDll); return 0; }
//KeyHook.cpp #include#include #define DEF_PROCESS_NAME "notepad.exe" HINSTANCE g_hInstance = NULL; HHOOK g_hHook = NULL; HWND g_hWnd = NULL; BOOL WINAPI DLLMain(HINSTANCE hinstDLL,DWORD dwReason,LPVOID lpvReserved){ switch(dwReason){ case DLL_PROCESS_ATTACH: g_hInstance = hinstDLL; break; case DLL_PROCESS_DETACH: break; } return TRUE; } LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam) { char szPath[MAX_PATH] = {0,}; char *p = NULL; if(nCode>=0){ //bit 31:0 = key press,1 = key release if(!(lParam&0x80000000)){ GetModuleFileNameA(NULL,szPath,MAX_PATH); p = strrchr(szPath,'\\'); //比较当前进程名称,若为notepad.exe,则消息不会传递给应用程序(或下一个“钩子”) if( !_stricmp(p+1,DEF_PROCESS_NAME) ) return 1; } } //若非notepad.exe,则调用CallNextHookEx()函数,将消息传递给应用程序(或者下个钩子) return CallNextHookEx(g_hHook,nCode,wParam,lParam); } #ifdef __cplusplus extern "C"{ #endif __declspec(dllexport) void HookStart(){ g_hHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,g_hInstance,0); } __declspec(dllexport) void HookStop(){ if(g_hHook) { UnhookWindowsHookEx(g_hHook); g_hHook = NULL; } } #ifdef __cplusplus } #endif
在用C语言写Dll文件的时候,用__declspec指定导出函数;
CALLBACK称为回调函数,是在某个特定事件发生时被指定调用的函数。在这里松开键盘按键就是这个特定的事件;
大致了解了dll文件的源代码
用OD打开这个程序,尝试去调试它
我是根据经验直接到内存的00401000H处找到了main的位置
书上使用了关键字符串检索的方法,当然书上的更好,不过殊途同归,都找到了main函数的入口
下面对这个主函数的汇编代码进行分析
从00401000H到0040102EH,程序调用LoadLibraryA将KeyHook.dll载入,检测是否载入成功,同时将该模块的句柄交给EAX,这里我猜测00401088H处的函数应该是一个弹窗函数,当载入失败的时候会弹出来并告诉用户载入模块失败
从0040102FH到00401049H将两个导入函数的地址传给两个指针,我暂时找不到这两个指针,只知道HookStart()的地址传给了EBX,因为源程序后面立刻调用了HookStart(),同时在汇编处立刻调用了地址位于EBX处的函数。
从0040104BH到00401068H处,首先先调用了载入的HookStart()函数,之后调用位于00401088H处的printf()函数,之后进入一段循环,71H代表的是q,所以当输入q的时候退出循环
此处就能看出来了,之前的GetProAdress函数将得到的地址传给EAX,然后将EAX的值传给EBX和EDI,所以这里结束循环的时候,直接调用EDI处的HookStop()函数
最后释放dll同时释放所有栈空间
这就是这个程序汇编的运行原理,我们研究一下HookStart()函数的原理,于是我们在0040104BH处单步进入
根据书上的说法,10001020就是钩子过程的地址
先打开notepad.exe(用OD)在调试设置当中设置中断于新模块
然后打开HookMain.exe,并在notepad.exe中敲击键盘,此时打开OD发现dll已经被注入进去了
然后双击找到的KeyHook.dll,进入调试
找到10001020处的KeyboardProc()函数
这就调试成功了
到此,关于“如何调试HookMain.exe”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!