首页
社区
课程
招聘
[原创]frida hook 动态加载的类(字节),切换loader后,java.lang.ClassNotFoundException的问题
发表于: 2025-9-2 10:32 3071

[原创]frida hook 动态加载的类(字节),切换loader后,java.lang.ClassNotFoundException的问题

2025-9-2 10:32
3071

// ===== 配置区 =====
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 可能限制
      }

传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 54
支持
分享
最新回复 (41)
雪    币: 362
活跃值: (903)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
看看
2025-9-2 10:46
0
雪    币: 3169
活跃值: (4094)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
过来瞧瞧
2025-9-2 11:07
0
雪    币: 3924
活跃值: (4380)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
6
2025-9-2 11:47
0
雪    币: 23
活跃值: (1480)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
666
2025-9-2 12:40
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
666
2025-9-2 15:55
0
雪    币: 209
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
666
2025-9-2 16:17
0
雪    币: 0
活跃值: (1625)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
6666
2025-9-3 10:48
0
雪    币: 0
活跃值: (1295)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
666
2025-9-3 14:34
0
雪    币: 1501
活跃值: (3838)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
10
2
2025-9-4 17:45
0
雪    币: 764
活跃值: (3082)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
1
2025-9-4 19:22
0
雪    币: 1828
活跃值: (1265)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
1
2025-9-5 07:08
0
雪    币: 2
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
11
2025-9-5 10:52
0
雪    币: 650
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
1
2025-9-5 15:22
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
1
2025-9-5 15:58
0
雪    币: 140
活跃值: (210)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
1
2025-9-5 20:41
0
雪    币: 8810
活跃值: (6642)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
感谢分享
2025-9-5 21:45
0
雪    币: 201
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
66666666
2025-9-6 01:29
0
雪    币: 21
活跃值: (290)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
66666
2025-9-6 10:09
0
雪    币: 97
活跃值: (1198)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
666666666666666
2025-9-6 23:06
0
雪    币: 318
活跃值: (420)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
感谢分享
2025-9-7 10:00
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
22
1
2025-9-7 15:48
0
雪    币: 1907
活跃值: (2730)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
看看
2025-9-7 16:25
0
雪    币: 1780
活跃值: (1355)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
24
看看
2025-9-8 10:33
0
雪    币: 766
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
感谢分享
2025-9-9 00:21
0
游客
登录 | 注册 方可回帖
返回