说到Inline Hook、Got Hook,大家并不陌生,在Native层都可以改变函数的执行
返回值或修改传入参数的值。在网上github现有比较成熟的Hook框架中,
Got Hook的代表:XHook,Inline Hook:SandHook。
Got Hook就是在运行时修改got表的函数入口地址,这种Hook方案针对同一个
进程的so文件都需要修改它们的got表;Inline Hook就是在函数的前几个指令插入
跳转指令,使目标函数跳转到我们的函数执行逻辑里面来。
列举两张图,示例为Got Hook和Inline Hook的流程原理。
怎么去做检测呢?
看到网上检测方案,真的感觉就像过家家一样,小打小闹。比如检测有没有指定类,
xposed:de.robv.android.xposed.XposedHelpers。
比如腾讯很久以前的乐固就主动抛出Java异常,然后检测Stack异常信息里面有没有xposed
类的字符串。或者是检测Package Name,或者是检测App Name,检测有没有libxxx.so文件,
再就是检测命名空间是否为XXXXX,比如SandHook的namespace就是SandHook。
其实我想问一句,这些检测方法就是掩耳盗铃,自欺欺人。把这些Hook框架稍微改动一下再重新打包,
这些方法就瞬间失效,更可笑的是网上都是这种检测方法,真的是让人贻笑大方。
在这里,我想提出几种检测思路:
检测物理磁盘上的so文件与内存里的so文件的映射关系,比如.data、.text等等。
检测指定的函数的前几个指令是否为跳转指令,比如arm64的跳转指令是0x058000050。
检测系统lib库的so文件的指定函数地址与本进程so的导入函数地址是否相等。比如libc库
的open函数。这种方式需要先计算好got起始地址,导入表函数位置。
最后,针对SVC Hook的:
SVC Hook有ptrace、seccomp、内存扫描svc指令。
内存扫描指令这种肯定不会存在,因为这种效率太低了,需要起一个线程监控,而且稳定性也差。
目前就seccomp的bpf最常用,这种就是设定filter过滤器规则,拦截到指定的系统调用号后会产生
一个信号量,这种信号量是你设定的,然后就会执行事先使用sigaction注册的函数。
我们可以这样检测:注册一个sigaction处理逻辑,然后主动使用 sigqueue函数发送信号量,
再接收,如果没有接收到说明被seccomp的bpf规则拦截了,SVC已经被Hook了。
更多【对Inline Hook,Got Hook和SVC Hook一些检测的浅谈】相关视频教程:www.yxfzedu.com