关于SetWindowsHookEx

永磁体呵呵哒 2012-07-24 09:06:11

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己经注入了

怎么回事儿,请指点一下。
...全文
301 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
jacky_qiu 2012-07-27
  • 打赏
  • 举报
回复
我以前也试过这样,是不成功的。
特别你在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;
}
*/

永磁体呵呵哒 2012-07-27
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

HHOOK g_hhook 设置共享代码段看看
[/Quote]

我试试这个,谢谢。
永磁体呵呵哒 2012-07-27
  • 打赏
  • 举报
回复
确实在dllmain里面调用 setwindowshookex 是不好使的。但是也没有返回错误
贪玩的老鼠 2012-07-25
  • 打赏
  • 举报
回复
HHOOK g_hhook 设置共享代码段看看
gmyhbio 2012-07-25
  • 打赏
  • 举报
回复
确定调用了函数?
确定是记事本为焦点时按的键盘?。
第一次按键没效果,会激活钩子。
再按才有用 - -

还有就像2L说的,你确定你的钩子没被拦截?
imlab 2012-07-25
  • 打赏
  • 举报
回复
先关闭杀毒软件,我最近也在做钩子,今天刚上传了个钩子代码,你去搜搜

15,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