从0到1:CTFer成长之路
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

4.2 APK逆向工具

本节主要介绍在APK逆向时主要使用的一些逆向工具和模块,好工具能大大加快逆向的速度。针对Android平台的逆向工具有很多,如Apktool、JEB、IDA、AndroidKiller、Dex2Jar、JD-GUI、smali、baksmali、jadx等,本节主要介绍JEB、IDA、Xposed和Frida。

4.2.1 JEB

针对Android平台有许多反编译器,其中JEB的功能最强大。JEB从早期的Android APK反编译器发展到现在,不仅支持Android APK文件反编译,还支持MIPS、ARM、ARM64、x86、x86-64、WebAssembly、EVM等反编译,展示页面和开放接口易用,大大降低了逆向工程的难度,见图4-2-1。

图4-2-1

JEB 2.0后增加了动态调试功能,动态调试功能简单易用,容易上手,可以调试任意开启调试模式的APK。

附加调试时,进程标记为D,表示该进程可以被调试,否则说明该进程没有打开调试开关,无法调试,见图4-2-2。

图4-2-2

打开调试功能后,OSX系统通过Command+B在smali层面上布置断点,右侧VM/局部变量窗口下查看当前位置各寄存器的值,双击能修改任意寄存器值,见图4-2-3。

图4-2-3

没有开启调试功能的应用、非Eng版本的Android手机被root后,可能出现无法调试其他应用的情况,这时可以通过Hook系统接口强制开启调试模式来进行,如通过Xposed Hook实现非Eng手机下的JEB动态调试。Hook动态修改debug状态的代码如下:

强制将PackageManagerService的getPackageInfo函数中应用程序调试Flag改为调试状态,即可强制打开调试模式,在任意root设备中完成动态调试。

4.2.2 lDA

在遇到Native(本地服务)逆向时,IDA优于JEB等其他逆向工具,其动态调试能大大加速Android Native层逆向速度,本节主要介绍如何使用IDA进行Android so Native层逆向。

IDA进行Android Native层调试需要用到IDA自带工具android_server:对于32位Android手机,使用32位版android_server和32位版IDA;对于64位Android手机,使用64位版android_server和64位版IDA,将android_server存至手机目录,且修改权限,见图4-2-4。

图4-2-4

IDA调试默认监听23946端口,需要使用adb forward指令将Android端口命令转发至本机:

打开IDA远程ARM/Android调试器,见图4-2-5。

Hostname选择默认的127.0.0.1或本机IP地址,Port选择默认的23946,见图4-2-6。再选择需要调试的应用,见图4-2-7。

图4-2-5

图4-2-6

进入IDA主页面后选择modules,找到该进程对应的native层so,见图4-2-8。

双击进入该so对应的导出表,找到需要调试的Native函数(见图4-2-9),然后双击进入函数页面,在主页面下断点、观察寄存器变化(见图4-2-10)。

某些Native函数(JNI_OnLoad、init_array)在so加载时会默认自动执行,对于这类函数无法直接使用上述方式进行调试,需要在动态库加载前断下,所有动态库都是通过linker加载,所以需要定位到linker中加载so的起始位置,然后在linker初始化该so时进入。

4.2.3 Xposed Hook

Xposed是一款在root设备下可以在不修改源码的情况下影响程序运行的Android Hook框架,其原理是将手机的孵化器zygote进程替换为Xposed自带的zygote,使其在启动过程中加载XposedBridge.jar,模块开发者可以通过JAR提供的API来实现对所有Function的劫持,在原Function执行的前后加上自定义代码。Xposed Hook的步骤如下。

<1>在AndroidManifest.xml中的application标签内添加Xposed相关的meta-data:

图4-2-7

图4-2-8

图4-2-9

图4-2-10

其中,xposedmodule表示这是一个Xposed模块,xposeddescription描述该模块的用途,可以引用string.xml中的字符串,xposedminversion是要求支持的Xposed Framework最低版本。

<2>导入XposedBridgeApi jar包。在Android studio中修改app/build.gradle,添加如下内容:

sync后,即可完成导入。

<3>编写Hook代码:

<4>声明Xposed入口。新建assets文件夹,并创建xposed_init文件,从中填写Xposed模块入口类名,如上述代码对应的类名为com.test.ctf.CTFDemo。

<5>激活Xposed模块。在Xposed应用中激活模块并且重启,即可观察Hook后的效果。

4.2.4 Frida Hook

Frida是一款跨平台的Hook框架,支持iOS、Android。对于Android应用,Frida不仅能Hook Java层函数,还能Hook Native函数,能大大提高逆向分析的速度。Frida的安装过程见官方文档,不再赘述,下面主要介绍Frida使用的技巧。

Hook Android Native函数:

Hook Android Java函数:

通过__fields__获取类成员变量:

Native层下获取Android jni env:

Java层获取类的field字段:

获取Native特定地址:

获取app context:

Frida需要在root环境下使用,但是提供了一种不需root环境的代码注入方式,通过反编译,在被测应用中注入代码,使其在初始化时加载Frida Gadget相关so,并且在lib目录下存放配置文件libgadget.config.so,说明动态注入的JS代码路径。重打包应用后,即可实现不需root的Frida Hook功能。