initializeGlobals() 符号解析
🔧 解析并初始化所有需要 hook 的 Native 符号地址,构造 NativeFunction 包装。
📎 源码在线查看:
script.js#L124-L183(initializeGlobals)
作用
用 ApiResolver("module") 按 exports:库通配符!函数名 的方式枚举匹配地址,把结果存入全局 addresses 表,并构造对应的 NativeFunction 包装。
解析两组符号
javascript
function initializeGlobals() {
var resolver = new ApiResolver("module");
var exps = [
[Process.platform == "darwin" ? "*libboringssl*" : "*libssl*",
["SSL_read", "SSL_write", "SSL_get_fd", "SSL_get_session", "SSL_SESSION_get_id"]],
[Process.platform == "darwin" ? "*libsystem*" : "*libc*",
["getpeername", "getsockname", "ntohs", "ntohl"]]
];
...
}| 组 | 库 | 符号 |
|---|---|---|
| SSL 组 | *libssl*(Android) / *libboringssl*(darwin) | SSL_read, SSL_write, SSL_get_fd, SSL_get_session, SSL_SESSION_get_id |
| libc 组 | *libc*(Android) / *libsystem*(darwin) | getpeername, getsockname, ntohs, ntohl |
平台分支:Process.platform == "darwin" 走 iOS/macOS 分支,其余走 Android/Linux 分支。
三种匹配结果处理
1. 零匹配
javascript
if (matches.length == 0) {
if (name == "SSL_get_fd") {
addresses["SSL_get_fd"] = 0; // 允许缺失,后续用桩
continue;
}
throw "Could not find " + lib + "!" + name; // 其它符号缺失直接抛异常
}SSL_get_fd允许缺失(个别 ROM 缺这个导出),置 0 后续用return_zero桩降级- 其它符号缺失直接抛异常,避免静默失败
2. 多匹配(关键逻辑)
javascript
else if (matches.length > 1) {
var selectedMatch = null;
for (var k = 0; k < matches.length; k++) {
if (matches[k].name.indexOf("com.android.conscrypt") !== -1) {
selectedMatch = matches[k];
break;
}
}
if (selectedMatch === null) {
selectedMatch = matches[0];
}
addresses[name] = selectedMatch.address;
console.log("[*] Selected " + name + " from: " + selectedMatch.name);
}同名符号在多个库里都有匹配(常见于 Android 同时存在系统 libssl 与 Conscrypt 自带 SSL 实现)。优先选 com.android.conscrypt 的实现,因为 Android 上 App 流量实际走 Conscrypt。无 conscrypt 命中则退回第一个匹配。
3. 唯一匹配
javascript
else {
addresses[name] = matches[0].address;
}构造 NativeFunction
javascript
if (addresses["SSL_get_fd"] == 0) {
SSL_get_fd = return_zero; // 桩,永远返回0
} else {
SSL_get_fd = new NativeFunction(addresses["SSL_get_fd"], "int", ["pointer"]);
}
SSL_get_session = new NativeFunction(addresses["SSL_get_session"], "pointer", ["pointer"]);
SSL_SESSION_get_id = new NativeFunction(addresses["SSL_SESSION_get_id"], "pointer", ["pointer", "pointer"]);
getpeername = new NativeFunction(addresses["getpeername"], "int", ["int", "pointer", "pointer"]);
getsockname = new NativeFunction(addresses["getsockname"], "int", ["int", "pointer", "pointer"]);
ntohs = new NativeFunction(addresses["ntohs"], "uint16", ["uint16"]);
ntohl = new NativeFunction(addresses["ntohl"], "uint32", ["uint32"]);每个 NativeFunction(address, retType, [argTypes]) 把 Native 地址包装成可调用的 JS 函数。
触发时机
javascript
// 脚本加载时立即执行一次
initializeGlobals();
// setssllib RPC 时重新执行
rpc.exports = {
setssllib: function (name) {
libname = name;
initializeGlobals();
}
};