Android-перехват вызовов абстрактного класса с использованием 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.use, если бы мы говорили и о Java.choose(), ситуация была бы такой же. Таким образом, даже в этом случае мы говорим, что если объект создан, а затем вызвать мой обратный вызов.
Теперь, что произойдет, если я попытаюсь подключиться к методу абстрактного класса Итак, скажем, я пытаюсь подключиться к методу
"static getInstance(String)" из 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()
и это тоже не работает.
2 ответа
Начиная с Frida 10.1.2, ранние инструменты работают довольно хорошо и могут использоваться в вашем случае для достижения вашей цели.
Я попробовал ваш код на моем устройстве (Huwaei P8 lite \w Android 6.0). Я использую последнюю Фриду (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.Выполните ()
Ниже приведен рабочий пример с использованием 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;
}
}
);