how to fix Error: java.lang.ClassNotFoundException on frida
how to fix Error: java.lang.ClassNotFoundException on frida
我正在尝试使用 Frida 绕过 android 应用程序的 root 检测机制,我尝试了很多不同的脚本(frida 代码共享)和不同的方法(比如隐藏 root)但没有成功!
所以我试图找到 class 和负责检查设备是否已 root 并更改它的 return 值的方法。
这是我的脚本:
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 并更改此方法 return 值,它会失败并出现错误:
frida.core.RPCException: Error: java.lang.ClassNotFoundException: Didn't find class ...
我也试过生成应用程序然后使用反对 运行 “android root disable” 但它会 return 这个错误 :
frida.core.RPCException: TypeError: cannot read property 'getApplicationContext' of null
at getApplicationContext (src/android/lib/libjava.ts:21)
我不确定这是 Frida 或我的系统的问题还是...
我想如果我能够在 class 加载后恰好使我的主代码 运行s(比如使用循环检查或使用钩子),问题就会得到解决但我不知道如何在 js 中为 frida 编写这种代码。
我在 macOS 11.5.1 上使用 python 3.9 并安装了最新版本的 frida 和 objection
我已经在 android 10 的根 phone 和 android 6
的模拟器上进行了测试
Class 未找到
你怎么知道 class 是 app.name.RootUtils
你有没有使用 Jadx 或 apktool 反编译成应用程序?调用 RootUtils.isRooted()
的方法怎么样?是否有任何特殊代码加载 RootUtils
class 例如来自应用程序中包含的非标准 dex 文件?如果 class 是从一个特殊的 dex 文件加载的,你可以挂钩这个 dex 加载机制并首先执行它,然后为 RootUtils.isRooted()
.
安装你的挂钩
或者假设 RootUtils.isRooted()
仅从另一种方法调用并且不使用特殊代码来加载 RootUtils
class 您可以挂钩该方法并使用 this 挂钩来安装安装你的 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);
}
}
关于挂钩 class
的问题
我能够通过一个简单但不是很技术性的解决方案解决这个问题。
我对 运行 我的挂钩使用了 setInteval 一遍又一遍,直到它开始工作,(正如@Robert 提到的,我还需要将挂钩包装在 try catch 中以防止代码在第一次之后停止尝试)
这可能并不适用于所有人,但因为它对我有用,所以我将 post 最终代码,希望它能在将来帮助其他人:)
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 毫秒。
有时应用程序会在其 class 加载程序中进行加密,您可能需要将 Java.classFactory.loader 替换为应用程序自定义的 class 加载程序,以便 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
})
我正在尝试使用 Frida 绕过 android 应用程序的 root 检测机制,我尝试了很多不同的脚本(frida 代码共享)和不同的方法(比如隐藏 root)但没有成功!
所以我试图找到 class 和负责检查设备是否已 root 并更改它的 return 值的方法。
这是我的脚本:
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 并更改此方法 return 值,它会失败并出现错误:
frida.core.RPCException: Error: java.lang.ClassNotFoundException: Didn't find class ...
我也试过生成应用程序然后使用反对 运行 “android root disable” 但它会 return 这个错误 :
frida.core.RPCException: TypeError: cannot read property 'getApplicationContext' of null at getApplicationContext (src/android/lib/libjava.ts:21)
我不确定这是 Frida 或我的系统的问题还是...
我想如果我能够在 class 加载后恰好使我的主代码 运行s(比如使用循环检查或使用钩子),问题就会得到解决但我不知道如何在 js 中为 frida 编写这种代码。
我在 macOS 11.5.1 上使用 python 3.9 并安装了最新版本的 frida 和 objection
我已经在 android 10 的根 phone 和 android 6
的模拟器上进行了测试Class 未找到
你怎么知道 class 是 app.name.RootUtils
你有没有使用 Jadx 或 apktool 反编译成应用程序?调用 RootUtils.isRooted()
的方法怎么样?是否有任何特殊代码加载 RootUtils
class 例如来自应用程序中包含的非标准 dex 文件?如果 class 是从一个特殊的 dex 文件加载的,你可以挂钩这个 dex 加载机制并首先执行它,然后为 RootUtils.isRooted()
.
或者假设 RootUtils.isRooted()
仅从另一种方法调用并且不使用特殊代码来加载 RootUtils
class 您可以挂钩该方法并使用 this 挂钩来安装安装你的 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);
}
}
关于挂钩 class
的问题我能够通过一个简单但不是很技术性的解决方案解决这个问题。
我对 运行 我的挂钩使用了 setInteval 一遍又一遍,直到它开始工作,(正如@Robert 提到的,我还需要将挂钩包装在 try catch 中以防止代码在第一次之后停止尝试)
这可能并不适用于所有人,但因为它对我有用,所以我将 post 最终代码,希望它能在将来帮助其他人:)
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 毫秒。
有时应用程序会在其 class 加载程序中进行加密,您可能需要将 Java.classFactory.loader 替换为应用程序自定义的 class 加载程序,以便 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
})