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 ...
随机推荐
- 无法加载程序集,因为该程序集包含EdmSchemaAttribute,并按名称加载结束类型。不允许同时按名称和特性进行加载
小小记录下,今天写程序时遇到的一个bug,相信大家用MVC+EF写项目时遇到的概率是挺大的.昨天本人也遇到了,很悲剧,暂时没想到好的办法解决,跟项目经理交流了下,这个问题认为出现在EF的自身设计上,它 ...
- struts2常用的常量constant
常用的常量配置 struts.serve.static.browserCache 该属性设置浏览器是否缓存静态内容.当应用处于开发阶段时,我们希望每次请求都获得服务器的最新响应,则可设置该属性为fa ...
- 对.Net系统架构改造的一点经验和教训
如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 在互联网行业,基于Unix/Linux的网站系统架构毫无疑问是当今主流的架构解决方案 ...
- xml中俩种解析方式
两种解析方式 1.from xml.etree import ElementTree as ET 利用ElementTree模块下的xml方法可以把一个字符串类型的东西转换成Element类,从而利用 ...
- Swift学习(二)
一.方法 在OC中,函数是C语言的形式,跟方法不一样 函数:int sum (int num1, int num2) { return num1 + num2; } 方法:- (int)sum:( ...
- 学习练习 java练习小题题目:判断一个整数能被几个9整除
题目:判断一个整数能被几个9整除 package com.hanqi.lianxi; import java.io.*; public class Test1 { //判断能否被9整除 static ...
- noip2007 树网的核
P1099 树网的核 112通过 221提交 题目提供者该用户不存在 标签动态规划树形结构2007NOIp提高组 难度提高+/省选- 提交该题 讨论 题解 记录 题目描述 设T=(V, E, W) ...
- No.007 Reverse Integer
7. Reverse Integer Total Accepted: 153147 Total Submissions: 644103 Difficulty: Easy Reverse digits ...
- SSH环境搭建步骤解析
一.建立Java web project:AngelSSH 二.引入jar包,必要清单如下 2.1,Struts2 commons-fileupload 文件上传组件 commons-io io ...
- 在C++中调用DLL中的函数 (3)
1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...