// ===== 配置区 =====
const TARGET_CLASS = "com.bytedance.sdk.component.r.mn.o"; // 匿名内部类
const TARGET_METHOD = "cx"; // 目标回调
// const TARGET_CLASS = "com.bytedance.sdk.component.on.mn.t$1"; // 匿名内部类
//// const TARGET_METHOD = "onFailure"; // 目标回调
// const TARGET_METHOD = "onResponse"; // 目标回调
const PASSTHROUGH = true; // true=调用原方法更稳;false=不调原方法(仅观测)
Java.perform(function () {
var pinnedLoader = null;
// 1) 精准锁定能加载目标类的 ClassLoader(找到就停止)
Java.enumerateClassLoaders({
onMatch: function (loader) {
try {
if (loader.findClass(TARGET_CLASS)) {
pinnedLoader = loader;
return 'stop'; // 立刻停止,避免后续被别的 loader 覆盖
}
} catch (e) {}
},
onComplete: function () {}
});
if (!pinnedLoader) {
console.log("[!] Target class not found in any loader:", TARGET_CLASS);
return;
}
console.log("[*] Pinned loader =", pinnedLoader);
// 2) 切到该 loader 后再 use
Java.classFactory.loader = pinnedLoader;
var Target = Java.use(TARGET_CLASS);
// 为防止 ContextClassLoader 被第三方(如 GDT)换走,这里准备线程类
var Thread = Java.use("java.lang.Thread");
// 3) 安全 Hook:不去 toString 参数、不访问 getClass,避免触发类加载
Target[TARGET_METHOD].overloads.forEach(function (ov) {
const sig = ov.argumentTypes.map(t => t.className).join(", ");
console.log("[*] Hooking", TARGET_CLASS + "." + TARGET_METHOD + "(" + sig + ")");
ov.implementation = function () {
// 3.1 线程上下文 ClassLoader 保护
var t = Thread.currentThread();
var old = t.getContextClassLoader();
var needRestore = false;
try {
// 只有在不同的时候才设置,避免无谓扰动
if (old !== pinnedLoader) {
t.setContextClassLoader(pinnedLoader);
needRestore = true;
}
} catch (e) {
// 忽略:某些 ROM 可能限制
}
// 3.2 观测:仅打印一次固定文案,不触碰任何参数,避免触发类加载
console.log("[+] onFailure() invoked");
try {
if (PASSTHROUGH) {
console.log("[+] onFailure() invoked2222");
// 打印所有参数
console.log("\n====== Hooked onResponse ======");
try {
for (let i = 0; i < arguments.length; i++) {
let arg = arguments[i];
try {
console.log(" arg[" + i + "]: " + arg);
} catch (ee) {
console.log(" arg[" + i + "]: <error printing> " + ee);
}
}
} catch (e) {
console.log("!! error printing arguments:", e);
}
console.log("[+] onFailure() invoked3333");
// 调用原方法通常更稳(SDK 上层可能依赖该回调触发后续清理)
let ret;
try {
if (PASSTHROUGH) {
ret = ov.apply(this, arguments);
console.log(">>> [Return Value]:", ret);
return ret;
} else {
console.log(">>> NOOP (skip original)");
return; // void
}
} catch (e) {
console.log("!!! Exception in hook:", e);
}
} else {
// NOOP:不调用原方法,只做观测
return;
}
} finally {
// 3.3 恢复 ContextClassLoader
if (needRestore) {
try { t.setContextClassLoader(old); } catch (e) {}
}
}
};
});
console.log("[*] Hook installed:", TARGET_CLASS + "." + TARGET_METHOD);
});
Java.perform(function () {
var pinnedLoader = null;
// 1) 精准锁定能加载目标类的 ClassLoader(找到就停止)
Java.enumerateClassLoaders({
onMatch: function (loader) {
try {
if (loader.findClass(TARGET_CLASS)) {
pinnedLoader = loader;
return 'stop'; // 立刻停止,避免后续被别的 loader 覆盖
}
} catch (e) {}
},
onComplete: function () {}
});
if (!pinnedLoader) {
console.log("[!] Target class not found in any loader:", TARGET_CLASS);
return;
}
console.log("[*] Pinned loader =", pinnedLoader);
// 2) 切到该 loader 后再 use
Java.classFactory.loader = pinnedLoader;
var Target = Java.use(TARGET_CLASS);
// 为防止 ContextClassLoader 被第三方(如 GDT)换走,这里准备线程类
var Thread = Java.use("java.lang.Thread");
// 3) 安全 Hook:不去 toString 参数、不访问 getClass,避免触发类加载
Target[TARGET_METHOD].overloads.forEach(function (ov) {
const sig = ov.argumentTypes.map(t => t.className).join(", ");
console.log("[*] Hooking", TARGET_CLASS + "." + TARGET_METHOD + "(" + sig + ")");
ov.implementation = function () {
// 3.1 线程上下文 ClassLoader 保护
var t = Thread.currentThread();
var old = t.getContextClassLoader();
var needRestore = false;
try {
// 只有在不同的时候才设置,避免无谓扰动
if (old !== pinnedLoader) {
t.setContextClassLoader(pinnedLoader);
needRestore = true;
}
} catch (e) {
// 忽略:某些 ROM 可能限制
}
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!