繁体   English   中英

如何修复错误:frida 上的 java.lang.ClassNotFoundException

[英]how to fix Error: java.lang.ClassNotFoundException on frida

我试图绕过使用 Frida 的 android 应用程序上的根检测机制,我尝试了很多不同的脚本(frida 代码共享)和不同的方法(如隐藏根),但没有成功!

所以我试图找到负责检查设备是否已植根并更改其返回值的类和方法。

这是我的脚本:

setTimeout(function() { // avoid java.lang.ClassNotFoundException
  Java.perform(function() {
    var hook = Java.use("app.name.RootUtils");
    console.log("info: hooking target class");

    hook.isRooted.overload().implementation = function() {
      console.log("info: entered target method");
      return Java.use("java.lang.Boolean").$new(false);
    }
  });
},0);

如果我正常注入此代码,它将无法工作,因为看起来 isRooted 方法会在它之前被调用

如果我使用 spawn 运行应用程序并更改此方法返回值,则会失败并出现错误:

frida.core.RPCException:错误:java.lang.ClassNotFoundException:找不到类...

我也尝试过生成应用程序,然后使用反对来运行“android root disable”,但它会返回此错误:

frida.core.RPCException:TypeError:无法在 getApplicationContext (src/android/lib/libjava.ts:21) 处读取 null 的属性“getApplicationContext”

我不确定这是否是 Frida 或我的系统的问题,或者......

我想如果我能够让我的主要代码在类被加载之后运行(比如使用循环检查或使用钩子)问题就会得到解决,但我不知道如何编写那种代码js for frida。

我在 macOS 11.5.1 上使用 python 3.9 并安装了最新版本的 frida 和 objection

我已经在一部带有 android 10 的 root 手机和带有 android 6 的模拟器上进行了测试

找不到类

你怎么知道这个类是app.name.RootUtils你有没有使用 Jadx 或 apktool 反编译为应用程序? 调用RootUtils.isRooted()的方法怎么样? 是否有任何特殊代码可以从应用程序中包含的非标准 dex 文件加载RootUtils类? 如果该类是从一个特殊的 dex 文件加载的,您可以挂钩此 dex 加载机制并首先执行它,然后为RootUtils.isRooted()安装您的挂钩。

或者,假设RootUtils.isRooted()另一种方法调用RootUtils.isRooted()并且不使用特殊代码来加载RootUtils类,您可以挂钩该方法并使用此挂钩来安装安装您的RootUtils.isRooted()挂钩。

错误处理

在 JavaScript 中处理错误的正确方法是使用try catch块,而不是setTimeout函数:

Java.perform(() => {
    try {
        var hook = Java.use("app.name.RootUtils");
        ...
    } catch (e) {
        console.log("Failed to hook root detection" + e);
    }
}

关于你挂在课堂上的问题

我能够通过一个简单但不是非常技术性的解决方案来解决这个问题。

我使用 setInteval 一遍又一遍地运行我的挂钩,直到它开始工作,(正如@Robert 提到的,我还需要将挂钩包装在 try catch 中,以防止代码在第一次尝试后停止)

这可能不适用于每个人,但由于它对我有用,我将发布最终代码,希望它在未来对其他人有所帮助:)

Java.perform(function() {
  var it = setInterval(function(){
    try{
      var hook = Java.use("app.name.RootUtils");
      console.log("info: hooking target class");

      hook.isRooted.overload().implementation = function() {
        console.log("info: entered target method");
        clearInterval(it);
        return Java.use("java.lang.Boolean").$new(false);
      }
    } catch(e) {
      console.log("failed!");
    }
  },200); // runs every 200milisecods
});

PS:您可能需要更改间隔时间以匹配您的应用程序需求,它对我有用 200 毫秒。

有时应用程序会在其类加载器中进行加密,您可能需要将 Java.classFactory.loader 替换为应用程序的自定义类加载器,以使 Java.use 正常运行。

这是如何完成的:

Java.perform(function() {

    //get real classloader
    //from http://www.lixiaopeng.top/article/63.html
    var application = Java.use("android.app.Application");
    var classloader;
    application.attach.overload('android.content.Context')
        .implementation = function(context) {
            var result = this.attach(context); // run attach as it is
            classloader = context.getClassLoader(); // get real classloader
            Java.classFactory.loader = classloader;
        return result;
    }
    
    //interesting classes
    const interestingClassPath = "com.myApp.SometingInteresting";
    interestingClass = Java.use(interestingClassPath);

   //do whatever you like here
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM