讨论一个注入hook完成后的清理问题

rageliu 2016-09-26 10:11:24
问题描述:

采用全局钩子的方式将dll注入了目标进程,并成功hook了目标进程里的函数Fun。使其调用时会先进入我的函数Fun_My。这些都没有问题。但是在我要卸载钩子的时候,如果刚好代码执行在我的函数Fun_My的代码里。就会崩溃。因为我已经卸载了dll,也就是dll已经不在目标进程里了。这时候Fun_My也是无效的内容了,并不是以前的正确的代码段。所以目标进程就崩溃了。

这种情况下,在我的dll执行detach即将卸载的时候,如何确保代码并不在Fun_My里面执行呢。

当然我肯定是提前执行了对函数的unhook的,只是最后的一次hook到的函数,可能还在Fun_My里面执行,还没有执行完返回。这就出了问题。

大家有遇到过么,或是思考过这个问题,有啥好的处理方法啊,关于技术的意见建议讨论都欢迎。感谢。
...全文
957 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
rageliu 2016-09-27
  • 打赏
  • 举报
回复
引用 22 楼 schlafenhamster 的回复:
hook 能不能 使用 临界区 ?
可以使用。不过这个问题临界解不了。在另一贴子里也讨论过。 http://bbs.csdn.net/topics/392024311
schlafenhamster 2016-09-27
  • 打赏
  • 举报
回复
hook 能不能 使用 临界区 ?
许文君 2016-09-27
  • 打赏
  • 举报
回复
如果功能不复杂,试试shellcode能不能达到目的
rageliu 2016-09-27
  • 打赏
  • 举报
回复
引用 19 楼 xuddk727 的回复:
[quote=引用 18 楼 rageliu 的回复:] [quote=引用 17 楼 xuddk727 的回复:] 明白了,那就dll延迟并自卸载
目前就是这么做的,加载后不卸载。 一直觉得这个方式不够优雅,所以提出来和大家讨论讨论。 因为我调试过其他一些类似的程序,它们确实是卸载了的,而且不会有问题,最少我测试很长时间很多次,没出问题。 所以看看大家有没有处理这个问题的好建议。[/quote] 没什么优雅不优雅的,能解决问题就行,直接freelibrary肯定有隐患,必要时可能得手工清理现场,非是那些搞安全的估计都不清楚,平时工作中用不到也基本不会去试。 退一步说,卸不卸载与优雅没关系,COM的dll与你的有些类似,可不需要你去卸载。[/quote] 当然有关系,dll一直被占用,不能删除。而且既然dll在,何其关联的一切dll都会被加载,内存占用很大。全局监控,所有进程都会加载,也就是说,所有进程对内存的消耗都会增加。
许文君 2016-09-27
  • 打赏
  • 举报
回复
引用 18 楼 rageliu 的回复:
[quote=引用 17 楼 xuddk727 的回复:] 明白了,那就dll延迟并自卸载
目前就是这么做的,加载后不卸载。 一直觉得这个方式不够优雅,所以提出来和大家讨论讨论。 因为我调试过其他一些类似的程序,它们确实是卸载了的,而且不会有问题,最少我测试很长时间很多次,没出问题。 所以看看大家有没有处理这个问题的好建议。[/quote] 没什么优雅不优雅的,能解决问题就行,直接freelibrary肯定有隐患,必要时可能得手工清理现场,非是那些搞安全的估计都不清楚,平时工作中用不到也基本不会去试。 退一步说,卸不卸载与优雅没关系,COM的dll与你的有些类似,可不需要你去卸载。
赵4老师 2016-09-26
  • 打赏
  • 举报
回复
参考WinAPIOverride32源代码?
zgl7903 2016-09-26
  • 打赏
  • 举报
回复
把卸载部分也做一个导出接口, Hook 部分进入Hook函数的时候设置个标记, 退出时清除 DLL中卸载时先等待标记无效时再卸载
rageliu 2016-09-26
  • 打赏
  • 举报
回复
引用 1 楼 xuddk727 的回复:
如果是IAT/EAT HOOK,则先恢复导入/导出表,再行卸载。其他方式各有类似恢复手段。 再有一种则是将代码二进制,然后直接远程注入,这样无dll亦可。
多谢回答。和我的问题不太一致啊。如何unhook处理我知道。我意思是,代码正在执行Fun_My的时候。请注意这时候地址是在我的dll的空间里的,因为执行的是Fun_My我的hook函数,如果在Fun_My还没有执行完,还没返回的时候,我做了unhook操作,这时候就会卸载我的dll,可又正在执行dll里的Fun_My函数,执行的代码所在模块被卸载,肯定就崩溃了
许文君 2016-09-26
  • 打赏
  • 举报
