我用修改PE格式写了一个拦截API的程序,但是让DLL执行到修改函数地址的时候为什么我的安装钩子的EXE文件总是抱错,错误是加载DLL出错,就是LoadLibrary这是个函数调用失败,我拦截的MessageBoxA这个函数,请问是怎么回事。
  有谁有原代码可以参考一下,用修改PE文件的方法拦截,谢谢!

解决方案 »

  1.   

    一个简单采用钩子函数对MessageBoxA进行拦截例子: 
    其中Dll文件为: 
    HHOOK g_hHook; 
    HINSTANCE g_hinstDll; 
    FARPROC pfMessageBoxA; 
    int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption,UINT uType); 
    BYTE OldMessageBoxACode[5],NewMessageBoxACode[5]; 
    HMODULE hModule ; 
    DWORD dwIdOld,dwIdNew; 
    BOOL bHook=false; 
    void HookOn(); 
    void HookOff(); 
    BOOL init(); 
    LRESULT WINAPI MousHook(int nCode,WPARAM wParam,LPARAM lParam); 
    BOOL APIENTRY DllMain( HANDLE hModule, 
    DWORD ul_reason_for_call, 
    LPVOID lpReserved 


    switch (ul_reason_for_call) 

    case DLL_PROCESS_ATTACH: 
    if(!init()) 

    MessageBoxA(NULL,"Init","ERROR",MB_OK); 
    return(false); 

    case DLL_THREAD_ATTACH: 
    case DLL_THREAD_DETACH: 
    case DLL_PROCESS_DETACH: 
    if(bHook) UnintallHook(); 
    break; 

    return TRUE; 

    LRESULT WINAPI Hook(int nCode,WPARAM wParam,LPARAM lParam)//空的钩子函数 
    { return(CallNextHookEx(g_hHook,nCode,wParam,lParam)); 

    HOOKAPI2_API BOOL InstallHook()//输出安装空的钩子函数 

    g_hinstDll=LoadLibrary("HookApi2.dll"); 
    g_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook,g_hinstDll,0); 
    if (!g_hHook) 

    MessageBoxA(NULL,"SET ERROR","ERROR",MB_OK); 
    return(false); 

    return(true); 

    HOOKAPI2_API BOOL UninstallHook()//输出御在钩子函数 
    { return(UnhookWindowsHookEx(g_hHook)); 
    } BOOL init()//初始化得到MessageBoxA的地址,并生成Jmp XXX(MyMessageBoxA)的跳转指令 

    hModule=LoadLibrary("user32.dll"); 
    pfMessageBoxA=GetProcAddress(hModule,"MessageBoxA"); 
    if(pfMessageBoxA==NULL) 
    return false; 
    _asm 

    lea edi,OldMessageBoxACode 
    mov esi,pfMessageBoxA 
    cld 
    movsd 
    movsb 

    NewMessageBoxACode[0]=0xe9;//jmp MyMessageBoxA的相对地址的指令 
    _asm 

    lea eax,MyMessageBoxA 
    mov ebx,pfMessageBoxA 
    sub eax,ebx 
    sub eax,5 
    mov dword ptr [NewMessageBoxACode+1],eax 

    dwIdNew=GetCurrentProcessId(); //得到所属进程的ID 
    dwIdOld=dwIdNew; 
    HookOn();//开始拦截 
    return(true); 
    } int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption, UINT uType )//首先关闭拦截,然后才能调用被拦截的Api 函数 

    int nReturn=0; 
    HookOff(); 
    nReturn=MessageBoxA(hWnd,"Hook",lpCaption,uType); 
    HookOn(); 
    return(nReturn); 

    void HookOn() 

    HANDLE hProc; 
    dwIdOld=dwIdNew; 
    hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);//得到所属进程的句柄 
    VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为可写 
    WriteProcessMemory(hProc,pfMessageBoxA,NewMessageBoxACode,5,0);//将所属进程中MessageBoxA的前5个字节改为JMP 到MyMessageBoxA 
    VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为原来的属性 
    bHook=true; 

    void HookOff()//将所属进程中JMP MyMessageBoxA的代码改为Jmp MessageBoxA 

    HANDLE hProc; 
    dwIdOld=dwIdNew; 
    hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld); 
    VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld); 
    WriteProcessMemory(hProc,pfMessageBoxA,OldMessageBoxACode,5,0); 
    VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld); 
    bHook=false; 

    //测试文件: 
    int APIENTRY WinMain(HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, 
    int nCmdShow) 
    { if(!InstallHook()) 

    MessageBoxA(NULL,"Hook Error!","Hook",MB_OK); 
    return 1; 

    MessageBoxA(NULL,"TEST","TEST",MB_OK);//可以看见Test变成了Hook,也可以在其他进程中看见 
    if(!UninstallHook()) 

    MessageBoxA(NULL,"Uninstall Error!","Hook",MB_OK); 
    return 1; 

    return 0; 
    }
      

  2.   

    to rainbowinfog(浊清):
    我测试过了,当前进程序可以HOOK,但其它进程的消息框没反应。不知是不是我测试不对?如果您有完整的Source可email给我:[email protected] 为谢!