前言
在Android应用中,出于对安全性的考虑,开发者会把一些重要的逻辑放到native层,即so库中。但是so库也并非绝对的安全,在强大的IDA反编译下,so库中的逻辑也将无所遁形。今天,我们要说的就是混淆so库中的方法名。
正文
我们先来看下为什么要这么做。我们新建一个Android项目,添加NDK支持,默认项目中会有一个方法如下
external fun stringFromJNI(): String
companion object {
// Used to load the 'native-lib' library on application startup.
init {
System.loadLibrary("native-lib")
}
}
然后我们编译运行,在app/build/intermediates/cmake/debug/obj/armeabi/libnative-lib.so
目录下找到我们编译出来的so库,在IDA中打开,我们可以很轻易的找到这个方法对应的地方
为什么会这样的?因为我们在写
JNI
的时候,采用javah命令生成的头文件,里面的方法名默认就是java_com_xxxx
这种形式。所以我们现在要做的就是改变这种映射关系。
当虚拟机加载这个这个库的时候,从java
层进入本地层首先会执行JNI_Onload
这个函数,java层的方法就是在这个方法中注册的,使用的方法为registerNativeMethods
,我们在这一步将注册我们自定义的方法,这样方法名就可以由我们自己来定义。接下来看代码实现。
- 重写
JNI_Onload
方法
extern "C"
jint JNI_OnLoad(JavaVM* vm,void* reserved){
JNIEnv* env;
if (vm->GetEnv((void**)(&env), JNI_VERSION_1_6) != JNI_OK)
{
return -1;
}
//这一步,注册我们的方法
if (!registerNatives(env)) {
return -1;
}
return JNI_VERSION_1_6;
}
- 接下来看
registerNatives
方法的实现
static JNINativeMethod gMethods[] = {
//第一个参数为Java层的方法名
//第二个参数为方法的签名,括号内为参数类型,后面为返回类型
//第三个参数即为我们需要重新注册的方法名
{ "stringFromJNI", "()Ljava/lang/String;", (void*)getStr},
};
extern "C"
int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = env->FindClass(className);
if (clazz == NULL) {
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
extern "C"
int registerNatives(JNIEnv* env)
{
if (!registerNativeMethods(env, JNIREG_CLASS, gMethods,
sizeof(gMethods) / sizeof(gMethods[0])))
return JNI_FALSE;
return JNI_TRUE;
}
到这里我们成功的替换了注册的方法,重新用IDA打开so库,发现我们这次找不到形如java_com_xxxx
的方法了最后,还有一步,我们还得实现替换后的方法
extern "C"
//这里指定该代码所在的段,编译的时候就会把这个函数编译到自定义的名叫”.mytext“的section里面
//由于我们在java层没有定义这个函数因此要写到一个自定义的section里面。
__attribute__((section (".mytext"))) JNICALL jstring getStr
(JNIEnv *env, jobject obj)
{
return (env)->NewStringUTF("abc");
}
至此,我们就完成了所有混淆方法的操作。
后记
这只是一步基础的安全操作,也很容破解。比如通过IDA动态调试找到RegisterNatives方法,就能直接找到所对应的方法,也能通过直接找额外的段来找到这个方法,但是这些就不在本文详细说明了,有兴趣的同学可以自己去尝试下。