Android使用Frida钩住抽象类方法调用
到目前为止,我正在努力学习,并尝试了一点。幸好我能找到足够的例子和教程来帮助我度过难关。 然而,此时此刻,我手头有一项非常具体的任务 让我们假设下面是我指的Frida钩子:Android使用Frida钩住抽象类方法调用,android,security,hook,code-injection,frida,Android,Security,Hook,Code Injection,Frida,到目前为止,我正在努力学习,并尝试了一点。幸好我能找到足够的例子和教程来帮助我度过难关。 然而,此时此刻,我手头有一项非常具体的任务 让我们假设下面是我指的Frida钩子: Java.perform(function () { var Activity = Java.use("myPack.myClass"); Activity.methodM1.overload('[B', 'java.lang.String').implementation = function (a, str) {
Java.perform(function () {
var Activity = Java.use("myPack.myClass");
Activity.methodM1.overload('[B', 'java.lang.String').implementation = function (a, str) {
var retval = this.methodM1(a, str);
console.log("[*] return value4: "+retval);
return retval;
};
});
现在,根据我到目前为止的理解,对于上面的Java.use,我是说,无论何时生成myPackage.myClass的对象,并且如果该对象调用methodM1方法,则将控件改为我的javascript函数,并执行其中提到的任何操作
这项工作按预期进行。然而,(为了本次讨论的目的)重点是:如果制作了对象,那么就会发生这种情况
类似地,如果我们也讨论Java.choose(),而不是Java.use,情况也会一样。因此,即使在这种情况下,我们说如果对象被生成,那么调用我的回调
现在,如果我试图钩住一个抽象类的方法,那么会发生什么呢?假设我试图钩住这个方法
'静态getInstance(字符串)'
属于
java.security.KeyPairGenerator(是一个抽象类)
这个类是抽象的,它的对象从来没有真正被生成过。方法是静态的,直接使用类名本身调用它。因此,在这种情况下,Java.use()和Java.choose()都无法提供帮助(如果我以上的理解是正确的)
那么,在这种情况下,我该如何连接到getInstance()呢
以下是我已经尝试过的东西:
Java.perform(
function()
{
Java.enumerateLoadedClasses(
{
onMatch: function(className)
{
if(className == "java.security.KeyPairGenerator")
{
var item = Java.use(className);
console.log("the PrivateKey class was just loaded");
item.getInstance.overload('java.lang.String').implementation = function(str)
{
console.log("[*] This got called ");
var ret = item.getInstance(str);
console.log("[*] return value4: "+retval);
return retval;
}
}
},
onComplete:function(){}
});
}
);
但这是行不通的。同样,我在这里的假设是,无论何时创建对象并调用getInstance(),都要钩住它。但是在这里,KeyPairGenerator是一个抽象类,它本身从来没有真正被实例化过。我也尝试过:
className.getInstance()
而不是
item.getInstance()
这也不起作用 自Frida 10.1.2以来,早期的仪器工作得非常好,可以在您的案例中使用,以达到您的目标 我在我的设备(Huwaei P8 lite\w Android 6.0)上尝试了你的代码。我正在使用最新的Frida(10.1.4)。因此,使用Java.enumerateLoadedClass(在您的例子中)会使应用程序挂起,几秒钟后,frida崩溃
Error: abort was called
at u (frida/node_modules/frida-java/lib/android.js:512)
at p (java.js:2054)
at frida/node_modules/frida-java/index.js:105
at [anon] (repl1.js:28)
at frida/node_modules/frida-java/lib/vm.js:39
at y (frida/node_modules/frida-java/index.js:325)
at frida/node_modules/frida-java/index.js:305
at call (native)
at getPackageInfoNoCheck (Input:1)
[...]
工作解决方案是依靠Frida的早期仪器能力:
/*
Working code.
No need of Java.enumerateLoadedClasses
The following application https://github.com/obaro/SimpleKeystoreApp has been installed on the target device for testing.
Call the current javascript script like so:
frida -U -f com.sample.foo.simplekeystoreapp -l myscript.js --no-pause
*/
function monitorKPG2()
{
console.log("Starting early instrumentation test...");
Java.perform(function () {
var target = Java.use("java.security.KeyPairGenerator");
console.log("Target = " + target);
target.getInstance.overload("java.lang.String", "java.lang.String").implementation = function(alg, prov) {
console.log("getInstance " + alg);
this.getInstance(alg, prov);
};
});
}
console.log("Call me may be");
monitorKPG2();
除了@D4l3k给出的令人敬畏的答案外,如果有人使用旧版本的Frida(无论出于何种原因),比如我在10.0.5上使用的Frida,那么仍然可以使用以下方法实现早期检测: Java.performNow()而不是Java.perform() 下面是使用Java.performNow()的工作示例:
您是否尝试直接从Java.use(“Java.security.KeyPairGenerator”)钩住getInstance?我不知道这是否行得通。我的意思是,在某个时候,如果你看一下生成的smali代码,它会从KeyPairGenerator调用getInstance,对吗?是的,这正是我的思维过程。是的,我也试过。但不知何故,它不起作用。更新了问题以供参考。
Java.performNow(
function()
{
var item = Java.use("java.security.KeyPairGenerator");
console.log("the PrivateKey class was just loaded");
item.getInstance.overload('java.lang.String').implementation = function(str)
{
console.log("[*] This got called " + str);
var ret = this.getInstance(str);
console.log("[*] return value4: "+ret);
return ret;
}
}
);