static LRESULT WINAPI GetMsgProc(int code, WPARAM wParam, LPARAM lParam) 
{
return ::CallNextHookEx(g_hHook, code, wParam, lParam);
}BOOL WINAPI SetSysHook(BOOL bInstall, DWORD dwThreadId)
{
BOOL bOk;
if(bInstall) 
{
g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, 
ModuleFromAddress(GetMsgProc), dwThreadId); 
bOk = (g_hHook != NULL);

else 
{
bOk = ::UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
return bOk;
}
当dwThreadId为安装钩子的App程序中的::GetCurrentThreadId()时注入该App没问题,但不是我想要的,我想注入系统范围内的,所以dwThreadId为0传入,但一执行到SetWindowsHookEx这里就崩溃,提示为:xx内存不能为 "written"

解决方案 »

  1.   


    static HMODULE ModuleFromAddress(PVOID pv) 
    {
    MEMORY_BASIC_INFORMATION mbi;
    if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
    {
    return (HMODULE)mbi.AllocationBase;
    }
    else
    {
    return NULL;
    }
    }
      

  2.   

    g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, 
                ModuleFromAddress(GetMsgProc), dwThreadId); 
    ============
    第三个参数一般是所在DLL的模块句柄,没仔细看你所写的函数,一般的做法是在DllMain中保存这个句柄,然后当作第三个参数来用,不用这样麻烦。
      

  3.   

    第3参数是系统API GetMsgProc函数所在的模块句柄,我觉得没错啊
      

  4.   

    你好像是用ModuleFromAddress来获取这个模块的吧,老实说,你的这个函数我没看明白,VirtualQuery好像不能完成你所想的功能吧,一般来说全局钩子是写在DLL中的,所以第三个参数就是这个DLL的模块句柄,也就是BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, calling function
      LPVOID lpvReserved   // reserved
    );
    第一个参数,你在DLL中保存这个参数,然后传给SetWindowsHookEx不很方便吗?
      

  5.   

    你这个应该是抄《windows 核心编程 第五版》API拦截这节的吧,应该改成
    g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, 
                ModuleFromAddress(SetSysHook), dwThreadId); 
      

  6.   

    改了SetSysHook,模块句柄也是一样的
      

  7.   

    又新发现:我拿到其他同样是xp sp2上机子上就正常,莫非我系统上中了木马还是???有时候关机时,就会弹出svchost.exe的错误框,一直没怎么注意
      

  8.   

    ModuleFromAddress 这是个什么函数?我没查到第三个参数是传入DllMain函数的第一个参数。