HHOOK g_hhook = NULL;//回调函数
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
wchar_t buf[128] = {0};
wsprintf(buf,_T("nCode:%d"), nCode);
MessageBoxW(NULL, buf,L"",MB_OK); return ::CallNextHookEx(g_hhook, nCode, wParam ,lParam);
}BOOL InstallHook()
{
//获得窗口句柄
HWND hWnd = FindWindow(_T("Notepad"),NULL);
if (NULL == hWnd)
{
MessageBoxW(NULL,_T("获得窗口句柄为空"), L"", MB_OK);
return FALSE;
}
//获得线程ID
DWORD dwThreadId = 0;
dwThreadId = GetWindowThreadProcessId(hWnd,NULL);
if (dwThreadId == 0)
{
MessageBoxW(NULL,_T("获得窗口线程句柄不正"), L"", MB_OK);
return FALSE;
}
g_hhook = SetWindowsHookExA(WH_KEYBOARD, KeyboardProc, GetModuleHandleA("本Dll的名字"), dwThreadId);
if (NULL == g_hhook)
{
//MessageBoxW(_T("SetWindowsHookExA Fail"));
int err = GetLastError();
wchar_t buf[128] = {0};
wsprintf(buf,_T("LGLE:%d"), err);
MessageBoxW(NULL, buf,L"",MB_OK);
}
return TRUE;
}
在dllmain中调用了InstallHook这个函数进行HOOK现在我想把此dll注入到记事本中,用其它的方法注入的。而不是通过另一个程序调用InstallHook这个函数
我通过调试发现走到这一步(if (NULL == g_hhook))的时候都没有问题,但是,就是没有HOOK 成功,用别的工具看不到消息钩子。按键盘也不弹框。便是dll己经注入了怎么回事儿,请指点一下。

