我利用SetWindowsHookEx将一个DLL注入某程序后,
在InitInstance()中判断,如果是被挂接的程序加载DLL,则创建MFC窗口,
BOOL CDllApp::InitInstance() 
{
         g_hInst = m_hInstance;
         //gs_hHook是SetWindowsHookEx返回的句柄,shared.
if(gs_hHook) g_MainDlg.Create(IDD_MAINDLG);
return CWinApp::InitInstance();
}而在ExitInstance里
int CRxwgApp::ExitInstance() 
{
if(IsWindow(g_MainDlg.GetSafeHwnd())) 
            g_MainDlg.DestroyWindow();
         
         //注意这里
if(gs_hHook) CloseHandle(gs_hHook);
gs_hHook   = NULL; return CWinApp::ExitInstance();
}请问在上面的ExitInstance里,调用CloseHandle(gs_hHook)是否正确?
或者是否应该调用UnhookWindowsHookEx,然后再调用CloseHandle

解决方案 »

  1.   

    只需要用UnhookWindowsHookEx,而且必须用。不需要CloseHandle
      

  2.   

    我按你的方法做了。有个严重的问题一直困扰我。第一次启动挂接程序时,能正常挂接。关闭挂接程序后(===我在挂接程序窗口的OnClose里调用了UnhookWindowsHookEx,不知道是否正确==) ,,,再次启动挂接程序,会导致被挂程序没有任何提示的关闭.........不知道能否指点一二?
      

  3.   

    ExitInstance() 中调用UnhookWindowsHookEx试试
      

  4.   

    我在挂接程序窗口的OnClose里调用了UnhookWindowsHookEx再次启动挂接程序,会导致被挂程序没有任何提示的关闭.........不知道能否指点一二?
    ========================================================是不是你在hook中对被挂程序做了一些特殊操作?再次启动hook成功否?
      

  5.   

    不好意思这么久才来。
    To: yjgx007void InstallHook( HWND hCallerWnd, DWORD dwThreadId ) 
    {
    if( dwThreadId == 0 || gs_hHook ) return ;
    gs_hHook = SetWindowsHookEx( WH_GETMESSAGE, (HOOKPROC) GetMsgProc, g_hInst, dwThreadId );
    PostThreadMessage( dwThreadId, WM_NULL, 0, 0 );
    g_dwHookedThread = dwThreadId; 
    gs_hCallerWnd = hCallerWnd;
    }
    这就是Hook方法。并且在第二次调用Hook时,我跟踪了挂接程序,返回是成功的,但似乎在被挂程序处理GetMsgProc时立刻就关闭了。LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam) 
    {
    StartFunctions();
    if( g_bHooked && code == HC_ACTION )
    {
    PMSG pMsg = (PMSG)lParam;
    switch ( pMsg->message )
    {
    case WM_KEYDOWN:
    if( pMsg->wParam == VK_F11 )
    {
    if(!g_MainDlg.IsWindowVisible() )
    {
    g_MainDlg.SetWindowPos( &CWnd::wndTopMost , 0,0,0,0, \
    SWP_NOMOVE|SWP_NOSIZE);
    g_MainDlg.ShowWindow( SW_SHOW );
    }
    else
    {
    g_MainDlg.ShowWindow( SW_HIDE );
    }
    }
    break;
    }
    }
    return(CallNextHookEx(gs_hHook, code, wParam, lParam));
    }
    这就是GetMsgProc,其中的StartFunctions里是一些初始化操作,只执行一次,里面创建了一个定时器,并且修改了目标程序的内存地址(是一段代码)。
    不知道哪里会有问题?????
      

  6.   

    unhook..., then closehandle.
      

  7.   

    to: freebird_top
    试过了,还是不行。
      

  8.   

    Check that the function - StartFunctions, may it causes this problem.
    Paste detail code...
      

  9.   

    void StartFunctions
    {
        if(g_bHooked) return;
        g_bHooked = TRUE;
        
        LogMessage("加载地图数据");
        LoadMapInfo(); <<--这里从文件加载了一些数据,有分配内存的操作
        LoadConfig(NULL); <<加载文件,没有分配内存   
        LogMessage("创建定时器"); 
        InitializeFunctions(); <<修改进程数据,使用ReadProcessMemory和WriteProcessMemory
        g_nTimerId = (UINT)SetTimer( NULL, 0, 1000, TimerProc );
        g_MainDlg.UpdateDialog(); <<更新窗口,无特殊操作
    }以上就是StartFunctions
    如果是内存分配造成的问题,由于目标进程能截获内存操作的异常,所以应该会出现内存操作出错的提示,ReadProcessMemory两个函数我也进行了跟踪,能正常读出数据和写入。
      

  10.   

    不是必须用UnhookWindowsHookEx吧?
      

  11.   

    你注释掉StartFunctions看看,如果正常...
      

  12.   

    closehandle只是将HANDLE计数减1,而实际上在你的程序中此handle的计数至少为2,所以这句没有将hook释放掉,你一定要用UnhookWindowsHookEx!
    你说的被挂程序消失很容易解释的
    int CRxwgApp::ExitInstance() 
    {
    //注意这里if(gs_hHook) UnhookWindowsHookEx(gs_hHook);
    gs_hHook  = NULL;if(IsWindow(g_MainDlg.GetSafeHwnd())) 
                g_MainDlg.DestroyWindow();
             
             
    return CWinApp::ExitInstance();
    }
    先等结果
      

  13.   

    真不好意思,这么久才来
    TO:shaojun1314
    按照你的做法我已经试过了,仍然会造成这种情况。请问:有没有可能是被挂程序的问题,它的一些防挂机制造成的?
      

  14.   

    各位,,,,,,,,,,问题已解决,是因为窗口程序里的一个初始化代码发生了内存访问错误造成的,真郁闷才发现感谢各位的关心与支持,如有兴趣,请帮忙看看此帖:
    http://community.csdn.net/Expert/topic/5260/5260287.xml?temp=.8815119