在 Frida Android 上,如果想先修改某个类的方法1内部调用的方法2,然后再启动方法1,通常用 Java.use 或 Interceptor.attach 进行 Hook。
Java.use()
👉 获取类并调用方法choose()
👉 查找已创建的实例并调用方法overload()
👉 精确调用特定参数的方法Java.cast()
👉 转换choose()
选中的对象并调用方法
implementation
会完全替换方法的所有代码,相当于删掉原来的方法逻辑,然后用 Frida 代码重新写一个新的方法。
o=java.use--->o.方法2.重写--->调用方法2--->实例java.use--->触发方法1
模拟1(不带参)
靶场
package com.example.fridaapp;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonInvoke = findViewById(R.id.buttonInvoke);
buttonInvoke.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ClassA classA = new ClassA();
classA.method1();
}
});
}
}
package com.example.fridaapp;
public class ClassA {
public void method1() {
System.out.println("A方法被调用");
ClassB classB = new ClassB();
classB.method2();
}
}
package com.example.fridaapp;
public class ClassB {
public void method2() {
System.out.println("B方法被调用");
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<!-- 可以在这里添加UI元素 -->
<Button
android:id="@+id/buttonInvoke"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Invoke Method"
android:layout_gravity="center" />
</LinearLayout>
Frida(choose能主动调用方法)
Java.perform(function() {
console.log("[+] 开始Hook方法...");
// Hook ClassA
var ClassA = Java.use("com.example.fridaapp.ClassA");
// Hook ClassB
var ClassB = Java.use("com.example.fridaapp.ClassB");
ClassB.method2.implementation = function() {
console.log("[+] ClassB.method2 被调用");
};
// 主动调用方法(可选)
Java.choose("com.example.fridaapp.MainActivity", {
onMatch: function(instance) {
// 创建并调用ClassA
var classA = ClassA.$new();
classA.method1();
},
onComplete: function() {
console.log("[*] MainActivity实例搜索完成");
}
});
});
结果(不用点击按钮,也能直接调用按钮的结果)
[+] 开始Hook方法...
[+] ClassB.method2 被调用
[*] MainActivity实例搜索完成
[MI 8 SE::fridaapp ]->
模拟2(带参)
靶场
package com.example.fridaapp;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private EditText inputNumber;
private TextView resultText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inputNumber = findViewById(R.id.inputNumber);
resultText = findViewById(R.id.resultText);
Button buttonInvoke = findViewById(R.id.buttonInvoke);
buttonInvoke.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
int number = Integer.parseInt(inputNumber.getText().toString());
ClassA classA = new ClassA();
int result = classA.method1(number);
resultText.setText("计算结果: " + result);
} catch (NumberFormatException e) {
resultText.setText("请输入有效的数字");
}
}
});
}
}
package com.example.fridaapp;
public class ClassA {
public int method1(int num) {
System.out.println("A方法被调用,参数: " + num);
ClassB classB = new ClassB();
int result = classB.method2(num);
return result + 10; // 在B方法的结果上加10
}
}
package com.example.fridaapp;
public class ClassB {
public int method2(int num) {
System.out.println("B方法被调用,参数: " + num);
return num * 2; // 将输入值乘以2
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
android:gravity="center">
<EditText
android:id="@+id/inputNumber"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="请输入数字"
android:inputType="number"
android:layout_marginBottom="16dp"/>
<Button
android:id="@+id/buttonInvoke"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="计算"
android:layout_marginBottom="16dp"/>
<TextView
android:id="@+id/resultText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="结果将显示在这里"/>
</LinearLayout>
Frida
Java.perform(function() {
// Hook ClassA
var ClassA = Java.use("com.example.fridaapp.ClassA");
ClassA.method1.implementation = function(num) {
console.log("A输入参数: " + num);
var result = this.method1(num); //先执行原来的方法1,输出的结果
console.log("A原始返回值: " + result);
var modifiedResult = result * 2; // 将结果再乘以2
console.log("A修改后返回值: " + modifiedResult);
return modifiedResult; //返回给主代码里面
};
// Hook ClassB
var ClassB = Java.use("com.example.fridaapp.ClassB");
ClassB.method2.implementation = function(num) {
console.log("B输入参数: " + num);
var result = num * 3; // 原来是乘以2,现在改成乘以3
console.log("B修改后的计算结果: " + result);
return result;
};
// Hook Button点击事件(可选)
Java.choose("com.example.fridaapp.MainActivity", {
onMatch: function(instance) {
console.log("[+] 找到MainActivity实例");
var classA = ClassA.$new();
classA.method1(11);
},
onComplete: function() {}
});
});
/*
A输入参数: 2
B输入参数: 2
B修改后的计算结果: 6 (2*3=6)
A原始返回值: 16 (6+10=16)
A修改后返回值: 32 (16*2=32)
*/
结果(不用点击按钮,也能直接调用按钮的结果)
[+] 找到MainActivity实例
A输入参数: 11
B输入参数: 11
B修改后的计算结果: 33
A原始返回值: 43
A修改后返回值: 86
[MI 8 SE::fridaapp ]-> A输入参数: 11
B输入参数: 11
B修改后的计算结果: 33
A原始返回值: 43
A修改后返回值: 86
模拟3(跳过加密)
靶场
package com.example.fridaapp;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private EditText inputNumber;
private TextView resultText;
private ClassB classB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inputNumber &#