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;
    }
  }
);
Другие вопросы по тегам