前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >frida反射调用对象中的方法与字段

frida反射调用对象中的方法与字段

作者头像
用户4682003
发布2022-05-19 14:34:45
3.9K0
发布2022-05-19 14:34:45
举报
文章被收录于专栏:网络安全技术点滴分享

该篇文章主要介绍当我们碰到参数或者返回值是一个对象时,如何通过frida反射调用该对象的方法(methods)与获取该对象的字段(fields)

添加测试frida反射调用的demo app

写一个测试类,其中包含字段(fields)int类型的count、String类型的plainText

及多个简单方法。其中display方法参数为ParametersTest对象

在文中,我们要hook display方法并hook它的参数ParametersTest对象反射调用ParametersTest对象的所有方法及打印parametersTest的所有字段

代码语言:javascript
复制
public class ParametersTest {

    private final int count = 523;//字段count
    private final String plainText = "this is a test";//字段plainText

    public int multiply(int val1,int val2){
        return val1 * val2;
    }

    public byte multiply(byte val1,byte val2){
        return (byte)(val1 * val2);
    }

    public short multiply(short val1,short val2){
        return (short)(val1 * val2);
    }

    public long multiply(long val1,long val2){
        return val1 * val2;
    }

    public float multiply(float val1,float val2){
        return val1 * val2;
    }

    public double multiply(double val1,double val2){
        return val1 * val2;
    }

    public String addMethod(String str1,String str2){
        return str1 + str2;
    }

    public void addMethod(int[] initArray){
        for(int i = 0; i < initArray.length;i++){
            initArray[i] = initArray[i] + 1;
        }
    }

    public void addMethod(byte[] byteArray){
        for(int i = 0; i < byteArray.length;i++){
            byteArray[i] = (byte)(byteArray[i] + 1);
        }
    }

    public void addMethod(long[] longArray){
        for(int i = 0; i < longArray.length; i++){
            longArray[i] = longArray[i] + 1;
        }
    }

    public void addMethod(float[] floatArray){
        for(int i = 0; i < floatArray.length; i++){
            floatArray[i] = floatArray[i] + 1;
        }
    }

    public void addMethod(double[] doubleArray){
        for(int i = 0; i < doubleArray.length; i++){
            doubleArray[i] = doubleArray[i] + 1;
        }
    }

    public void addMethod(String[] strArray){
        String result = "";
        for(int i = 0; i < strArray.length; i++){
            result = result + strArray[i];
        }
    }
    //display方法参数为ParametersTest对象
    public void display(ParametersTest parametersTest){
        int[] intArray = {1,2,3,4,5};
        parametersTest.addMethod(intArray);

        byte[] byteArray = {0x10,0x11,0x12,0x13};
        parametersTest.addMethod(byteArray);

        long[] longArray = {0x1,0x2,0x3,0x4};
        parametersTest.addMethod(longArray);

        String[] strArray = {"abcde","1222CDedd","12daer","cder"};
        parametersTest.addMethod(strArray);

        float[] floatArray = {0x1,0x2,0x3,0x4};
        parametersTest.addMethod(floatArray);

        double[] doubleArray = {0x1,0x2,0x3,0x4};
        parametersTest.addMethod(doubleArray);

        String str1 = "acerwe";
        String str2 = "werwed";
        parametersTest.addMethod(str1,str2);

        int intVal1 = 3;
        int intVal2 = 4;
        int retInt = parametersTest.multiply(intVal1,intVal2);

        byte byteVal1 = 0x1;
        byte byteVal2 = 0x2;
        byte retByte = parametersTest.multiply(byteVal1,byteVal2);

        long longVal1 = 0x3;
        long longVal2 = 0x4;
        long retLong = parametersTest.multiply(longVal1,longVal2);

        float floatVal1 = 0x3;
        float floatVal2 = 0x4;
        float retFloat = parametersTest.multiply(floatVal1,floatVal2);

        short shortVal1 = 0x3;
        short shortVal2 = 0x4;
        short retShort = parametersTest.multiply(shortVal1,shortVal2);

        double doubleVal1 = 0x3;
        double doubleVal2 = 0x4;
        double retDouble = parametersTest.multiply(doubleVal1,doubleVal2);
    }

}

frida反射调用打印字段(fields)类型、名称、值

代码语言:javascript
复制

//hook display方法
parametersTestClass.display.overload("com.example.parameterstest.ParametersTest").implementation = function (val1) {
  getReflectFields(val1);//打印所有字段(fields)类型、名称、值
  getReflectMethod(val1)//hook ParametersTest对象的所有方法
  this.display(val1);//调用display方法
}
代码语言:javascript
复制

function getReflectFields(val1) {
  var clazz = Java.use("java.lang.Class");
  var parametersTest = Java.cast(val1.getClass(),clazz);
  //getDeclaredFields()获取所有字段
  var fields = parametersTest.getDeclaredFields();
  fields.forEach(function (field) {//依次打印字段的类型、名称、值
    send("field type is: " + (field.getType()));
    send("field name is: " + (field.getName()));
    send("field value is: " + field.get(val1));
  })
}

结果如下:

frida反射调用类中的方法

代码语言:javascript
复制

function getReflectMethod(val1) {
  try{
    var clazz = Java.use("java.lang.Class");
    var parametersTest = Java.cast(val1.getClass(),clazz);
    //getDeclaredMethods()获取所有方法
    var methods = parametersTest.getDeclaredMethods();
      methods.forEach(function (method) {
        var methodName = method.getName();
        var val1Class = val1.getClass();
        var val1ClassName = Java.use(val1Class.getName());
        var overloads = val1ClassName[methodName].overloads;
        overloads.forEach(function (overload) {
          var proto = "(";
          overload.argumentTypes.forEach(function (type) {
            proto += type.className + ", ";
          });
          if(proto.length > 1){
            proto = proto.substr(0 ,proto.length - 2);
          }
          proto += ")";
          overload.implementation = function () {
            var args = [];
            for(var j = 0; j < arguments.length; j++){
              for(var i in arguments[j]){
                var value = String(arguments[j][i]);
                send(val1ClassName + "." + methodName + " and arguments value is: " + value);
              }
              args[j] = arguments[j] + "";
            }
            //打印方法参数
            send(val1ClassName + "." + methodName + " and args is: " + args);
            //调用方法
            var retval = this[methodName].apply(this,arguments);
            //打印方法返回值
            send(methodName + " return value is: " + retval);
            return retval;//返回方法返回值
          }
        })
      })

    }catch(e){
      send("'" + val1 + "' hook fail: " + e);
    }
  }
  

结果如下

  1. 完整测试代码可以在公众号回复“frida reflect”通过百度云下载(包含测试demo、frida脚本)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 网络安全技术点滴分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档