回复
如果是IAT/EAT HOOK,则先恢复导入/导出表,再行卸载。其他方式各有类似恢复手段。 再有一种则是将代码二进制,然后直接远程注入,这样无dll亦可。
rageliu 2016-09-26
  • 打赏
  • 举报
回复
引用 17 楼 xuddk727 的回复:
明白了,那就dll延迟并自卸载
目前就是这么做的,加载后不卸载。 一直觉得这个方式不够优雅,所以提出来和大家讨论讨论。 因为我调试过其他一些类似的程序,它们确实是卸载了的,而且不会有问题,最少我测试很长时间很多次,没出问题。 所以看看大家有没有处理这个问题的好建议。
许文君 2016-09-26
  • 打赏
  • 举报
回复
明白了,那就dll延迟并自卸载
rageliu 2016-09-26
  • 打赏
  • 举报
回复
引用 15 楼 zgl7903 的回复:
如果你的DLL没有卸载的话(FreeLibrary) UnhookWindowsHookEx 应该不会导致程序奔溃, (可以测试下Hook中仅调用 CallNextHookEx 而不作其它任何事) UnHookSafe() { if(hhk) { UnhookWindowsHookEx(hhk); while(bHookDoing) sleep(0); hhk = NULL; } } 写日志
因为注入后hook了目标进程里的其他函数到我自己的函数,如果我的主进程关闭,就需要调用UnhookWindowsHookEx,这时候就导致目标进程里的dll被卸载,但是很可能正执行在我的hook函数里,,而这时我的dll却被卸载,所以崩溃。
zgl7903 2016-09-26
  • 打赏
  • 举报
回复
如果你的DLL没有卸载的话(FreeLibrary) UnhookWindowsHookEx 应该不会导致程序奔溃, (可以测试下Hook中仅调用 CallNextHookEx 而不作其它任何事) UnHookSafe() { if(hhk) { UnhookWindowsHookEx(hhk); while(bHookDoing) sleep(0); hhk = NULL; } } 写日志
rageliu 2016-09-26
  • 打赏
  • 举报
回复
引用 13 楼 Saleayas 的回复:
你的这个问题类似于 DLL 如何卸载自身的问题。 在你的函数需要卸载 DLL 的时候,在呼叫卸载函数的时候,压入返回地址,进入你卸载后需要执行的代码。 在你的卸载函数结束的时候,手动弹出返回堆栈,这样 ret 返回的时候,就可以进入你设定的代码了。
感谢回答,你说得是另一个问题了。目前我的问题是,已经卸载后,还有其他地方还在继续调用执行已经不存在的dll地址里的函数,所以崩溃。
Saleayas 2016-09-26
  • 打赏
  • 举报
回复
你的这个问题类似于 DLL 如何卸载自身的问题。 在你的函数需要卸载 DLL 的时候,在呼叫卸载函数的时候,压入返回地址,进入你卸载后需要执行的代码。 在你的卸载函数结束的时候,手动弹出返回堆栈,这样 ret 返回的时候,就可以进入你设定的代码了。
rageliu 2016-09-26
  • 打赏
  • 举报
回复
引用 11 楼 xuddk727 的回复:
你这里卸载dll是为了什么
因为我的监测程序关闭了啊。那我做的全局hook,肯定是要unhook的。注入的对应dll自然也会detach
许文君 2016-09-26
  • 打赏
  • 举报
回复
你这里卸载dll是为了什么
rageliu 2016-09-26
  • 打赏
  • 举报
回复
引用 9 楼 xuddk727 的回复:
这么看来你hook的函数要么是被频繁调用的,要么是处理耗时较长的,问题本质上就是多线程安全。可模拟COM那样加个引用计数,并在你的处理函数中内置标记unhook
多谢回复,我尝试过的也大概是这个思路。 但是这并不是理想的方式,比如极限的情况,刚进入函数,正处于压参的代码时,这时候还不到设置标记,但是却一定会进入函数。 或是在函数离开的时候,虽然已经恢复了标记,但是汇编代码还处于平栈的时候,一样会出问题。 当然上面说的都是特殊情况,但是代码就是这样,往往出问题的就是在一些特殊运行情况下。 另外这个和平时说的多线程安全还是有点不同,那个是对访问修改等做临界,说白了就是只允许串行进入,可先可后。但是这里是再也不进入。
许文君 2016-09-26
  • 打赏
  • 举报
回复
这么看来你hook的函数要么是被频繁调用的,要么是处理耗时较长的,问题本质上就是多线程安全。可模拟COM那样加个引用计数,并在你的处理函数中内置标记unhook
rageliu 2016-09-26
  • 打赏
  • 举报
回复
看了WinAPIOverride32源代码,主要是不同的hook方式的实现。针对unhook就是按常规做的,并没有特殊的处理。也就是说,它也存在这个问题。
加载更多回复(3)

15,472

社区成员

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

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