alm
alm

Reputation: 101

Frida - Calling a specific method overload

I am exploring an Android program that has several methods with the same names and parameters.

I need to call a specific method overload. Java code like this

package a;
public class d
{
     public int a() {
        return 10;
    }

    public long a() {
        return 20;
    }
    public long b() {
        long ret = a();
        return ret + 1;
    }
}

I need replace implementation of b() and call (int)a() instead of (long)a(). Please help me fix my frida js code.

Java.perform(function () {
  Var Class_A_D = java.Use("a.d");
  Class_A_D.b.implementation = function(){
    var ret = this.(a); // need to call int implementation
    return ret;
 }
}

Upvotes: 2

Views: 9136

Answers (2)

alm
alm

Reputation: 101

I found the answer with Java.reflect

Java.perform(function () {
    var Java_lang_Object = Java.use('java.lang.Object');
    var Java_lang_String = Java.use('java.lang.String');
//This function get method reference by reflect
        function dynamic_search_method(io_object, iv_name, iv_ret_type, it_par){ 
          var lt_methods = io_object.getMethods()  ;
          var lv_found;
          for(var  lv_i=0;lv_i < lt_methods.length;lv_i++){
             if(lt_methods[lv_i].getName().toString()  == iv_name && lt_methods[lv_i].getGenericReturnType().toString() == iv_ret_type){
                var lt_par_type = lt_methods[lv_i].getParameterTypes();
                if(lt_par_type.length == it_par.length){
                  lv_found = true; 
                  for(var  lv_j=0;lv_j < lt_par_type.length && lv_found == true;lv_j++){
                    if(lt_par_type[lv_j].getName().toString() != it_par[lv_j]) lv_found = false  ; 
                  }                   
                  if(lv_found == true) return lt_methods[lv_i];
                }
             }
          }
         return null;
        }
//This function call method dynamically 
        function dynamic_invoke(io_object,io_method, it_par){
          if(io_object===null || io_method ===null ) return null;
          try{
            var lo_cast_obj = Java.cast( io_object ,Java_lang_Object);
          }catch(e){
            return null;
          }
          var lt_par = Java.array('java.lang.Object',it_par);
          return io_method.invoke(lo_cast_obj,lt_par);
        }
//example of use
  Var Class_A_D = java.Use("a.d");


  Class_A_D.b.implementation = function(){
// call method "a" of instance, with "long" return and without parameter
var lo_meth = dynamic_search_method(this.getClass(),"a","long",[]);
var lv_var= dynamic_invoke(this,lo_meth,[]);

// call method "c" of instance, with "android.content.Context" return and with 2 parameters
lo_meth = dynamic_search_method(this.getClass(),"a","class android.content.Context",['java.lang.String','java.lang.String']);
var lv_var= dynamic_invoke(this,lo_meth,[Java_lang_String.$new("Test"),Java_lang_String.$new("String")]);
// call static method
var lo_meth = dynamic_search_method(Class_A_D.class,"d","class java.lang.String",[]);
var lv_var= dynamic_invoke(Class_A_D.class,lo_meth,[]);    
};

)};

Upvotes: 3

Beto Rodriguez
Beto Rodriguez

Reputation: 124

The code in class d is violating the method signature principle which is defined by the method name and each parameter type.

Because the method type is not part of the signature Java reads these methods as the same: public int a() {...} public long a(){...}

both signatures are "a()"

You should rename those methods to have different names ( or to have input parameters of different types )

More info here : https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html

Upvotes: -1

Related Questions