在进行安全研究中,我们需要经常使用ida等工具对app的so进行动态调试。这其中遇到的最大问题可能就是app加了反调试、反root等保护手段对应用运行环境进行检测,而这些手段往往是在我们附加进程之前就已经加载了的,所以不能通过ida等调试工具直接附加进程的方式来调试这些so,因而需要我们自己实现加载器来加载目标so文件。
下面就是我们写的一个简单的加载器代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <dlfcn.h> 4 5 int main(){ 6 printf("Loading libs "); 7 int (*pt2Function)(void) = NULL; 8 //pointer to a void function - change this to match method sig 9 void* sdl_library = dlopen("/system/libtarget.so", RTLD_LAZY); 10 if (sdl_library == NULL) { 11 // report error ... 12 printf("Unable to load library "); 13 char *errstr; 14 errstr = dlerror(); 15 if (errstr != NULL) 16 printf ("A dynamic linking error occurred: (%s) ", errstr); 17 } else { 18 printf("Lib loaded, getting dlysm "); 19 void* initializer = dlsym(sdl_library,"JNI_OnLoad"); 20 if (initializer == NULL) { 21 // report error ... printf("Unable to get address of JNI_OnLoad "); 22 char *errstr; 23 errstr = dlerror(); 24 if (errstr != NULL) 25 printf ("A dynamic linking error occurred: (%s) ", errstr); 26 } else { 27 // cast initializer to its proper type and use 28 printf("calling get process "); 29 //asm("BKPT #0"); 30 pt2Function = initializer; 31 printf("got get process, setting up "); 32 printf("Ok, lets Calling the function"); 33 int result = pt2Function(); 34 printf("Result of call is %d", result); 35 //asm("BKPT #0"); 36 } 37 } 38 return 0; 39 }
从代码中可知,我们的目标是JNI_Onload函数,这是因为反调试和系统环境检测功能代码往往是在JNI_Onload函数中设置的。我们可以控制该函数指针指向任意so文件的导出函数然后调用它。
这个代码可以在任意标准Linux系统下编译运行。我们使用dlopen()函数动态加载library库,dlsym()函数控制指针指向我们需要测试的导出函数,然后直接调用目标函数,传递任意参数给它,以便跟踪执行流程,甚至进行fuzz,漏洞利用。
要对上述代码进行编译,还需编写Android.mk文件:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # give module name LOCAL_MODULE := soloader # list your C files to compile LOCAL_SRC_FILES := soloader.c # Build executables instead of a library for android. include $(BUILD_EXECUTABLE)
通过Android studio创建Android工程,将soloader.c和Android.mk文件置于src/mian/jni目录下,通过ndk-build进行编译,然后在/libs/armeabi目录下就可以找到编译好的soloader了。然后通过adb命令push到/system目录(需要先remount),就可以执行了。
本文根据https://www.trustwave.com/Resources/SpiderLabs-Blog/Custom-Native-Library-Loader-for-Android/进行翻译。