美文网首页
HOOK了MessageBoxW函数

HOOK了MessageBoxW函数

作者: f675b1a02698 | 来源:发表于2017-09-14 16:14 被阅读0次

    说明

    该函数通过消息hook注入dll到目标程序,之后通过inline hook 了messageboxw函数的头补个字节来实现MessageBox的HOOK

    代码1是dll内容,代码2是hook程序

    源码

    #include

    #include

    HWND hwnd = NULL;

    DWORD dwPid = 0;

    void HookOff();

    void HookOn();

    VOID InlineHook();

    typedef int (WINAPI* MBW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);

    MBW OldMsgBoxW = NULL;//指向原函数的指针

    FARPROC pfOldMsgBoxW;//指向函数的远指针

    BYTE OldCode[5];//原API入口

    BYTE NewCode[5];//新API的入口代码(jmp xxxxxxxx)

    HANDLE hProcess = NULL;//本程序进程句柄

    HINSTANCE hInst = NULL;//API所在的dll文件句柄

    BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpvReserved){

    switch (fdwReason){

    case DLL_PROCESS_ATTACH://进程加载DLL

    {

    DWORD dwPid = GetCurrentProcessId();

    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwPid);

    InlineHook();

    MessageBox(NULL, "DLL_PROCESS_ATTACH", "DLL HOOK", MB_OK);

    }

    break;

    case DLL_THREAD_ATTACH://线程加载DLL

    //MessageBox(NULL, "DLL_THREAD_ATTACH", "DLL HOOK", MB_OK);

    break;

    case DLL_THREAD_DETACH://线程卸载DLL

    //MessageBox(NULL, "DLL_THREAD_DETACH", "DLL HOOK", MB_OK);

    break;

    case DLL_PROCESS_DETACH://进程卸载DLL

    HookOff();

    MessageBox(NULL, "DLL_PROCESS_DETACH", "DLL HOOK", MB_OK);

    break;

    }

    return TRUE;

    }

    //自己的MessageBox函数

    int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType){

    HookOff();

    int nRet = MessageBoxW(hWnd, L"哈哈,MessageBoxW被HOOK了", lpCaption, uType);

    HookOn();

    return nRet;

    }

    //导出?或许不需要 开始inline hook

    VOID InlineHook(){

    //获取原API入口地址

    HMODULE hmod = LoadLibrary(TEXT("User32.dll"));

    OldMsgBoxW = (MBW)GetProcAddress(hmod, "MessageBoxW");

    pfOldMsgBoxW = (FARPROC)OldMsgBoxW;

    //出错判定

    if (NULL == pfOldMsgBoxW){

    MessageBox(NULL, TEXT("获取原API入口地址出错"), TEXT("error!"), 0);

    return;

    }

    //asm获取前5个字节,复制到OldCode

    __asm{

    lea edi, OldCode//获取OldCode数组的地址,放到edi

    mov esi, pfOldMsgBoxW//获取原API入口地址,放到esi

    cld//方向标志位,为以下两条指令做准备,从低地址到高地址

    movsd//复制原API入口前4个字节到OldCode数组

    movsb//复制原API入口第5个字节到OldCode数组

    }

    //这是准备跳转到我们函数的code

    NewCode[0] = 0xe9;//jmp

    __asm{

    lea eax, MyMessageBoxW//获取我们的MyMessageBoxW函数地址 1000

    mov ebx, pfOldMsgBoxW//原系统API函数地址 2000

    sub eax, ebx//intnAddr= UserFunAddr ?SysFunAddr 这里得到相对地址?没看太明白

    sub eax, 5//nAddr=nAddr-5

    mov dword ptr[NewCode + 1], eax//将算出的地址nAddr保存到NewCode后面个字节

    //注:一个函数地址占5个字节

    }

    HookOn();

    }

    //开启钩子的函数

    void HookOn(){

    if (NULL == hProcess){

    return;

    }

    DWORD dwTemp = 0;

    DWORD dwOldProtect;

    //修改API函数入口前个字节为jmp xxxxxx

    VirtualProtectEx(hProcess, pfOldMsgBoxW, 5, PAGE_READWRITE, &dwOldProtect);

    WriteProcessMemory(hProcess, pfOldMsgBoxW, NewCode, 5, 0);

    VirtualProtectEx(hProcess, pfOldMsgBoxW, 5, dwOldProtect, &dwTemp);

    }

    //关闭钩子的函数

    void HookOff(){

    if (NULL == hProcess){

    return;

    }

    DWORD dwTemp = 0;

    DWORD dwOldProtect;

    //恢复API函数入口前个字节

    VirtualProtectEx(hProcess, pfOldMsgBoxW, 5, PAGE_READWRITE, &dwOldProtect);

    WriteProcessMemory(hProcess, pfOldMsgBoxW, OldCode, 5, 0);

    VirtualProtectEx(hProcess, pfOldMsgBoxW, 5, dwOldProtect, &dwTemp);

    }

    LRESULT WINAPI myproc(int code, WPARAM w, LPARAM l){

    //只是使用钩子注入DLL到进程

    return CallNextHookEx(myproc, code, w, l);

    }

    源码

    #include

    #include

    typedef BOOL(_stdcall *LPAPI_IDP)(VOID);

    int main(int argc, PCHAR argv[]){

    HMODULE hModule = LoadLibrary("Kernel32");// 加载模块Kernel32

    if (hModule == NULL)

    {

    printf("被调试,无法获取 kernel32.dll模块\n");//ExitProcess(0); // 如果发现程序被调试 直接退出进程

    }

    LPAPI_IDP IsDebuggerPresent = GetProcAddress(hModule, "IsDebuggerPresent");// 获取下地址

    if (IsDebuggerPresent == NULL)

    {

    printf("被调试,无法获取 IsDebuggerPresent 地址\n");//ExitProcess(0); // 如果发现程序被调试 直接退出进程

    }

    if (*(BYTE *)IsDebuggerPresent == 0xcc ||// 调用前检测下是否被下了断点

    *(BYTE *)IsDebuggerPresent != 0x64 ||

    IsDebuggerPresent())// 调用

    {

    printf("被调试,下断点\n");//ExitProcess(0); // 如果发现程序被调试 直接退出进程

    }

    LPSTR name;

    __asm{

    mov eax, fs:[0x18]//_NT_TIB

    mov eax, [eax + 0x30]//_NT_TIB

    mov eax, [eax + 0xc]//_PEB_LDR_DATA

    mov eax, [eax + 0xc]//_LIST_ENTRY

    mov eax, [eax + 0x30]

    mov name, eax

    }

    wprintf(L"%s\n", name);

    BOOL ret = IsDebuggerPresent();

    printf("IsDebuggerPresent = %d\n", ret);

    HHOOK kbhook;

    HMODULE mydll = LoadLibrary("mydll.dll");

    HMODULE myproc = GetProcAddress(mydll, "myproc");

    kbhook = SetWindowsHookEx(WH_KEYBOARD, myproc, mydll, 0);

    if (kbhook == NULL){

    printf("SetWindowsHookEx failed %d\n", GetLastError());

    } else

    {

    printf("执行SetWindowsHookEx完成.\n");

    printf("额,不执行?\n");

    }

    //BOOL crdp = CheckRemoteDebuggerPresent();

    //消息循环

    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0)){

    TranslateMessage(&msg);

    DispatchMessage(&msg);

    };

    UnhookWindowsHookEx(kbhook);

    getchar();

    return 0;

    }

    相关文章

      网友评论

          本文标题:HOOK了MessageBoxW函数

          本文链接:https://www.haomeiwen.com/subject/gzwqsxtx.html