let trace_map = new Map();
function _py_str(s) {
return '"' + String(s).replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"';
}
function dump_as_python_dict(trace_map) {
if (!trace_map || typeof trace_map.forEach !== "function") {
console.log("{}");
return;
}
let lines = [];
trace_map.forEach(function (node, pc_hex) {
let br_reg = (node && node.br_reg) ? node.br_reg : "";
let values = (node && node.values) ? node.values : new Map();
let innerParts = [];
values.forEach(function (val, xn_1) {
if (Array.isArray(val)) {
let listStr = "[" + val.map(function (s) { return _py_str(s); }).join(", ") + "]";
innerParts.push(_py_str(xn_1) + ": " + listStr);
} else {
innerParts.push(_py_str(xn_1) + ": " + _py_str(val));
}
});
let valuesStr = "{" + innerParts.join(", ") + "}";
lines.push(" " + _py_str(pc_hex) + ": {\"br_reg\": \"" + br_reg + "\", \"values\": " + valuesStr + "}");
});
console.log("{\n" + lines.join(",\n") + "\n}");
}
function hook_libmtguard_by_offset(base) {
let hook_addr_map = new Map();
hook_addr_map.set(0x139dd0, "x9");
hook_addr_map.set(0x13a184, "x8");
hook_addr_map.set(0x13a548, "x10");
hook_addr_map.set(0x13a5b4, "x8");
hook_addr_map.set(0x13a914, "x8");
hook_addr_map.set(0x13afc8, "x8");
hook_addr_map.set(0x13b00c, "x8");
hook_addr_map.set(0x13b6cc, "x8");
hook_addr_map.set(0x13bce0, "x8");
hook_addr_map.set(0x13bed4, "x8");
hook_addr_map.set(0x13c214, "x8");
hook_addr_map.set(0x13d024, "x8");
hook_addr_map.set(0x13d07c, "x8");
hook_addr_map.forEach(function (br_reg_name, off) {
let addr = base.add(off)
Interceptor.attach(addr, {
onEnter() {
let changed = false;
let pc_offset = this.context.pc.sub(base);
let pc_offset_hex = "0x" + pc_offset.toString(16);
console.log("pc_offset_hex =", pc_offset_hex);
let reg = this.context[br_reg_name];
let xn_value_1 = reg.toInt32();
let xn_value_1_hex = "0x" + xn_value_1.toString(16);
console.log("xn_value_1_hex =", xn_value_1_hex);
let xn_value_2 = xn_value_1 + 0x2e;
let xn_value_2_hex = "0x" + xn_value_2.toString(16);
console.log("xn_value_2_hex =", xn_value_2_hex);
let xn_value_3 = this.context.x23.add(xn_value_2 * 8).readU64();
let xn_value_3_hex = "0x" + xn_value_3.toString(16);
console.log("xn_value_3_hex =", xn_value_3_hex);
let xn_value_4 = this.context.x23.add(xn_value_3 * 8).readU64();
let xn_value_4_hex = "0x" + xn_value_4.toString(16);
console.log("xn_value_4_hex =", xn_value_4_hex);
let xn_value_5 = ptr(xn_value_4).sub(base);
let xn_value_5_hex = "0x" + (xn_value_5 >>> 0).toString(16);
console.log("xn_value_5_hex =", xn_value_5_hex);
if(!trace_map.has(pc_offset_hex)) {
trace_map.set(pc_offset_hex, {
br_reg: br_reg_name,
values: new Map()
});
changed = true;
}
let pc_node = trace_map.get(pc_offset_hex);
if(!pc_node.values.has(xn_value_1_hex)) {
pc_node.values.set(xn_value_1_hex, [xn_value_3_hex, xn_value_5_hex]);
changed = true;
}
if (!changed)
return;
dump_as_python_dict(trace_map);
console.log("======================");
}
});
});
}
function hook_linker_load() {
var dlopen = Module.findExportByName(null, "dlopen");
var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
if (dlopen) {
console.log("[+] dlopen @", dlopen);
Interceptor.attach(dlopen, {
onEnter: function (args) {
var name = args[0].readCString();
if (name && name.indexOf(".so") > -1) {
}
}
});
} else {
console.log("[-] dlopen not found");
}
if (android_dlopen_ext) {
console.log("[+] android_dlopen_ext @", android_dlopen_ext);
Interceptor.attach(android_dlopen_ext, {
onEnter: function (args) {
this.soname = args[0].readCString();
},
onLeave: function () {
if (!this.soname) return;
if (this.soname.indexOf("libxxguard.so") === -1) {
return;
}
var base = Module.findBaseAddress("libxxguard.so");
if (!base) {
base = Module.findBaseAddress(this.soname);
}
if (!base) {
console.log("[-] libxxguard.so base not found yet");
return;
}
console.log("[+] libxxguard.so base =", base);
console.log("[+] libxxguard.so pid =", Process.id);
hook_libmtguard_by_offset(base);
}
});
} else {
console.log("[-] android_dlopen_ext not found");
}
}
function main() {
hook_linker_load();
}
setImmediate(main);