如何使用IDA来导入头文件
本文详细记录一下使用IDA导入头文件的方法,以jni.h为例。
0x00 简介
在分析Android中的so时,常见的一个需求是要分析动态注册时JNI_Onload函数,但是IDA的识别效果不是很好,部分函数如RegisterNatives、FindClass、GetEnv没有识别出来。这时就需要导入jni.h这个头文件了。原生的JNI_Onload函数在IDA中F5的效果如下:
0x01 获取jni.h
jni.h源码位于Android NDK目录下,路径:<ndk-bundle>/sysroot/usr/include/jni.h
。在导入之前需要注释相应的头文件,否则IDA会找不到。复制一份到你需要的位置保存。
0x02 导入头文件
点击IDA中File->Load file -> Parse C header file,或者按快捷键Ctrl+F9可以打开导入窗口
选择刚才的jni.h导入后,可以看到IDA的导入成功窗口,注意一定要看log是否有其他报错:
0x03 导入结构体
这里给出一个JNI_Onload的动态注册的例子:
#include <jni.h>
static JNINativeMethod nativeMethod[]={
{
"helloworld",
"(Ljava/lang/String;)Ljava/lang/String;",
(void*)jnihelloworld
},
};
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
JNIEnv *env = NULL;
jint result = JNI_FALSE;
check();
if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
return result;
}
if (env == NULL) {
return result;
}
jclass clazz = env->FindClass("<your package name>"); // change to yourself
if (clazz == NULL) {
return result;
}
if (env->RegisterNatives(clazz, nativeMethod, sizeof(nativeMethod) / sizeof(nativeMethod[0])) < 0) {
return result;
}
result = JNI_VERSION_1_6;
return result;
}
在IDA中目前是无法识别JNIEnv *中的函数的,因此需要导入JNIEnv结构体。
点击IDA的Structures窗口,在空白处按I,会出现Create structure/union窗口,点击Add standard structure就可以导入结构体了。
选择_JNIEnv结构体,点击OK。
导入完成后,就可以看到Structures中多了一个_JNIEnv结构体:
0x04 修复参数类型
回到JNI_Onload函数,点env(由v4重命名而来),按y
修改参数的类型为JNIEnv *
,之后就可以识别出env中的函数了。同理还可以导入JavaVM *,最终F5效果如下: