IDA动态调试动态注册native函数流程

安卓/手游逆向交流群963612891
IDA动态调试动态注册native函数流程1.编写目的
记录IDA动态调试步骤
2使用工具
逆向工具: IDA 7.0 , Jadx

运行环境:Nexus 5 (Android 4.4)
3.原字符串信息
IDA动态调试动态注册native函数流程
4.实现流程4.1 使用adb命令定位字符串位置
1.手机打开字符串所在界面
2.手机连接电脑
3.在cmd中输入”adb shell dumpsys activity top”查看当前顶层界面所在app的工程位置

结果:
目标所在位置 : ”com.glj.dynamicregistration/.MainActivity”
IDA动态调试动态注册native函数流程

4.2 使用Jadx对APP进行逆向分析
Jadx工具分析完后打开包名”com.glj.dynamicregistration”下的”MainActivity”
IDA动态调试动态注册native函数流程

4.3 定位字符串显示位置
1.在onCreate中只有一个TextView从getText()函数中获取字符串,再看getText()函数是经过native修饰的.那么可以肯定这是一个jni函数.再看Activity中确实加载了一个”hellojni”的so库,那么我们基本上定义这是从so库中获取的字符内容.
IDA动态调试动态注册native函数流程
4.4 获取so库
将app的apk格式改为zip压缩包格式后打开,在lib目录下进行扣取
IDA动态调试动态注册native函数流程
4.4 IDA加载so库静态分析
(1)将so文件直接拖拽进入IDA加载后点击Exports窗口是否存在java开头的函数,看下图,发现并没有.那么下一步只能去分析JNI_OnLoad函数了.

IDA动态调试动态注册native函数流程
4.5 静态分析JNI_OnLoad
(1) 将JNI_OnLoad函数的形参识别为”JavaVM*”类型
(2) 从13行中可以看到sub_F70函数,那么我们继续跟进去.
IDA动态调试动态注册native函数流程
(3) 在sub_F70中可以看见直接返回了sub_FA4函数的返回值.那么我们继续跟进去看.
IDA动态调试动态注册native函数流程

(4)在sub_FA4函数终于看到了我们的RegisterNatives函数了,那么可以继续跟进去查看一番
IDA动态调试动态注册native函数流程
(5)很抱歉,不能继续再跟了,那么将sub_FA4函数的代码同步到汇编里面.
IDA动态调试动态注册native函数流程
IDA动态调试动态注册native函数流程

4.5动态JNI_OnLoad函数4.5.1 启动android-server
IDA动态调试动态注册native函数流程
4.5.2 端口转发
IDA动态调试动态注册native函数流程

4.5.3 使用am命令启动app
注:命令格式为:am start -D -n 包名/.入口
IDA动态调试动态注册native函数流程

使用Android Device Monitor工具查看当前APP的端口
IDA动态调试动态注册native函数流程

4.5.4 打开IDA工具附加进程
IDA动态调试动态注册native函数流程
选择”Debugger”->”Attach”->”Remote ARMLinux/Android debugger”进行打开附加窗口,并点击”Debug options”勾选三项

IDA动态调试动态注册native函数流程
IDA动态调试动态注册native函数流程

在附加进程窗口搜索关键字并双击调试的进行加载.
IDA动态调试动态注册native函数流程

进程附加完毕
IDA动态调试动态注册native函数流程
4.5.5 定位JNI_OnLoad函数
(1)此时继续勾选三项”Debugger”->”Debugger options”
IDA动态调试动态注册native函数流程
IDA动态调试动态注册native函数流程

(2) 使用jdb命令开始调试
IDA动态调试动态注册native函数流程
(3) 在IDA中按F9直至”libhellojni.so”加载为止.通过IDA的Output window窗口可以查看
IDA动态调试动态注册native函数流程

(4) 此时在IDA的Debugger中打开Module list.并在其中使用Ctrl+F搜索hellojni.待结果处双击进入.进入后继续找到JNI_OnLoad函数继续双击进入.具体打开方式”Debugger”->”Debugger windows”->”Module list”
IDA动态调试动态注册native函数流程
IDA动态调试动态注册native函数流程
IDA动态调试动态注册native函数流程
4.5.6调试JNI_OnLoad函数
(1)在JNI_OnLoad函数中下断点后一路F9,直至进入到断点为止.
IDA动态调试动态注册native函数流程

4.5.7根据基址+偏移的方式算出RegisterNatives的位置.
基址:加载so库的初始地址.的当前地址:0x754BF000
IDA动态调试动态注册native函数流程
偏移地址:静态分析时RegisterNatives所在的位置:0xFEA
IDA动态调试动态注册native函数流程
绝对地址 = (754BF000+FEA)=0x754BFFEA

在IDA中使用G键进行跳转地址到:0x754BFFEA后下断点.并F9跳转到该位置.
IDA动态调试动态注册native函数流程
IDA动态调试动态注册native函数流程

4.5.8 对sub_754BFFEA函数进行单步调试
通过JNI的知识可以推出R2存放的就是Native方法列表,那么进入R2寄存器查看里面的数据进行验证一下.
IDA动态调试动态注册native函数流程

方法表对应的是java方法名,签名数据,C函数代码具体实现位置这三步.那么继续验证754C19D8, 754C19E0和754BFEA9地址中存放的值

IDA动态调试动态注册native函数流程
IDA动态调试动态注册native函数流程
IDA动态调试动态注册native函数流程
IDA动态调试动态注册native函数流程

其中看到jni_getText函数是不是一脸懵逼…其实这里只需要C或者P一下即可还原为汇编指令代码.
IDA动态调试动态注册native函数流程
IDA动态调试动态注册native函数流程

那么我们进入R1寄存器中查看数据进行验证一下吧.

IDA动态调试动态注册native函数流程

5总结
要分析一个APP里面的native方法最有效的方法就是先静态分析一波,找到相关信息.然后在动态调试时使用基址加偏移的方式去定位函数.这样会很有效率,其次就是对JNI需要一定的了解,因为动态注册的JNI函数都是在JNI_OnLoad中进行加载的,所以在静态分析是定位到RegisterNatives函数,然后需要关注的是R0=JNIEnv* , R1=obj, R2=注册方法列表, R3=方法个数.其中方法表里的格式为Java方法名,签名信息,C函数代码实现地址.经过这一波分析,可以清楚地在JNI_OnLoad中找到相应的C函数体有一定的认知了.