如果so是加密的,或者字符串有ollvm加密,可以把so文件dump下来,放到IDA中逆向,但是需要修复so文件

代码实际上就是获取so的基址和大小,然后读取这段内存,然后写出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function dump_so(so_name) {
Java.perform(function () {
var currentApplication = Java.use("android.app.ActivityThread").currentApplication();
var dir = currentApplication.getApplicationContext().getFilesDir().getPath();
var libso = Process.getModuleByName(so_name);
console.log("[name]:", libso.name);
console.log("[base]:", libso.base);
console.log("[size]:", ptr(libso.size));
console.log("[path]:", libso.path);
var file_path = dir + "/" + libso.name + "_" + libso.base + "_" + ptr(libso.size) + ".so";
var file_handle = new File(file_path, "wb");
if (file_handle && file_handle != null) {
Memory.protect(ptr(libso.base), libso.size, 'rwx');
var libso_buffer = ptr(libso.base).readByteArray(libso.size);
file_handle.write(libso_buffer);
file_handle.flush();
file_handle.close();
console.log("[dump]:", file_path);
}
});
}

注意dump出的so文件是adb pull无法pull出来的,没权限,需要adb进shell之后改777权限,然后移动到/sdcard目录下,/data/local/tmp下不行

1
/data/user/0/com.ximalaya.ting.android/files/liblogin_encrypt.so_0xb32e2000_0xe000.so

这个时候直接丢到IDA是报错,可以解析一部分内容,原因是IDA是作为静态格式去解析so文件的,而内存中的加载的so文件格式和静态格式不一样,需要修复so文件

使用SoFixer去修复

1
2
3
4
5
6
7
sofixer -s xxx.so -o fix.so -m 0x0 -d
-s 待修复的so文件路径
-o 修复后的so路径
-m 内存dump的基地址(十六位),基地址看文件名就行,比如liblogin_encrypt.so_0xb32e2000_0xe000.so,就是就是0xb32e2000
-d 输出debug信息

SoFixer_x86.exe -s liblogin_encrypt.so_0xb32e2000_0xe000.so -o fix.so -m 0xb32e2000 -d

SoFixer修复之后的so文件并不完全修复,有些节没有修复,不影响静态分析,但是拿去运行是运行不了的