-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathpthread_create-fake.js
More file actions
96 lines (88 loc) · 3.01 KB
/
pthread_create-fake.js
File metadata and controls
96 lines (88 loc) · 3.01 KB
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
/**
* 替换目标库使用的pthread_create函数。
* @description 该脚本使用 Frida 进行动态分析,主要目标是:
* 1. 监听 `dlopen` / `android_dlopen_ext`,在加载目标库时执行后续 Hook 操作。
* 2. 监听 `call_constructors` 以确保目标库完全初始化后再 Hook `dlsym`。
* 3. Hook `dlsym` 并拦截特定符号(如 `pthread_create`),替换其返回值。
* 4. 通过 `fake_pthread_create` 生成虚假 `pthread_create` 实现,使目标库无法正确调用线程创建函数。
*/
const TARGET_LIB_NAME = "libmsaoaidsec.so";
var TargetLibModule = null; // 存储目标库模块信息
function create_fake_pthread_create() {
const fake_pthread_create = Memory.alloc(4096)
Memory.protect(fake_pthread_create, 4096, "rwx")
Memory.patchCode(fake_pthread_create, 4096, code => {
const cw = new Arm64Writer(code, { pc: ptr(fake_pthread_create) })
cw.putRet()
})
return fake_pthread_create
}
function hook_dlsym() {
var dlsym = Module.findExportByName(null, "dlsym");
if (dlsym !== null) {
Interceptor.attach(dlsym, {
onEnter: function (args) {
// 获取调用 dlsym 的返回地址
let caller = this.context.lr;
if (caller.compare(TargetLibModule.base) > 0 &&
caller.compare(TargetLibModule.base.add(TargetLibModule.size)) < 0) {
var name = ptr(args[1]).readCString(); // 读取符号名
if (name == 'pthread_create') {
console.warn(`replace symbol name: pthread_create`);
this.canFake = true;
}
}
},
onLeave: function (retval) {
if (this.canFake) {
retval.replace(fake_pthread_create);
}
}
});
}
}
function find_call_constructors() {
is64Bit = Process.pointerSize === 8;
var linkerModule = Process.getModuleByName(is64Bit ? "linker64" : "linker");
var symbols = linkerModule.enumerateSymbols();
for (var i = 0; i < symbols.length; i++) {
if (symbols[i].name.indexOf('call_constructors') > 0) {
console.warn(`call_constructors symbol name: ${symbols[i].name} address: ${symbols[i].address}`);
return symbols[i].address;
}
}
}
function hook_call_constructors() {
var ptr_call_constructors = find_call_constructors();
var listener = Interceptor.attach(ptr_call_constructors, {
onEnter: function (args) {
if (!TargetLibModule) {
TargetLibModule = Process.findModuleByName(TARGET_LIB_NAME);
}
console.warn(`call_constructors onEnter: ${TARGET_LIB_NAME} Module Base: ${TargetLibModule.base}`);
hook_dlsym();
listener.detach();
},
})
}
function hook_dlopen() {
["android_dlopen_ext", "dlopen"].forEach(funcName => {
let addr = Module.findExportByName(null, funcName);
if (addr) {
Interceptor.attach(addr, {
onEnter(args) {
let libName = ptr(args[0]).readCString();
if (libName && libName.indexOf(TARGET_LIB_NAME) >= 0) {
hook_call_constructors();
}
},
onLeave: function (retval) {
}
});
}
});
}
var is64Bit = Process.pointerSize === 8;
// 创建虚假pthread_create
var fake_pthread_create = create_fake_pthread_create();
hook_dlopen()