IDA动态调试动态注册native函数流程1.编写目的
记录IDA动态调试步骤
2使用工具
逆向工具: IDA 7.0 , Jadx
运行环境:Nexus 5 (Android 4.4)
3.原字符串信息
4.实现流程4.1使用adb命令定位字符串位置
1.手机打开字符串所在界面
2.手机连接电脑
3.在cmd中输入”adb shell dumpsys activity top”查看当前顶层界面所在app的工程位置
结果:
目标所在位置 : ”com.glj.dynamicregistration/.MainActivity”
4.2使用Jadx对APP进行逆向分析
Jadx工具分析完后打开包名”com.glj.dynamicregistration”下的”MainActivity”
4.3定位字符串显示位置
1.在onCreate中只有一个TextView从getText()函数中获取字符串,再看getText()函数是经过native修饰的.那么可以肯定这是一个jni函数.再看Activity中确实加载了一个”hellojni”的so库,那么我们基本上定义这是从so库中获取的字符内容.
4.4获取so库
将app的apk格式改为zip压缩包格式后打开,在lib目录下进行扣取
4.4 IDA加载so库静态分析
(1)将so文件直接拖拽进入IDA加载后点击Exports窗口是否存在java开头的函数,看下图,发现并没有.那么下一步只能去分析JNI_OnLoad函数了.
4.5 静态分析JNI_OnLoad
(1)将JNI_OnLoad函数的形参识别为”JavaVM*”类型
(2)从13行中可以看到sub_F70函数,那么我们继续跟进去.
(3)在sub_F70中可以看见直接返回了sub_FA4函数的返回值.那么我们继续跟进去看.
(4)在sub_FA4函数终于看到了我们的RegisterNatives函数了,那么可以继续跟进去查看一番
(5)很抱歉,不能继续再跟了,那么将sub_FA4函数的代码同步到汇编里面.
4.5动态JNI_OnLoad函数4.5.1启动android-server
4.5.2端口转发
4.5.3使用am命令启动app
注:命令格式为:am start -D -n 包名/.入口
使用Android Device Monitor工具查看当前APP的端口
4.5.4打开IDA工具附加进程
选择”Debugger”->”Attach”->”Remote ARMLinux/Android debugger”进行打开附加窗口,并点击”Debug options”勾选三项
在附加进程窗口搜索关键字并双击调试的进行加载.
进程附加完毕
4.5.5定位JNI_OnLoad函数
(1)此时继续勾选三项”Debugger”->”Debugger options”
(2) 使用jdb命令开始调试
(3) 在IDA中按F9直至”libhellojni.so”加载为止.通过IDA的Output window窗口可以查看
(4) 此时在IDA的Debugger中打开Module list.并在其中使用Ctrl+F搜索hellojni.待结果处双击进入.进入后继续找到JNI_OnLoad函数继续双击进入.具体打开方式”Debugger”->”Debugger windows”->”Module list”
4.5.6调试JNI_OnLoad函数
(1)在JNI_OnLoad函数中下断点后一路F9,直至进入到断点为止.
4.5.7根据基址+偏移的方式算出RegisterNatives的位置.
基址:加载so库的初始地址.的当前地址:0x754BF000
偏移地址:静态分析时RegisterNatives所在的位置:0xFEA
绝对地址 = (754BF000+FEA)=0x754BFFEA
在IDA中使用G键进行跳转地址到:0x754BFFEA后下断点.并F9跳转到该位置.
4.5.8对sub_754BFFEA函数进行单步调试
通过JNI的知识可以推出R2存放的就是Native方法列表,那么进入R2寄存器查看里面的数据进行验证一下.
方法表对应的是java方法名,签名数据,C函数代码具体实现位置这三步.那么继续验证754C19D8, 754C19E0和754BFEA9地址中存放的值
其中看到jni_getText函数是不是一脸懵逼…其实这里只需要C或者P一下即可还原为汇编指令代码.
那么我们进入R1寄存器中查看数据进行验证一下吧.
5总结
要分析一个APP里面的native方法最有效的方法就是先静态分析一波,找到相关信息.然后在动态调试时使用基址加偏移的方式去定位函数.这样会很有效率,其次就是对JNI需要一定的了解,因为动态注册的JNI函数都是在JNI_OnLoad中进行加载的,所以在静态分析是定位到RegisterNatives函数,然后需要关注的是R0=JNIEnv* , R1=obj, R2=注册方法列表, R3=方法个数.其中方法表里的格式为Java方法名,签名信息,C函数代码实现地址.经过这一波分析,可以清楚地在JNI_OnLoad中找到相应的C函数体有一定的认知了.
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)