关于SetWindowsHookEx的使用

轻箬笠 2020-04-27 03:48:55
我想做个东西,把dll注入到另一个进程里面去,从而过滤一下特定的消息。
SetWindowsHookEx(
WH_GETMESSAGE,
(HOOKPROC)FunctionAddress,
ModuleHandle,
dwThreadId
);

我使用上面这个函数的时候碰到几个问题。
第一种解决方案,将dwThreadId=0,也就是定义成全局钩子,但是我希望只有我的目标程序能够加载这个dll(目标程序的名字不一定),其他程序加载这个dll的时候,直接卸载。
第二种解决方案,为dwThreadId设置一个值,我用获取进程的主线程ID上面的方案获取了要注入的那个进程的mainThreadId,但是SetWindowsHookEx执行失败,错误码87(The parameter is incorrect. )

但是,我把dwThreadId设置为GetCurrentThreadId(),SetWindowsHookEx是执行成功的。
我现在应该怎么处理呢?定义全局钩子的话,如何实现只让目标程序挂上钩子,其他程序不挂?如果是为主线程挂上钩子的话,这个错误码87该怎么解决?
...全文
335 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
轻箬笠 2020-05-21
  • 打赏
  • 举报
回复
引用 1 楼 _mervyn 的回复:
首先这个函数只能挂勾GUI线程。 没有创建过窗口资源的线程是不能挂勾的。 获取进程的主线程id 这一做法欠妥,首先,一个进程的主线程 不一定创建窗口(虽然绝大多数进程的界面都是主线程在跑。。。)。另一个问题是,你调用SetWindowsHookEx的时机,你的目标线程是否一定创建了窗口? 比较健全的做法是,利用findwindow等找寻窗口的函数,先找到窗口。再利用GetWindowThreadProcessId函数的返回值得到目标线程。 另外,我不知道你是在什么时候,什么地方调用的SetWindowsHookEx , 你是要将钩子注入到其他进程。所以hook函数肯定是在你的dll中,一般SetWindowsHookEx的调用的相关代码也会在你的dll中。 所以我先根据你的现象,假设一下一种错误的做法,你可以对照下。 如果你调用SetWindowsHookEx的相关代码在dll的dllmian中,你自己的主程序exe只是简单加载了下你的dll,使其运行dllmian,从而开始调用SetWindowsHookEx,我假设你在这时调用成功了,且没有打印调用成功的日志。 这时目标进程开始加载你的dll,你的dll在目标进程的地址空间中开始调用dllmian,如果你没有做特殊的判断,还是一样的去运行SetWindowsHookEx,只不过这次线程id对应的线程就会是目标进程自己的了。而这种情况下,hmod参数必须为0,从而报了87错误。而你刚好在错误时才会输出日志。让你以为注入失败了。 如果真的是这样的话。。 我相信你应该知道该怎么改了。 dllmain中应该分情况处理。 或者,你的dll应该导出接口去实现SetWindowsHookEx,你的主程序exe去主动调用这个接口。
多谢回复。我一开始也是不理解,后面才明白过来你说的东西。后面直接改成窗口创建后再hook了。不过还是非常感谢,说到问题点子上了。
_mervyn 2020-05-20
  • 打赏
  • 举报
回复
首先这个函数只能挂勾GUI线程。 没有创建过窗口资源的线程是不能挂勾的。 获取进程的主线程id 这一做法欠妥,首先,一个进程的主线程 不一定创建窗口(虽然绝大多数进程的界面都是主线程在跑。。。)。另一个问题是,你调用SetWindowsHookEx的时机,你的目标线程是否一定创建了窗口? 比较健全的做法是,利用findwindow等找寻窗口的函数,先找到窗口。再利用GetWindowThreadProcessId函数的返回值得到目标线程。 另外,我不知道你是在什么时候,什么地方调用的SetWindowsHookEx , 你是要将钩子注入到其他进程。所以hook函数肯定是在你的dll中,一般SetWindowsHookEx的调用的相关代码也会在你的dll中。 所以我先根据你的现象,假设一下一种错误的做法,你可以对照下。 如果你调用SetWindowsHookEx的相关代码在dll的dllmian中,你自己的主程序exe只是简单加载了下你的dll,使其运行dllmian,从而开始调用SetWindowsHookEx,我假设你在这时调用成功了,且没有打印调用成功的日志。 这时目标进程开始加载你的dll,你的dll在目标进程的地址空间中开始调用dllmian,如果你没有做特殊的判断,还是一样的去运行SetWindowsHookEx,只不过这次线程id对应的线程就会是目标进程自己的了。而这种情况下,hmod参数必须为0,从而报了87错误。而你刚好在错误时才会输出日志。让你以为注入失败了。 如果真的是这样的话。。 我相信你应该知道该怎么改了。 dllmain中应该分情况处理。 或者,你的dll应该导出接口去实现SetWindowsHookEx,你的主程序exe去主动调用这个接口。

64,653

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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