Android使用Frida

时间:2017-07-02 10:48:02

标签: android security hook code-injection 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的Object并且该对象调用方法 methodM1 时,获取控件改为我的javascript函数,并做那里提到的任何事情。

这项工作符合预期。然而,关键点(为了讨论而感兴趣)是: IF 对象生成然后会发生这种情况。

同样地,如果我们也在讨论Java.choose(),那么代替Java.use,情况就是这样。所以即使在这种情况下,我们也会说如果对象被创建,那么就调用我的回调。

现在,如果我试图挂钩到抽象类的方法会发生什么所以让我说我试图挂钩到方法

  

'static getInstance(String)'   的   java.security.KeyPairGenerator(这是一个抽象类)。

这个类是 abstract ,它的对象永远不会真正被制作出来。并且方法是 static ,它是使用类名本身直接调用的。所以在这种情况下, 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(){}
    });
  }
);

但这不起作用。同样,我的假设是每当Object被生成并且getInstance()被调用时,挂钩它。但是在这里, KeyPairGenerator 是一个抽象类,它从来没有真正在第一个地方实例化。我也尝试过:

  

className.getInstance()

而不是

  

item.getInstance()

这也不起作用。

2 个答案:

答案 0 :(得分:2)

自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();

答案 1 :(得分:0)

除了@ 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;
    }
  }
);