Frida - 调用特定方法重载
Frida - Calling a specific method overload
我正在探索一个 Android 程序,该程序具有多个具有相同名称和参数的方法。
我需要调用特定的方法重载。
Java 这样的代码
package a;
public class d
{
public int a() {
return 10;
}
public long a() {
return 20;
}
public long b() {
long ret = a();
return ret + 1;
}
}
我需要替换 b() 的实现并调用 (int)a() 而不是 (long)a()。
请帮我修复我的 frida js 代码。
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;
}
}
classd中的代码违反了由方法名和每个参数类型定义的方法签名原则。
因为方法类型不是签名的一部分 Java 读取这些方法是相同的:
public int a() {...}
public 长 a(){...}
两个签名都是"a()"
您应该重命名这些方法以具有不同的名称(或具有不同类型的输入参数)
更多信息在这里:https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
我找到了 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,[]);
};
)};
我正在探索一个 Android 程序,该程序具有多个具有相同名称和参数的方法。
我需要调用特定的方法重载。 Java 这样的代码
package a;
public class d
{
public int a() {
return 10;
}
public long a() {
return 20;
}
public long b() {
long ret = a();
return ret + 1;
}
}
我需要替换 b() 的实现并调用 (int)a() 而不是 (long)a()。 请帮我修复我的 frida js 代码。
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;
}
}
classd中的代码违反了由方法名和每个参数类型定义的方法签名原则。
因为方法类型不是签名的一部分 Java 读取这些方法是相同的: public int a() {...} public 长 a(){...}
两个签名都是"a()"
您应该重命名这些方法以具有不同的名称(或具有不同类型的输入参数)
更多信息在这里:https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
我找到了 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,[]);
};
)};