解决方案 »

  1.   

    HHOOK g_hhook 设置共享代码段看看
      

  2.   

    我以前也试过这样,是不成功的。
    特别你在dllmain里面调用SetWindowHookEx是错误的。不知你的注入方式是是怎样的。
    dll文件
    /****************************************************************************
    Inject.dll
    ****************************************************************************/
    #include <windows.h>
    /****************************************************************************
    使用下面的HMODULE GetCurrentModule()可以获取dll自己的句柄。
    接着使用
    TCHAR lib_name[MAX_PATH]; 
    ::GetModuleFileName( GetCurrentModule(), lib_name, MAX_PATH );
    就可以获取dll的路径了Most DLL developers have faced the challenge of detecting a HMODULE/HINSTANCE handle 
    within the module you're running in. It may be a difficult task if you wrote the DLL 
    without a DLLMain() function or you are unaware of its name. For example:
    Your DLL was built without ATL/MFC, so the DLLMain() function exists, 
    but it's hidden from you code and you cannot access the hinstDLL parameter. 
    You do not know the DLL's real file name because it could be renamed by everyone, 
    so GetModuleHandle() is not for you.
    This small code can help you solve this problem:
    ****************************************************************************/
    #if _MSC_VER >= 1300    // for VC 7.0
    // from ATL 7.0 sources
    #ifndef _delayimp_h
    extern "C" IMAGE_DOS_HEADER __ImageBase;
    #endif
    #endif
    HMODULE GetCurrentModule()
    {
    #if _MSC_VER < 1300    // earlier than .NET compiler (VC 6.0)

    // Here's a trick that will get you the handle of the module
    // you're running in without any a-priori knowledge:
    MEMORY_BASIC_INFORMATION mbi;
    static int dummy;
    VirtualQuery( &dummy, &mbi, sizeof(mbi) );

    return reinterpret_cast<HMODULE>(mbi.AllocationBase);
    #else    // VC 7.0
    // from ATL 7.0 sources
    return reinterpret_cast<HMODULE>(&__ImageBase);
    #endif
    }
    //当这个dll被注入到某个进程时,IsDllAlreadyInject会被设为true
    //当卸载dll时,发现IsDllAlreadyInject为false,说明这个dll已经被卸载了。
    bool IsDllAlreadyInject=false;LRESULT HookProc (int code, WPARAM wParam, LPARAM lParam)
    {
    #define pCW ((CWPSTRUCT*)lParam) if( (pCW->message)!=WM_NULL )
    return true; BOOL InjectResult=FALSE; //begin subclass
    if ( pCW->lParam==-10000 )
    {
    //first Uninstall WH_CALLWNDPROC hook
    if (!::UnhookWindowsHookEx(  (HHOOK)pCW->wParam   ))
    {
    trace(_T("UnhookWindowsHookEx Failed"));
    goto END;
    } //撤销成功;在这里添加你自己的代码
    // Let's increase the reference count of the DLL (via LoadLibrary),
    // so it's NOT unmapped once the hook is removed;
    TCHAR lib_name[MAX_PATH]; 
    ::GetModuleFileName( GetCurrentModule(), lib_name, MAX_PATH );
    InjectResult= ( NULL!=::LoadLibrary( lib_name ) ); IsDllAlreadyInject=true;
    } //end inject
    else if ( pCW->lParam==-10001 )
    {
    //first Uninstall WH_CALLWNDPROC hook
    if (!::UnhookWindowsHookEx(  (HHOOK)pCW->wParam   ))
    {
    trace(_T("UnhookWindowsHookEx Failed"));
    goto END;
    } //当卸载dll时,发现IsDllAlreadyInject为false,说明这个dll已经被卸载了。
    if (!IsDllAlreadyInject)
    {
    trace("dll already not inject");
    goto END;
    } //撤销注入;在这里添加你自己的代码

    InjectResult=::FreeLibrary( GetCurrentModule() );
    }END: //保存结果
    TCHAR buf[4];
    _itot((int)InjectResult,buf,10);
    ::WriteProfileString("InjectDll",_T("InjectResult"),buf); return true;
    }
    extern "C" _declspec(dllexport) BOOL Inject(HWND hWnd,bool IsInject)
    {
    HHOOK hHook = SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)HookProc, 
    /*::GetModuleHandle(_T("Inject.dll"))*/ GetCurrentModule() , GetWindowThreadProcessId(hWnd,NULL) ); if( !hHook )
    return FALSE; //send message to make target application load this dll
    //after calling SetWindowsHookEx,the application will not 
    //Load Dll immediately until it receives a message
    // By the time SendMessage returns, 
    // the hWnd has already been subclassed
    SendMessage( hWnd,WM_NULL,(WPARAM)hHook, IsInject? -10000 : -10001); return ::GetProfileInt("InjectDll",_T("InjectResult"),0);
    }
    //-------------------------------------------------------------
    // HookProc
    // Notice:
    // - executed by the instance of "HookInjEx.dll" mapped into "explorer.exe";
    //
    // When called from InjectDll:
    //   - sublasses the start button;
    //   - removes the hook, but the DLL stays in the remote process
    // though, because we increased its reference count via LoadLibray
    // (this way we disturb the target process as litle as possible);
    //
    // When called from UnmapDll:
    //   - restores the old window procedure for the start button;
    //   - reduces the reference count of the DLL (via FreeLibrary);
    //   - removes the hook, so the DLL is unmapped;
    //
    // Also note, that the DLL isn't unmapped immediately after the
    // call to UnhookWindowsHookEx, but in the near future
    // (right after finishing with the current message).
    // Actually it's obvious why: windows can NOT unmap the 
    // DLL in the middle of processing a meesage, because the code
    // in the hook procedure is still required. 
    // That's why we can change the order LoadLibrary/FreeLibrary &
    // UnhookWindowsHookEx are called.
    //
    // FreeLibrary, in contrast, unmapps the DLL imeditaley if the 
    // reference count reaches zero.
    //在你的exe里调用以下函数把dll注入到指定窗口/****************************************************************************
    IsInject:
    true  表示注入dll
    false 表示卸载dll
    ****************************************************************************/
    /*
    static
    BOOL InjectWnd(HWND hWnd,bool IsInject)
    {
    HMODULE hDll=LoadLibrary(_T("Inject.dll"));
    if (!hDll) return FALSE; BOOL(*Inject)(HWND,bool)=(BOOL(*)(HWND,bool))GetProcAddress(hDll,"Inject");
    if (!Inject) return FALSE; BOOL ret=Inject(hWnd,IsInject); FreeLibrary( hDll ); //释放模块句柄 return ret;
    }
    */
      

  3.   

    确实在dllmain里面调用 setwindowshookex  是不好使的。但是也没有返回错误