好久没写博客了, 一个月一篇还是要尽量保证,今天谈下Hook技术。
在Window平台上开发任何稍微底层一点的东西,基本上都是Hook满天飞, 普通应用程序如此,安全软件更是如此, 这里简单记录一些常用的Hook技术。
基本上做Windows开发都知道这个API, 它给我们提供了一个拦截系统事件和消息的机会, 并且它可以将我们的DLL注入到其他进程。
但是随着64位时代的到来和Vista之后的UAC机制开启,这个API很多时候不能正常工作了:
首先,32位DLL没法直接注入到64位的应用程序里面, 因为他们的地址空间完全不一样的。当然尽管没法直接注入,但是在权限范围内,系统会尽量以消息的方式让你能收到64位程序的消息事件。
其次,UAC打开的情况下低权限程序没法Hook高权限程序, 实际上低权限程序以高权限程序窗口为Owner创建窗口也会失败, 低权限程序在高权限程序窗口上模拟鼠标键盘也会失败。
有人说我们可以关闭UAC, Win7下你确实可以,但是Win8下微软已经不支持真正关闭UAC, 从这里我们也可以看到微软技术过渡的方式, 中间会提供一个选项来让你慢慢适应,最后再把这个选项关掉, UAC和Aero模式都是如此。
那么我们如何解决这些问题?
对于64位问题 , 解决方法是提供2个DLL,分别可以Hook32和64位程序。
对于权限问题, 解决方法是提升权限, 通过注册系统服务, 由服务程序创建我们的工作进程。这里为什么要创建一个其他进程而不直接在服务进程里干活? 因为Vista后我们有了Session隔离机制,服务程序运行在Session 0,我们的其他程序运行在Session 1, Session 2等, 如果我们直接在服务程序里干活,我们就只能在Session 0里工作。通过创建进程,我们可以在
DuplicateTokenEx后将Token的SessionID设置成目标Session,并且在
CreateProcessAsUser时指定目标WinStation和Desktop, 这样我们就既获得了System权限,并且也可以和当前桌面进程交互了。
很多人可能都不知道这个API, 但是这个API其实挺重要的, 看名字就知道它是Hook事件(Event)的, 具体哪些事件可以看
这里.
为什么说这个API重要, 因为这个API大部分时候没有SetWindowsHookEx的权限问题, 也就是说这个API可以让你Hook到高权限程序的事件, 它同时支持进程内(WINEVENT_INCONTEXT)和进程外(WINEVENT_OUTOFCONTEXT)2种Hook方式, 你可以以进程外的方式Hook到64位程序的事件。
为什么这个API没有权限问题, 因为它是给Accessibility用的, 也就是它是给自动测试和残障工具用的, 所以它要保证有效。
我曾经看到这样一个程序,当任何程序(无论权限高低)有窗口拖动(拖标题栏改变位置或是拖边框改变大小), 程序都能捕获到, 当时很好奇它是怎么做到的?
Spy了下窗口消息, 知道有这样2个消息:WM_ENTERSIZEMOVE和WM_EXITSIZEMOVE表示进入和退出这个事件, 但是那也只能获得自己的消息,其他程序的消息它是如何捕获到的?当时怀疑用的是Hook, 却发现没有DLL注入。查遍了Windows API 也没有发现有API可以查询一个窗口是否在这个拖动状态。最后发现用的是SetWinEventHook的EVENT_SYSTEM_MOVESIZESTART和EVENT_SYSTEM_MOVESIZEEND。
API Hook
常见的API Hook包括2种, 一种是基于PE文件的导入表(IAT), 还有一种是修改前5个字节直接JMP的inline Hook.
对于基于IAT的方式, 原理是PE文件里有个导入表, 代表该模块调用了哪些外部API,模块被加载到内存后, PE加载器会修改该表,地址改成外部API重定位后的真实地址, 我们只要直接把里面的地址改成我们新函数的地址, 就可以完成对相应API的Hook。《Windows核心编程》里第22章有个封装挺好的CAPIHook类,我们可以直接拿来用。
对于基于Jmp方式的inline hook, 原理是修改目标函数的前5个字节, 直接Jmp到我们的新函数。虽然原理挺简单, 但是因为用到了平台相关的汇编代码, 一般人很难写稳定。真正在项目中用还是要求稳定, 所以我们一般用微软封装好的
Detours, 对于Detours的原理,这里有篇不错的文章
微软研究院Detour开发包之API拦截技术。
比较一下2种方式:
IAT的方式比较安全简单, 但是只适用于Hook导入函数方式的API。
Inline Hook相对来说复杂点, 但是它能Hook到任何函数(API和内部函数),但是它要求目标函数大于5字节, 同时把握好修改时机或是Freeze其他线程, 因为多线程中改写可能会引起冲突。
COM Hook
Window上因为有很多开发包是以COM方式提供的(比如DirectX), 所以我们就有了拦截COM调用的COM Hook。
因为COM里面很关键的是它的接口是C++里虚表的形式提供的, 所以COM的Hook很多是时候其实就是虚表(vtable)的Hook。
对于COMHook,考虑下面2种case:
一种是我们Hook程序先运行,然后启动某个游戏程序(DirectX 9), 我们想Hook游戏的绘画内容。
这种方式下, 我们可以先Hook API Direct3DCreate9, 然后我们继承于IDirect3D9, 自己实现一个COM对象返回回去, 这样我们就可以拦截到所有对该对象的操作,为所欲为了, 当然我们自己现实的COM对象内部会调用真正的Direct3DCreate9,封装真正的IDirect3D9。
当然有时我们可能不用替代整个COM组件,我们只需要修改其中一个或几个COM函数, 这种情况下我们可以创建真正的IDirect3D9对象后直接修改它的虚表, 把其中某些函数改成我们自己的函数地址就可以了。
还有一种case是游戏程序已经在运行了, 然后才启动我们的Hook进程, 我们怎么样才能Hook到里面的内容?
这种情况下我们首先要对程序内存有比较详细的认识, 才能思考创建出来的D3D对象的虚表位置, 从而进行Hook, 关于程序内存布局,可见我这篇
理解程序内存。
理论上说COM对象如果是以C++接口的方式实现, 虚表会位于PE文件的只读数据节(.rdata), 并且所有该类型的对象都共享该虚表, 所以我们只要创建一个该类型对象,我们就可以获得其他人创建的该类型对象的虚表位置,我们就可以改写该虚表实现Hook(实际操作时需要通过VirtualProtect修改页面的只读属性才能写入)。
但是实际上COM的虚表只是一块内存, 它并不一定是以C++实现, 所以它可以存在于任何内存的任何地方。另外对象的虚表也不一定是所有同类型的对象共享同一虚表, 我们完全可以每个对象都有自己的一份虚表。比如我发现IDirect3D9是大家共享同一虚表的(存在D3D9.dll的), 但是IDirect3DDevice9就是每个对象都有自己的虚表了(存在于堆heap)。所以如果你要Hook IDirect3DDevice9接口,通过修改虚表实际上没法实现。
但是尽管有时每个对象的虚表不一样,同类型对象虚表里的函数地址却都是一样的, 所以这种情况下我们可以通过inline Hook直接修改函数代码。当然有些情况下如果是静态链接库,即使函数代码也是每个模块都有自己的一份, 这种情况下就只能反汇编获取虚表和函数的地址了。
最后,总结一下, 上面主要探讨了Windows上的各种Hook技术,通过将这些Hook技术组起来, 可以实现很多意想不到的功能, 比如我们完全可以通过Hook D3D实现Win7任务栏那种Thumbnail预览的效果(当然该效果可以直接由DWM API实现, 但是如果我们可以通过HOOK已动画的方式实现是不是更有趣 )。
- Hook技术
hook钩子: 使用技术手段在运行时动态的将额外代码依附现进程,从而实现替换现有处理逻辑或插入额外功能的目的. 它的技术实现要点有两个: 1)如何注入代码(如何将额外代码依附于现有代码中). 2)如何 ...
- 程序破解之 API HOOK技术 z
API HOOK,就是截获API调用的技术,在程序对一个API调用之前先执行你的函数,然后根据你的需要可以执行缺省的API调用或者进行其他处理,假设如果想截获一个进程对网络的访问,一般是几个socke ...
- API HOOK技术
API HOOK技术是一种用于改变API执行结果的技术,Microsoft 自身也在Windows操作系统里面使用了这个技术,如Windows兼容模式等. API HOOK 技术并不是计算机病毒专有技 ...
- 【Hook技术】实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展
[Hook技术]实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展 公司有个监控程序涉及到进程的保护问题,需要避免用户通过任务管理器结束掉监控进程,这里使用 ...
- 逆向实用干货分享,Hook技术第一讲,之Hook Windows API
逆向实用干货分享,Hook技术第一讲,之Hook Windows API 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) ...
- 逆向实用干货分享,Hook技术第二讲,之虚表HOOK
逆向实用干货分享,Hook技术第二讲,之虚表HOOK 正好昨天讲到认识C++中虚表指针,以及虚表位置在反汇编中的表达方式,这里就说一下我们的新技术,虚表HOOK 昨天的博客链接: http://www ...
- x64内核HOOK技术之拦截进程.拦截线程.拦截模块
x64内核HOOK技术之拦截进程.拦截线程.拦截模块 一丶为什么讲解HOOK技术. 在32系统下, 例如我们要HOOK SSDT表,那么直接讲CR0的内存保护属性去掉. 直接讲表的地址修改即可. 但是 ...
- Windows Hook技术
0x01 简介 有人称它为“钩子”,有人称它为“挂钩”技术.谈到钩子,很容易让人联想到在钓东西,比如鱼钩就用于钓鱼.编程技术的钩子也是在等待捕获系统中的某个消息或者动作.钩子的应用范围非常广泛,比如输 ...
- Android Native Hook技术(二)
Hook技术应用 已经介绍了安卓 Native hook 原理,这里介绍 hook 技术的应用,及 Cyida Substrate 框架. 分析某APP,发现其POST请求数据经过加密,我们希望还原其 ...
随机推荐
- asp.net C# cookies 的使用方法
Response.Cookie("username").value="aa" 写入username=Request.Cookies("username ...
- 删除从第i个位置开始,长度为len的子串
/*字符串采用带头结点的链表存储,设计算法函数void delstring(linkstring s, int i,int len)在字符串s中删除从第i个位置开始,长度为len的子串.*//**** ...
- group_concat函数详解
来自: http://hchmsguo.iteye.com/blog/555543 MySQL中group_concat函数 完整的语法如下: group_concat([DISTINCT] 要连接的 ...
- 区间型DP
区间型DP是一类经典的动态规划问题,主要特征是可以先将大区间拆分成小区间求解最后由小区间的解得到大区间的解. 有三道例题 一.石子合并 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆. ...
- Only女装首页HTML+CSS代码实现
这是效果图,因为太长,缩略了. 在学习HTML和CSS基础的时候做的.自己切图下来做的. 没有什么技术含量. 源代码和图片我放在github上了, 上个链接吧: https://github.com/ ...
- 绿色ip扫描工具
ip扫描,可以扫描一下自己的局域网有多少设备在线,有没有在蹭网.优点在于:短小精悍,快速,不用安装. 其实,我自己也写过一个但是没有这个精致,感兴趣的可以一起讨论. 下载地址:32位 64位 我的淘宝 ...
- websocket---Html5
使用websocket主要是处理,通过服务器向页面发送消息,进行页面操作的处理. 以前类似情况,由于程序立即相应,处理事件较短,所遇采用过ajax进行轮询, 但是由于本次,需要人工干预,所以采用web ...
- C++的一个奇技淫巧
C++如何写一个函数,得到一个数组的长度呢? size_t GetArrayLength(int Array []) { return sizeof(Array)/sizeof(Array[0]); ...
- 带回调函数的js运动框架
function startMove(obj, json, endFun) { //开始前关闭之前obj上的定时器 clearInterval(obj.timer); //定时器 obj.timer ...
- RHEL6.5 删除桌面启动器(计算机/Home/回收站)
首先,安装gconf-editor以获得gconftool-2命令 终端命令: gconftool-2 --set /apps/nautilus/desktop/computer_icon_visib ...