怕上火喝王老吉 发表于 2020-3-7 16:28

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

本帖最后由 怕上火喝王老吉 于 2020-3-7 16:31 编辑

IDA动态调试动态注册native函数流程1.编写目的记录IDA动态调试步骤2使用工具逆向工具: IDA 7.0 , Jadx
运行环境:Nexus 5 (Android 4.4)3.原字符串信息https://yl.qiyikt.com/data/attachment/forum/201911/25/232226evvelqacde1lwydy.png4.实现流程4.1 使用adb命令定位字符串位置   1.手机打开字符串所在界面2.手机连接电脑3.在cmd中输入”adb shell dumpsys activity top”查看当前顶层界面所在app的工程位置
结果:目标所在位置 : ”com.glj.dynamicregistration/.MainActivity”https://yl.qiyikt.com/data/attachment/forum/201911/25/232227injkn26adkdc2mmz.png
4.2 使用Jadx对APP进行逆向分析Jadx工具分析完后打开包名”com.glj.dynamicregistration”下的”MainActivity”https://yl.qiyikt.com/data/attachment/forum/201911/25/232228h2c6lgpbegcp72be.png
4.3 定位字符串显示位置1.在onCreate中只有一个TextView从getText()函数中获取字符串,再看getText()函数是经过native修饰的.那么可以肯定这是一个jni函数.再看Activity中确实加载了一个”hellojni”的so库,那么我们基本上定义这是从so库中获取的字符内容.https://yl.qiyikt.com/data/attachment/forum/201911/25/232228hocbaap1r4pp11wk.png4.4 获取so库   将app的apk格式改为zip压缩包格式后打开,在lib目录下进行扣取      https://yl.qiyikt.com/data/attachment/forum/201911/25/232229er7i0jrjxz4jawrb.png4.4 IDA加载so库静态分析(1)将so文件直接拖拽进入IDA加载后点击Exports窗口是否存在java开头的函数,看下图,发现并没有.那么下一步只能去分析JNI_OnLoad函数了.
https://yl.qiyikt.com/data/attachment/forum/201911/25/232230v2yogfgp8xmfn3jg.png4.5 静态分析JNI_OnLoad(1) 将JNI_OnLoad函数的形参识别为”JavaVM*”类型(2) 从13行中可以看到sub_F70函数,那么我们继续跟进去.https://yl.qiyikt.com/data/attachment/forum/201911/25/232230fhrksok01shkyshu.png(3) 在sub_F70中可以看见直接返回了sub_FA4函数的返回值.那么我们继续跟进去看.https://yl.qiyikt.com/data/attachment/forum/201911/25/232230o9f8fvmh9mck898n.png
(4)在sub_FA4函数终于看到了我们的RegisterNatives函数了,那么可以继续跟进去查看一番https://yl.qiyikt.com/data/attachment/forum/201911/25/232230r0l0mk0002mw9m70.png(5)很抱歉,不能继续再跟了,那么将sub_FA4函数的代码同步到汇编里面.https://yl.qiyikt.com/data/attachment/forum/201911/25/232231cbw2bwpc7b7bpp18.pnghttps://yl.qiyikt.com/data/attachment/forum/201911/25/232232xvs4nzgyw1vnnh4l.png
4.5动态JNI_OnLoad函数4.5.1 启动android-serverhttps://yl.qiyikt.com/data/attachment/forum/201911/25/232233u8i26mz02522ct82.png4.5.2 端口转发https://yl.qiyikt.com/data/attachment/forum/201911/25/232233coejvd8deeezde2c.png
4.5.3 使用am命令启动app注:命令格式为:am start -D -n 包名/.入口
https://yl.qiyikt.com/data/attachment/forum/201911/25/232234a7wgvirvchhv7avw.png使用Android Device Monitor工具查看当前APP的端口https://yl.qiyikt.com/data/attachment/forum/201911/25/232234gpj79pljgailjp83.png
4.5.4 打开IDA工具附加进程https://yl.qiyikt.com/data/attachment/forum/201911/25/232234ekk6dhdjeleckjeh.png选择”Debugger”->”Attach”->”Remote ARMLinux/Android debugger”进行打开附加窗口,并点击”Debug options”勾选三项
https://yl.qiyikt.com/data/attachment/forum/201911/25/232235yq8p3fknfqoqnf71.png
https://yl.qiyikt.com/data/attachment/forum/201911/25/232235sy0vyu8ggz000zmz.png
在附加进程窗口搜索关键字并双击调试的进行加载.https://yl.qiyikt.com/data/attachment/forum/201911/25/232235qn1unrrqu9j3o3nc.png
进程附加完毕https://yl.qiyikt.com/data/attachment/forum/201911/25/232237d0q2zxl0xb0qoobl.png4.5.5 定位JNI_OnLoad函数(1)此时继续勾选三项”Debugger”->”Debugger options”https://yl.qiyikt.com/data/attachment/forum/201911/25/232237c888ibloci621liv.png
https://yl.qiyikt.com/data/attachment/forum/201911/25/233140rn8k5kvv7mnx8kdx.png(2)   使用jdb命令开始调试https://yl.qiyikt.com/data/attachment/forum/201911/25/233140o28swcwx2xzwi3ix.png
(3)   在IDA中按F9直至”libhellojni.so”加载为止.通过IDA的Output window窗口可以查看https://yl.qiyikt.com/data/attachment/forum/201911/25/233140pr79rd6di40l0p0c.png

(4)   此时在IDA的Debugger中打开Module list.并在其中使用Ctrl+F搜索hellojni.待结果处双击进入.进入后继续找到JNI_OnLoad函数继续双击进入.具体打开方式”Debugger”->”Debugger windows”->”Module list”https://yl.qiyikt.com/data/attachment/forum/201911/25/233140iiw4eej44latrmri.png

https://yl.qiyikt.com/data/attachment/forum/201911/25/233141vhzoccm9c8b8eczn.pnghttps://yl.qiyikt.com/data/attachment/forum/201911/25/233141c70ab2n220aah0me.png
4.5.6调试JNI_OnLoad函数(1)在JNI_OnLoad函数中下断点后一路F9,直至进入到断点为止.https://yl.qiyikt.com/data/attachment/forum/201911/25/233141gi61ti6grnmi333r.png

4.5.7根据基址+偏移的方式算出RegisterNatives的位置.基址:加载so库的初始地址.的当前地址:0x754BF000https://yl.qiyikt.com/data/attachment/forum/201911/25/233142apez2vziai3cxxe2.png
偏移地址:静态分析时RegisterNatives所在的位置:0xFEAhttps://yl.qiyikt.com/data/attachment/forum/201911/25/233142cffq8tn3ylxu8sft.png
绝对地址 = (754BF000+FEA)=0x754BFFEA
在IDA中使用G键进行跳转地址到:0x754BFFEA后下断点.并F9跳转到该位置.https://yl.qiyikt.com/data/attachment/forum/201911/25/233142h3n3on5ggp66sz1g.png



https://yl.qiyikt.com/data/attachment/forum/201911/25/233143clntwlzr78bsq3f2.png
4.5.8 对sub_754BFFEA函数进行单步调试通过JNI的知识可以推出R2存放的就是Native方法列表,那么进入R2寄存器查看里面的数据进行验证一下.https://yl.qiyikt.com/data/attachment/forum/201911/25/233143zcqjaz1rzamfacga.png

方法表对应的是java方法名,签名数据,C函数代码具体实现位置这三步.那么继续验证754C19D8, 754C19E0和754BFEA9地址中存放的值
https://yl.qiyikt.com/data/attachment/forum/201911/25/233144kr4c4ycmxyyucjyj.png

https://yl.qiyikt.com/data/attachment/forum/201911/25/233144hoepn2k181l1f6p6.png

https://yl.qiyikt.com/data/attachment/forum/201911/25/233144j4z6vxv4mzvbbgqt.png

https://yl.qiyikt.com/data/attachment/forum/201911/25/233145d4bb3jqb34jjqall.png

其中看到jni_getText函数是不是一脸懵逼…其实这里只需要C或者P一下即可还原为汇编指令代码.https://yl.qiyikt.com/data/attachment/forum/201911/25/233145g0vnh3dg2hdhdh62.png

https://yl.qiyikt.com/data/attachment/forum/201911/25/233147u3z44gg943zz4otx.png

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

https://yl.qiyikt.com/data/attachment/forum/201911/25/233148ihb2hhhvfz2zdvfd.png
5总结要分析一个APP里面的native方法最有效的方法就是先静态分析一波,找到相关信息.然后在动态调试时使用基址加偏移的方式去定位函数.这样会很有效率,其次就是对JNI需要一定的了解,因为动态注册的JNI函数都是在JNI_OnLoad中进行加载的,所以在静态分析是定位到RegisterNatives函数,然后需要关注的是R0=JNIEnv* ,R1=obj, R2=注册方法列表, R3=方法个数.其中方法表里的格式为Java方法名,签名信息,C函数代码实现地址.经过这一波分析,可以清楚地在JNI_OnLoad中找到相应的C函数体有一定的认知了.工具链接:https://pan.baidu.com/s/1Wxa-jRXx72AgUrU6icvUQA
提取码:o3uh

erh 发表于 2020-3-9 18:23

怕上火喝王老吉 发表于 2020-3-9 11:00
没有失效啊

确实没有失效.
应该是我没有下载那个文本文件,直接从网页上复制网盘地址的事.
谢谢!

xiaoqu525 发表于 2020-3-7 17:02

好像很厉害的样子。。。

此用户无法显示 发表于 2020-3-7 17:15

厉害啊楼主,支持技术贴

Rolanju 发表于 2020-3-7 17:53

支持一下

wenwlg 发表于 2020-3-7 18:27

好复杂。。。。

DG5200 发表于 2020-3-7 18:32

谢谢大佬分享,学习了

雨落惊鸿, 发表于 2020-3-7 19:12

厉害厉害

sunbester 发表于 2020-3-7 19:22

网盘里没有android例子啊

xt2000 发表于 2020-3-7 19:28

支持一下

夜步城 发表于 2020-3-7 21:03

来学习一下,感谢
页: [1] 2
查看完整版本: IDA动态调试动态注册native函数流程