Hook技术入门
1. 什么是Hook?
用自己的话说一下自己的理解(不一定对,等之后有了更深的理解之后再做更新)
Hook钩子,和动态插桩以及蹦床机制差不多,主要是为了能在执行目标函数或指令之前,拦截数据或者执行逻辑,先执行自己插入的一段代码,然后再执行原本的目标函数。完成这个任务的方法有很多,比如可以将要调用的函数地址替换为自己的函数地址,或者在指令流中插入跳转指令使执行逻辑跳转到自己插入的代码块上,等等。不过在修改了原本的数据或指令后,还需要还原以执行原本正常的功能,也就是说在hook时还需要保存原本的现场数据以及指令信息等。
实际上就是在原本的程序执行逻辑中,hook函数获得控制权,并执行我们自定义的功能,然后再将控制权返回原本的逻辑继续执行。形象化可以理解为一条直线在向前走,结果走到了岔路上,走了一会儿又回到了原本的直线方向继续向前。
2. Hook的应用场景。
Hook的应用非常广泛,不仅开发人员会用到,攻击者也会用到。
开发有:对程序的执行记录日志、防止应用重复启动等。
攻击有:使用hook拦截用户输入信息,获取键盘数据等。
3. Hook的技术方式或框架。
-
inline hook方式:目标函数执行指令中插入Jump跳转指令实现重定向
-
动态代理方式:思路应该是类似于设计模式中的代理模式,代理原本的函数的执行
-
Method Swizzle方式:动态改变SEL(方法编号)与IMP(方法实现)的对应关系
-
Cydia Substrate方式:适用于iOS和andriod,定义了一系列的函数和宏,底层调用了objc的runtime和fishHook来替代目标函数或者系统方法
-
fishHook方式:是Facebook提供一种动态修改链接Mach-O文件的工具。此利用Mach-O文件加载原理,通过修改非懒加载和懒加载两个表的指针达到C函数的Hook的目的
-
Xposed框架:目标函数为native,利用JNI hook重定向表中的函数指针
-
Legend框架:Android 免 Root 环境下的一个 Apk Hook 框架,该框架代码设计简洁,通用性高,适合逆向工程时一些 Hook 场景。大部分的功能都放到了 Java 层,兼容性非常好。原理是直接构造出新旧方法对应的虚拟机数据结构,然后替换信息写到内存中即可
4. Hook的一般步骤和技巧。
-
寻找 Hook 点。原则是尽可能是静态变量或者单例对象,因为它们容易定位,其次是尽量 Hook public 的对象和方法。
-
选择适当的hook方式或框架。
-
将hook代码注入到目标程序的运行内存中。
以上这个过程很类似于静态插桩,选择插桩点,准备要插桩的代码,然后将插桩点的代码以一定的方式写到插桩点位置,这样在执行时,执行到插桩点就可以运行我们插入的代码。Hook也是一样,当执行到Hook点时,会先执行钩子函数以及我们写入的函数逻辑,再执行正常逻辑。
5. 什么地方都可以Hook。
这里有一篇博客,在AddressHook、InlineHook、VEH_HOOK、SSDT_HOOK、IRP_Hook、Object Hook、sysenterHook这几个方面进行了举例说明。因为刚开始看还没有消化那么多的东西,所以这里先记录一下。
-
参考链接
-
C/C++ HOOK API(原理深入剖析之-LoadLibraryA)——inline hook方式
-
HOOK利用c++函数钩子——inline hook,不是完整的代码,但是逻辑很清晰
-
盘点Android常用Hook技术——总结了多种hook方式,包括主要原理和各个方式的优缺点
-
什么是 Hook (钩子) 线程以及应用场景——打印程序执行日志以及防止程序重复执行的应用
- Hook技术-简书——Andriod界面免注册跳转过程的hook,使用动态代理方式
-
带你了解Hook技术-华为云——动态代理方式,还有拦截通知栏、剪贴板的demo
- Hook原理,逆向开发-华为云——fishhook实例