温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何调试HookMain.exe

发布时间:2021-10-15 09:07:46 来源:亿速云 阅读:135 作者:iii 栏目:编程语言

这篇文章主要介绍“如何调试HookMain.exe”,在日常操作中,相信很多人在如何调试HookMain.exe问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何调试HookMain.exe”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、程序功能

在装好了工具的Windows XP中打开HookMain.exe,然后打开记事本,这时向键盘中键入任何消息都不会在记事本中出现,因为HookMain.exe已经让KeyHook.dll在记事本打开的时候加载进到记事本的进程当中了。在process explorer中可以看到
如何调试HookMain.exe
上面是notepad.exe这个进程,下面是加载的一部分动态链接库,可以看到在倒数第三行该库被加载了

二、HookMain.exe源代码

#include<stdio.h>
#include<conio.h>
#include<windows.h>

#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.dll的源代码

//KeyHook.cpp
#include<stdio.h>
#include<windows.h>

#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调试HookMain.exe

用OD打开这个程序,尝试去调试它
我是根据经验直接到内存的00401000H处找到了main的位置
书上使用了关键字符串检索的方法,当然书上的更好,不过殊途同归,都找到了main函数的入口
如何调试HookMain.exe
下面对这个主函数的汇编代码进行分析

从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处单步进入如何调试HookMain.exe
根据书上的说法,10001020就是钩子过程的地址

六、用OD调试notepad.exe进程中的KeyHook.dll

先打开notepad.exe(用OD)在调试设置当中设置中断于新模块
如何调试HookMain.exe
然后打开HookMain.exe,并在notepad.exe中敲击键盘,此时打开OD发现dll已经被注入进去了
如何调试HookMain.exe
然后双击找到的KeyHook.dll,进入调试
找到10001020处的KeyboardProc()函数
这就调试成功了

到此,关于“如何调试HookMain.exe”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI