分析SO文件时,总是会遇上调用JNI函数的情况,每次遇上总是要去翻书签,查找自己保留的书签目录,遇到书签、历史记录不小心被清除了,就瓜了,所以想在这里记录下三种方式,可以直接让我们直观的看到调用的函数,
1、用IDA打开android_ndk_xxx/sample/Hello-jni下生成的libhello-jni.so,Java_com_example_hellojni_HelloJni_stringFr
omJNI 函数显示如下:
F5(Tab)以后的显示结果如下:
想要得到调用的jni函数名,鼠标选中a1,单击y,弹出如下界面
将a1修改为JNIEnv*,单击OK按钮,就会显示调用的具体函数名称,如下图所示:
2、导入jni.h头文件
步骤二:简单修改jni.h ,注释第27行的#include<stdarg.h> ,还有将1122行的#define JNIEXPORT_attribute_((visibility("default"))) 改成 #define JNIEXPORT 修改完后可以成功导入 {文件保存在C:\Program Files (x86)\IDA 6.6\tools}
步骤三:导入成功后把jni.h修改的地方 改回来 防止编译NDK出错。
步骤四:点击IDA Pro 主界面上的“Structures”选项卡 然后按下Insert键打开“Create structure/union”对话框,点击界面上的"Add standard structure"按钮,在打开的结构体选择对话框中选择JNINativeInterface并点击OK返回,同理JNIInvokeInterface结构体也导入进来;(我自己按照这种方式导入,但是不停的报错,于是我只能逐个按照错误信息,将错误点干掉(然后就成功了))
以下是我的实验结果:
一开始我没有按照步骤二来执行(因为我想要知道我不按照流程做会怎样)我直接导入jni.h,报错了,错误如下:
说明没有找到cdefs.h头文件,我测试了各种办法,都无法解决这个问题,于是我把这个头文件导入给注释了,
再次导入,依旧报错,报错内容为:
platforms\android-21\arch-arm\usr\include\jni.h,28: Can't open include file 'stdarg.h'
这里我没有注释掉头文件的导入,我换了一种方式,options->complier,将stdarg.h的所在路径(android-ndk-r10d\toolchains\arm-linux-androideabi-4.8\prebuilt\windows\lib\gcc\arm-linux-androideabi\4.8\include)加入到Include directories中,与ida默认提供的gun C++的头文件路径以":"分割开来。之后再次导入jni.h,显示成功。
之后就是按照步骤四来执行,完成之后还是不能正常显示调用的jni.h函数名称了,如图所示;
这里我们离成功只差一步了。
5、首先我们应该转换 __JNIEnv, 可以看到
4 _JNIEnv struct {const struct JNINativeInterface *functions;} 4 |
结果如下图所示:
正常显示了,
第三种方法是采用飞虫提供的jni.idc脚本来完成jni.h的导入,每一次我们进行逆向分析,如果都需要按照方式一,方式二来进行,就太蛋疼了。这里要感谢飞虫大佬为我们提供了这么好用的idc脚本(我对这个jni.idc脚本很好奇,所以打算花点时间好好研究一下,之后会把相关的分析贴出来,方便像我这样记忆又不好,又是小白的来学习下),感谢他,,至于脚本我会放在我的资源里边,欢迎下载,当然你也可以通过谷歌,或者百度去找,肯定能找到,
方法如下:script file导入jni.idc,重复步骤4,5就可以正常显示了。
参考:
https://blog.csdn.net/u010382106/article/details/44960243
https://bbs.pediy.com/thread-204264.htm