Android 使用 Frida 挂钩抽象 class 方法调用
Android hooking of abstract class method calls using Frida
我正在努力学习 Frida 并且到目前为止已经进行了一些试验。谢天谢地,事情大部分都奏效了,我可以找到足够的示例和教程来帮助我完成。
但是,此时此刻,我手头有一项非常具体的任务。
所以让我们说下面是我指的 Frida 钩子:
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,情况会是一样的。所以即使在那种情况下,我们也会说如果对象被创建,然后调用我的回调。
现在,如果我尝试连接到抽象方法中会发生什么情况 class 所以假设我正在尝试连接到方法中
'static getInstance(String)'
of
java.security.KeyPairGenerator (which is an abstract class).
这个 class 是 抽象的 ,它的对象从来没有真正被制造出来。并且该方法是 static,直接使用 class 名称本身调用。所以在这种情况下,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 是一个抽象 class,它本身从来没有真正实例化过。我也试过了:
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,仍然可以使用以下方式实现早期检测:
Java.performNow() 而不是 Java.perform()
下面是使用 Java.performNow() 的工作示例:
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;
}
}
);
我正在努力学习 Frida 并且到目前为止已经进行了一些试验。谢天谢地,事情大部分都奏效了,我可以找到足够的示例和教程来帮助我完成。 但是,此时此刻,我手头有一项非常具体的任务。
所以让我们说下面是我指的 Frida 钩子:
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,情况会是一样的。所以即使在那种情况下,我们也会说如果对象被创建,然后调用我的回调。
现在,如果我尝试连接到抽象方法中会发生什么情况 class 所以假设我正在尝试连接到方法中
'static getInstance(String)' of java.security.KeyPairGenerator (which is an abstract class).
这个 class 是 抽象的 ,它的对象从来没有真正被制造出来。并且该方法是 static,直接使用 class 名称本身调用。所以在这种情况下,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 是一个抽象 class,它本身从来没有真正实例化过。我也试过了:
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,仍然可以使用以下方式实现早期检测: Java.performNow() 而不是 Java.perform()
下面是使用 Java.performNow() 的工作示例:
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;
}
}
);