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

怎么回事儿,请指点一下。
...全文
377 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
  • 打赏
  • 举报
回复
先关闭杀毒软件,我最近也在做钩子,今天刚上传了个钩子代码,你去搜搜
内容概要:本文围绕不确定环境下的多式联运路径优化问题展开研究,提出并实现了基于AFO算法、遗传算法(GA)和粒子群优化算法(PSO)的三种智能优化方法,并借助Matlab平台完成算法编程与仿真。研究构建了考虑时间、成本、转运风险等多重不确定因素的路径优化模型,系统比较了AFO、GA、PSO三种算法在收敛速度、全局寻优能力和稳定性方面的表现,同时引入Matlab自带的全局优化搜索器作为基准对照,深入分析各算法在复杂物流网络中的适用边界与性能差异。研究表明,AFO算法在解决此类组合优化问题时展现出更快的收敛效率和更强的局部规避能力。; 适合人群:具备一定Matlab编程基础与运筹优化知识,从事物流工程、交通运输规划、智能算法开发等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于多式联运、综合货运网络中的路径决策支持系统构建;②为不确定性条件下复杂路径规划问题提供智能算法选型依据与技术实现方案;③支持科研人员复现主流优化算法并开展横向性能对比实验,推动算法改进与实际落地。; 阅读建议:建议读者结合提供的Matlab代码逐模块分析算法实现流程,重点理解目标函数设计、约束条件处理及参数敏感性分析部分,可通过调整问题规模与算法参数进行对比实验,进一步拓展至动态路径规划或大规模网络优化等延伸场景。

15,465

社区成员

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

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