好久没写博客了, 一个月一篇还是要尽量保证,今天谈下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类,我们可以直接拿来用。
我曾经用API Hook来实现自动测试,见这里 API Hook在TA中的应用
对于基于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。
关于C++ 对象模型和虚表可以看我这篇 探索C++对象模型
对于COMHook,考虑下面2种case:
一种是我们Hook程序先运行,然后启动某个游戏程序(DirectX 9), 我们想Hook游戏的绘画内容。
这种方式下, 我们可以先Hook API Direct3DCreate9, 然后我们继承于IDirect3D9, 自己实现一个COM对象返回回去, 这样我们就可以拦截到所有对该对象的操作,为所欲为了, 当然我们自己现实的COM对象内部会调用真正的Direct3DCreate9,封装真正的IDirect3D9。
当然有时我们可能不用替代整个COM组件,我们只需要修改其中一个或几个COM函数, 这种情况下我们可以创建真正的IDirect3D9对象后直接修改它的虚表, 把其中某些函数改成我们自己的函数地址就可以了。
其实ATL就是用接口替代的方式来调试和记录COM接口引用计数的次数, 具体可以看我这篇 理解ATL中的一些汇编代码
还有一种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技术的一些简单总结的更多相关文章

  1. Hook技术

    hook钩子: 使用技术手段在运行时动态的将额外代码依附现进程,从而实现替换现有处理逻辑或插入额外功能的目的. 它的技术实现要点有两个: 1)如何注入代码(如何将额外代码依附于现有代码中). 2)如何 ...

  2. 程序破解之 API HOOK技术 z

    API HOOK,就是截获API调用的技术,在程序对一个API调用之前先执行你的函数,然后根据你的需要可以执行缺省的API调用或者进行其他处理,假设如果想截获一个进程对网络的访问,一般是几个socke ...

  3. API HOOK技术

    API HOOK技术是一种用于改变API执行结果的技术,Microsoft 自身也在Windows操作系统里面使用了这个技术,如Windows兼容模式等. API HOOK 技术并不是计算机病毒专有技 ...

  4. 【Hook技术】实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展

    [Hook技术]实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展 公司有个监控程序涉及到进程的保护问题,需要避免用户通过任务管理器结束掉监控进程,这里使用 ...

  5. 逆向实用干货分享,Hook技术第一讲,之Hook Windows API

    逆向实用干货分享,Hook技术第一讲,之Hook Windows API 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) ...

  6. 逆向实用干货分享,Hook技术第二讲,之虚表HOOK

    逆向实用干货分享,Hook技术第二讲,之虚表HOOK 正好昨天讲到认识C++中虚表指针,以及虚表位置在反汇编中的表达方式,这里就说一下我们的新技术,虚表HOOK 昨天的博客链接: http://www ...

  7. x64内核HOOK技术之拦截进程.拦截线程.拦截模块

    x64内核HOOK技术之拦截进程.拦截线程.拦截模块 一丶为什么讲解HOOK技术. 在32系统下, 例如我们要HOOK SSDT表,那么直接讲CR0的内存保护属性去掉. 直接讲表的地址修改即可. 但是 ...

  8. Windows Hook技术

    0x01 简介 有人称它为“钩子”,有人称它为“挂钩”技术.谈到钩子,很容易让人联想到在钓东西,比如鱼钩就用于钓鱼.编程技术的钩子也是在等待捕获系统中的某个消息或者动作.钩子的应用范围非常广泛,比如输 ...

  9. Android Native Hook技术(二)

    Hook技术应用 已经介绍了安卓 Native hook 原理,这里介绍 hook 技术的应用,及 Cyida Substrate 框架. 分析某APP,发现其POST请求数据经过加密,我们希望还原其 ...

随机推荐

  1. xenomai for at91

    http://www.at91.com/linux4sam/bin/view/Linux4SAM/RealTime#Xenomai

  2. php-4种排序

    <?php$arr = array(1, 43, 54, 62, 21, 66, 32, 78, 36, 76, 39); //1. 冒泡排序 //在要排序的一组数中,对当前还未排好的序列,从前 ...

  3. iOS多线程 NSOperation的用法

    上一篇写了 GCD 的使用,接下来就了解一下 NSOperation ,NSOperation是苹果对 GCD 的 OC 版的一个封装,但是相对于GCD来说可控性更强,并且可以加入操作依赖. NSOp ...

  4. HTML5调用手机相机拍照

    前端调用手机相机拍照 实现方式常见有两种: 一种是通过video控件,通过捕获video的流,截取video中的图像实现拍照, 还有一种是通过input[file]控件调用移动端的摄像头,实现拍照. ...

  5. (转)详解Linux Top 命令

    top 命令是最流行的性能监视工具之一,我们必需了解.它是一个优秀的交互式工具,用于监视性能.它提供系统整体性能,但报告进程信息才是 top 命令的长处.top 命令交互界面如下图所视:

  6. Mini projects #4 ---- Pong

    课程全名:An Introduction to Interactive Programming in Python,来自 Rice University 授课教授:Joe Warren, Scott ...

  7. mysql 函数(一)

    1.ascii() 查询ascii值,多个字符的情况下,显示左边第一个字符的ascii值 SELECT ASCII("abc"); 等同于 SELECT ASCII("a ...

  8. 关于MFC文本框输入内容的获取 与 设置文本框的内容

    八月要开始做界面了<( ̄︶ ̄)/,然而目前只会用MFC╮(╯▽╰)╭ 好吧,言归正传,设置好文本框后,要获取用户输入的内容,可以用: GetDlgItemText() ; 这个函数有两个参数,第 ...

  9. Bootstrap库之Modals

    Bootstrap库之Modals. Bootstrap是Twitter推出的一个开发工具包,包含了一些比较常用的CSS,JavaScript代码.使用Bootstrap可以加快前端开发的速度.本站( ...

  10. tar.xz文件解压

    原文:http://blog.csdn.net/rheostat/article/details/7614451 感谢CSDN的<帝都码农> ======================= ...