HOOK API 在多线程时应该注意的问题点
在使用INLINE HOOK API实现对系统API的拦截时,正常情况下并没有太大问题,但一旦涉及到多线程,不管是修改IAT还是JMP,2种方法均会出现不可预料的问题,特别是在HOOK一些复杂的大型系统软件时,会被时不时的一个内存错误搞得心浮气躁。
HOOK API数量越多,需要注意的内容越多,最近实现HOOK FileSystem API,由于是Kernel32中的函数,所有涉及到文件(filename,filehandle)的API均要被HOOK,同时需要在HOOK中实现overlapped功能,而这个功能点相对比较复杂,连带涉及到完成端口、事件等函数的HOOK。
经过上百个版本的更新调试,目前初步稳定下来,下面列出需要注意的地方,主要是与FileSystem API相关的,其他API(如网络API、内存API等)可能不太适用:
1)从稳定性方面考虑,建议使用JMP方式实现HOOK API,修改IAT的方式不是不可以,而是太容易被其他程序修改而导致不稳定的问题了,大部分杀毒软件均会对IAT进行修改同时保护,所以这种方法要么容易报病毒,要么HOOK失败,同时系统也会对IAT进行修补,对于小型系统或者小量API可能不出现问题,但是对于FileSystem API,个人不推荐。
2)对Vista、WIN7以上的兼容:一开始在XP中进行HOOK时,一切正常,当切换到WIN7后,发现HOOK不起作用,这是由于VISTA、WIN7以上的APP在原来调用Kernel32.DLL的函数时,由于系统AppPatch的功能,已被自动重定向到KernelBase.dll中,而微软有很奇怪的做法,当然估计也是由于兼容性的考虑(即在EXE右键属性中选择兼容XP,VISTA运行时,AppPatch会自动选择重定向哪些API),某些API同时存在于Kernel32和KernelBase中,而不知道是不是重定向功能的不完善还是其他什么原因,同一个App中两个模块即使调用同一个API,也有可能分别跳转到Kernel32和KernelBase中,适用JMP的方式进行HOOK API时,由于通过GetProcAddress获取函数地址,所以均会被自动重定向到KernelBase中,因此需要自己实现一个GetProcAddress函数。
3)多线程同步问题:个人建议使用临界区RTL_CRITICAL_SECTION,不管是开发效率还是运行效率,临界区是首选,对于HOOK后的API中使用不同进程资源的情况,也是在使用临界区进行同步处理后,再去使用其他方法实现的。
4)多线程HOOK后经常卡死的问题,WINDOWS的FileSystem API存在嵌套调用的问题,如CopyFile内部会调用CreateFile等函数,Kernel32的CreateFile会调用KernelBase中的CreateFile,GetFileSize函数内部可能会调用GetFileSizeEx的函数等等,如果在这些函数中同时使用一个内核对象进行同步,必定导致卡死,因此需要考虑这些问题,比如在调用CopyFile时,需要和CreateFile使用不同的内核对象进行同步,而在Kernel32的CreateFile中,需要对KernelBase的CreateFile进行解除HOOK。
5)在HOOK和UNHOOK过程中,需要使用同一个内核对象对WriteProcessMemory进行同步保护,否则将导致进程中某些不可预料的地址内存数据损坏的问题(这个应该是WriteProcessMemory函数内部不支持多线程导致的)。
6)在使用RTL_CRITICAL_SECTION或其他同步函数中,锁的进入和离开函数,尽量使用inline,减少SP的跳转可增加速度,可大大增加多线程切换寄存器的稳定性;
题外话:从硬件上讲CPU只有一套寄存器,但是对于系统运行环境来说,每一个线程(甚至是纤程,即协程或微线程)都有一套虚拟寄存器,这样才能实现不同线程切换时还原所谓的“CPU运行现场”,而每一次SP的跳转从目前各种编译器技术上来讲均会进行所谓的“现场保护”,也就是push各种寄存器,inline函数就是为了减少这种操作的,在于内核打交道的过程中,有些操作是可能被中断的,减少“运行现场”的切换次数必定是大大增强稳定性!
HOOK API 在多线程时应该注意的问题点的更多相关文章
- 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥) 介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...
- [转]Delphi多线程编程入门(二)——通过调用API实现多线程
以下是一篇很值得看的关于Delphi多线程编程的文章,内容很全面,建议收藏. 一.入门 ㈠. function CreateThread( lpThreadAttributes: Pointer ...
- 汇编Ring 3下实现 HOOK API
[文章标题]汇编ring3下实现HOOK API [文章作者]nohacks(非安全,hacker0058) [作者主页]hacker0058.ys168.com [文章出处]看雪论坛(bbs.ped ...
- HOOK API(四)—— 进程防终止
HOOK API(四) —— 进程防终止 0x00 前言 这算是一个实战吧,做的一个应用需要实现进程的防终止保护,查了相关资料后决定用HOOK API的方式实现.起初学习HOOK API ...
- HOOK API(三)—— HOOK 所有程序的 MessageBox
HOOK API(三) —— HOOK 所有程序的 MessageBox 0x00 前言 本实例要实现HOOK MessageBox,包括MessageBoxA和MessageBoxW,其实现细节与H ...
- HOOK API(二)—— HOOK自己程序的 MessageBox
HOOK API(二) —— HOOK自己程序的 MessageBox 0x00 前言 以下将给出一个简单的例子,作为HOOK API的入门.这里是HOOK 自己程序的MessageBox,即将自己程 ...
- HOOK API (一)——HOOK基础+一个鼠标钩子实例
HOOK API (一)——HOOK基础+一个鼠标钩子实例 0x00 起因 最近在做毕业设计,有一个功能是需要实现对剪切板的监控和进程的防终止保护.原本想从内核层实现,但没有头绪.最后决定从调用层入手 ...
- 汇编 -- Hook API (MessageBoxW)
说到HOOK.我看了非常多的资料和教程.无奈就是学不会HOOK.不懂是我的理解能力差.还是你们说的 不够明确,直到我看了下面这篇文章,最终学会了HOOK: http://blog.sina.com.c ...
- HOOK API入门之Hook自己程序的MessageBoxW(简单入门)
说到HOOK,我看了很多的资料和教程,无奈就是学不会HOOK,不懂是我的理解能力差,还是你们说的 不够明白,直到我看了以下这篇文章,终于学会了HOOK: http://blog.sina.com.cn ...
随机推荐
- 用HTML代码加载Unity内容(unity频道:http://unity3d.9ria.com/)
Unity内容在浏览器通过Unity网络播放器插件加载.HTML代码与这个插件通常不直接通信,而是通过UnityObject的脚本帮助.其主要任务是Unity的内容嵌入一个非常简单的任务,通过从各种浏 ...
- C++容器类概述
原文转自:http://blog.csdn.net/wangxiaolong_china/article/details/8362540 什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器 ...
- Hdfs增量导入小文件合并的思路
1.使用mr进行合并 2.使用getmerge 将文件拉取到本地,再上传到hdfs,注意nl参数 3.使用appendToFile 4.使用hadoop提供的打包压缩技术 Usage: hadoop ...
- Cardinality Feedback
该特性主要针对 统计信息陈旧.无直方图或虽然有直方图但仍基数计算不准确的情况, Cardinality基数的计算直接影响到后续的JOIN COST等重要的成本计算评估,造成CBO选择不当的执行计划 O ...
- Ant not found - Make sure it's in the path or use --with-ant-home
# pacman -S apache-ant 参考:http://blog.csdn.net/linshutao/article/details/6638116
- 菜鸟-手把手教你把Acegi应用到实际项目中(11)-切换用户
在某些应用场合中,我们可能需要用到切换用户的功能,从而以另一用户的身份进行相关操作.这一点类似于在Linux系统中,用su命令切换到另一用户进行相关操作. 既然实际应用中有这种场合,那么我们 ...
- Missing artifact com.sun:tools:jar:1.5.0:system 补充
转自:http://blog.csdn.net/sweblish/article/details/6662586 解决方案一: 原来,是${java.home}在作怪,eclipse 没有使用 JAV ...
- sqlserver 批量删除存储过程和批量修改存储过程的语句
sqlserver 批量删除存储过程和批量修改存储过程的语句- sqlserver 批量删除存储过程和批量修改存储过程的语句,需要的朋友可以参考下. - 修改: 复制代码 代码如下: declare ...
- 利用sql批量删除表,存储过程
利用sql批量删除表,存储过程. 最近用godaddy的空间,由于系统里面的表多,一个个的删除很麻烦,就网上搜集了一下解决方法. 给大家分享一下: 1.批量删除存储过程 declare @procNa ...
- 关于NopCommerce3.6版的@Html.Widget(“home_page_top”)的说明
以首页幻灯片为例子,首页幻灯片是在插件Nop.Plugin.Widgets.NivoSlider里面实现的 首页视图位置 这里其实是加载插件里面的视图内容,具体实现在插件实现 这个是扩展方法,就是执行 ...