wechat_hook.js
3.44 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
/*
* WeChat macOS SQLCipher key interceptor
* Hook sqlite3_key / sqlite3_key_v2 in all loaded modules
*/
var found_keys = {};
function hookSqliteKey(moduleName, exports) {
var key_funcs = ['sqlite3_key', 'sqlite3_key_v2'];
key_funcs.forEach(function(fname) {
var sym = exports.find(function(e) { return e.name === fname; });
if (!sym) return;
Interceptor.attach(sym.address, {
onEnter: function(args) {
try {
var db = args[0];
if (fname === 'sqlite3_key') {
var pKey = args[1];
var nKey = args[2].toInt32();
if (nKey > 0 && nKey <= 128) {
var key = pKey.readByteArray(nKey);
var keyHex = Array.from(new Uint8Array(key))
.map(function(b) { return ('0' + b.toString(16)).slice(-2); })
.join('');
if (!found_keys[keyHex]) {
found_keys[keyHex] = true;
send({type: 'key', func: fname, module: moduleName, key_hex: keyHex, key_len: nKey});
}
}
} else {
// sqlite3_key_v2(db, zDbName, pKey, nKey)
var pKey = args[2];
var nKey = args[3].toInt32();
if (nKey > 0 && nKey <= 128) {
var key = pKey.readByteArray(nKey);
var keyHex = Array.from(new Uint8Array(key))
.map(function(b) { return ('0' + b.toString(16)).slice(-2); })
.join('');
if (!found_keys[keyHex]) {
found_keys[keyHex] = true;
send({type: 'key', func: fname, module: moduleName, key_hex: keyHex, key_len: nKey});
}
}
}
} catch(e) {
send({type: 'error', msg: e.toString()});
}
}
});
send({type: 'hooked', func: fname, module: moduleName, addr: sym.address.toString()});
});
}
// 扫描所有已加载模块
Process.enumerateModules().forEach(function(mod) {
try {
var exports = mod.enumerateExports();
var hasKey = exports.some(function(e) {
return e.name === 'sqlite3_key' || e.name === 'sqlite3_key_v2';
});
if (hasKey) {
hookSqliteKey(mod.name, exports);
}
} catch(e) {}
});
// 也 hook Module.load 以捕获之后加载的动态库
var dlopen_ptr = Module.findExportByName(null, 'dlopen');
if (dlopen_ptr) {
Interceptor.attach(dlopen_ptr, {
onLeave: function(retval) {
try {
Process.enumerateModules().forEach(function(mod) {
try {
var exports = mod.enumerateExports();
var hasKey = exports.some(function(e) {
return e.name === 'sqlite3_key' || e.name === 'sqlite3_key_v2';
});
if (hasKey) hookSqliteKey(mod.name, exports);
} catch(e) {}
});
} catch(e) {}
}
});
}
send({type: 'ready', msg: 'WeChat key interceptor active'});