Frida辅助分析ollvm字符串加密

.init_array字段

在IDA中,按ctrl + S可以找到

里面存有函数地址,在程序运行前先执行.init_array中的函数

在这里可以进行,ollvm混淆,frida检测,反调试等操作

ollvm字符串加密

hook打印对应地址的字符串

ollvm默认的字符串混淆,静态的时候没法看见字符串,执行起来之后,先调用.init_array里面的函数来解密字符串,解密完之后,内存中的字符串就是明文状态了。

  • var addr_37070 = base_hello_jni.add(0x37070);,在base地址的基础上添加偏移需要用封装好的方法add(),不能直接加

  • ptr(addr_37070).readCString(),意思是读取将addr_37070地址转为指针,再读取其地址中的字符串

hook_1.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function hook_native() {
var base_hello_jni = Module.findBaseAddress("libhello-jni.so");
if (base_hello_jni) {
//ollvm默认的字符串混淆,静态的时候没法看见字符串
//执行起来之后,先调用.init_array里面的函数来解密字符串
//解密完之后,内存中的字符串就是明文状态了。
var addr_37070 = base_hello_jni.add(0x37070);
console.log("addr_37070:", ptr(addr_37070).readCString());

var addr_37080 = base_hello_jni.add(0x37080);
console.log("addr_37080:", ptr(addr_37080).readCString());
}
}

function print_string(addr) {
var base_hello_jni = Module.findBaseAddress("libhello-jni.so");
var addr_str = base_hello_jni.add(addr);
console.log("addr:", addr, " ", ptr(addr_str).readCString());
}

function main() {
hook_native();
}

setImmediate(main);

inline hook、hook dlopen和android_dlopen_ext

注意hook JNI_Load()中的RegisterNatives时需要使用frida来帮我们启动apk:frida -U -f --no-pause com.example.xxx -l hook.js

  • console.log("addr_RegisterNatives name:", ptr(args[2]).readPointer().readCString()),如果发现打印的应该是一个字符串,但输出却是地址可以使用.readPointer()读取地址,再.readCString()读取字符串

  • inline hook时,如果报错,so未加载,说明inline hook在我们指定的so文件还没加载好就注入了,这时就要hook dlopen看看找到我们需要的so文件,在它加载好后再注入,如果还是没有(版本太低)就要hook一下高版本的android_dlopen_ext

  • inline hook 在低版本有时候不稳定,低版本有些是指令2字节,有些指令是4字节

hook_2.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
function hook_libart() {
var module_libart = Process.findModuleByName("libart.so");
var symbols = module_libart.enumerateSymbols(); //枚举模块的符号

var addr_GetStringUTFChars = null;
var addr_FindClass = null;
var addr_GetStaticFieldID = null;
var addr_SetStaticIntField = null;
var addr_RegisterNatives = null; // 怎么hook RegisterNatives

for (var i = 0; i < symbols.length; i++) {
var name = symbols[i].name;
if (name.indexOf("art") >= 0) {
if ((name.indexOf("CheckJNI") == -1) && (name.indexOf("JNI") >= 0)) {
if (name.indexOf("GetStringUTFChars") >= 0) {
console.log(name);
addr_GetStringUTFChars = symbols[i].address;
} else if (name.indexOf("FindClass") >= 0) {
console.log(name);
addr_FindClass = symbols[i].address;
} else if (name.indexOf("GetStaticFieldID") >= 0) {
console.log(name);
addr_GetStaticFieldID = symbols[i].address;
} else if (name.indexOf("SetStaticIntField") >= 0) {
console.log(name);
addr_SetStaticIntField = symbols[i].address;
} else if (name.indexOf("RegisterNatives") >= 0) {
console.log(name);
addr_RegisterNatives = symbols[i].address;
}
}
}
}

if (addr_RegisterNatives) {
Interceptor.attach(addr_RegisterNatives, {
onEnter: function (args) {
console.log("addr_RegisterNatives:", hexdump(args[2]));
console.log("addr_RegisterNatives name:", ptr(args[2]).readPointer().readCString());
console.log("addr_RegisterNatives sig:", ptr(args[2]).add(Process.pointerSize).readPointer().readCString());
}, onLeave: function (retval) {

}
});
}
}

function print_string(addr) {
var base_hello_jni = Module.findBaseAddress("libhello-jni.so");
//frida中地址的加法
var addr_str = base_hello_jni.add(addr);
console.log("addr:", addr, " ", ptr(addr_str).readCString());
}

function inline_hook() {
var base_hello_jni = Module.findBaseAddress("libhello-jni.so");
console.log("base_hello_jni:", base_hello_jni);
if (base_hello_jni) {
console.log(base_hello_jni);
//inline hook
var addr_07320 = base_hello_jni.add(0x07320);
Interceptor.attach(addr_07320, {
onEnter: function (args) {
console.log("addr_07320 x13:", this.context.x13);
}, onLeave: function (retval) {
}
});
}
}


function hook_dlopen() {
var dlopen = Module.findExportByName(null, "dlopen");
Interceptor.attach(dlopen, {
onEnter: function (args) {
this.call_hook = false;
var so_name = ptr(args[0]).readCString();
if (so_name.indexOf("libhello-jni.so") >= 0) {
console.log("dlopen:", ptr(args[0]).readCString());
this.call_hook = true;
}

}, onLeave: function (retval) {
if (this.call_hook) {
inline_hook();
}
}
});
// 高版本Android系统使用android_dlopen_ext
var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
Interceptor.attach(android_dlopen_ext, {
onEnter: function (args) {
this.call_hook = false;
var so_name = ptr(args[0]).readCString();
if (so_name.indexOf("libhello-jni.so") >= 0) {
console.log("android_dlopen_ext:", ptr(args[0]).readCString());
this.call_hook = true;
}

}, onLeave: function (retval) {
if (this.call_hook) {
inline_hook();
}
}
});
}

function main() {
hook_dlopen();
}

setImmediate(main);