Hook方法的讨论
Android逆向-Hook方法的讨论
总结
Frida server
Frida gadget
xposed
定制ROM:脱壳机思路
系统so替换
这是早期的思路,通过对系统so进行静态注入,使得APP在启动时加载系统so,顺带的把我们自定义的so加载起来,因为这个自定义的so名称可以自定义,以及Android的碎片化,APP基本上不可能根据so的名称来对这种hook方式进行检测。
然而,想法很丰满,现实很骨感,实际测试下来发现,Android系统启动时,会先生成Zygote进程,在Zygote进程中加载所有必需的so,后续所有的APP进程都是Zygote fork出来的,因此,替换后的系统so的加载时机并不是在APP启动时
那么,能不能启动一个线程,不断循环检测要hook的APP是否被fork了呢?然而生活又给了我致使一击,Zygote在fork进程之前,会先等待进程中的所有子线程结束,以免某些子线程中的任务还没完成就进行了fork,导致功能异常。因此,如果启动一个线程,就会导致整个系统直接就起不来了(因为还有一些包括Launcher在内的系统APP需要通过Zygote fork出来)
有没有一个so,是在APP启动时进行加载的呢?通过对比Zygote进程和一个简单demo的maps列表,发现/system/lib/hw/gralloc.default.so这个so是在APP启动时加载的,经过一番百度,这个so应该是与APP图形界面渲染有关的so,而根据so的命名可以看出,这个so是有可能根据硬件的不同而变化的。而且经过测试,这个so是在Activity被启动时才加载的,因此,假如APP在Application中进行了一些操作,这种方案是监控不到的。Riru插件定制
其实Riru的整体思路和系统so替换的思路是很相似的,不过个人感觉系统so替换的思路要比Riru的思路实现起来更简单一些。
Riru相比于系统so替换的强大之处在于他对APP启动时会调用的函数进行了hook,并以插件的形式对外提供了接口,免去了自己再去研究源码,寻找hook点。
接下来编写了一个插件使用Frida Gadget进行尝试,然后再次发现悲催了,Frida Gadget的Listen模式中,需要PC端找到APP进程然后恢复程序运行,但是Riru提供的接口中,进程的相关环境还没有完全初始化好,使用PS命令查找不到进程
最后的最后,在Frida的JS API中找到了网络相关的API,因此采用了Frida Gadget的script的模式,然后在hook接口中实现了一个TCP服务器,将hook信息通过网络通信及adb转发发送到PC端。
整个流程为:- 编写Riru插件gadget_loader:功能为读取配置文件(放置在/data/local/tmp目录下),根据配置文件,若当前APP是需要检测的APP,则加载libgadget.so。
- 在插件中添加libgadget.so及其配置文件
- 安装gadget_loader插件。
- 将libloader.so的配置文件和libgadget.so需要执行的脚本放置到/data/local/tmp目录下
- libgadget.so脚本通过hook对应API监控APP接口调用行为,并通过网络连接将监控信息发送至PC
最后总结一下这个方案的几个特点:
- 不需要对APK进行修改,也不需要对进程进行注入,因此可以避开APP的检测机制
- 方案为了方便,最后采用了Riru插件进行实现,这使得APP有可能检测到存在Riru插件,如果碰到这种情况,完全可以采用系统so替换的方案,然后模仿Riru的思路hook几个API,实现Gadget so的加载,这样就基本上不可能被检测到了。
- 因为整个方案只是替换一个系统so,并添加了几个文件到系统中,实现了APK的零侵入,对系统的侵入也非常的小,兼容性会非常好(主要取决于Frida Gadget中是否有bug)
- 与PC端的交互采用的是socket通信,这个通信的接口是可自定义的,在保证了与PC端交互的同时又能避免固定端口被检测
- 整个方案的实现过程非常简单,低版本的系统上可以直接替换系统so,高版本的系统因为一些Android的安全机制,只能采用Magisk插件的形式进行so的替换,不过高版本系统上的root本来就几乎都是使用Magisk,这点小小的前置要求就也就几近于无了
研究点
- Riru插件编写
- 系统so替换
- 定制ROM
参考
[原创]分享一个基本不可能被检测到的hook方案-Android安全-看雪-安全社区|安全招聘|kanxue.com
- 本文作者: Taardis
- 本文链接: https://taardisaa.github.io/2023/10/10/Android逆向-Hook方法的讨论/
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!