Frida用法快查表

一、处理重载方法(Overloads Handling)

场景:区分同名但参数类型不同的方法(如 intString 输入的不同逻辑)
关键点:使用 .overload() 指定参数类型,或通过 .overloads 遍历所有版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var MyClass = Java.use('com.example.MyClass');
// 指定参数类型为 int 和 String 的重载方法
MyClass.myMethod.overload('int', 'java.lang.String').implementation = function(a, b) {
console.log(`参数: ${a}, ${b}`);
return this.myMethod(a, b); // 调用原始方法
};

// 遍历所有重载版本
MyClass.myMethod.overloads.forEach(overload => {
overload.implementation = function(...args) {
console.log(`重载方法调用,参数类型: ${args.map(arg => arg.type)}`);
return this.myMethod(...args);
};
});

二、构造函数 Hook(Constructor Hooking)

场景:篡改对象初始化参数(如绕过校验逻辑)
限制:避免直接 Hook Android 组件生命周期(如 Activity 实例化)

1
2
3
4
5
6
var Checker = Java.use('com.example.Checker');
Checker.$init.overload('int', 'int').implementation = function(a, b) {
console.log(`原始构造参数: ${a}, ${b}`);
// 强制修改构造参数
this.$init(1234, 4321); // 调用修改后的构造函数
};

三、动态实例操作(Dynamic Instance Manipulation)

场景:调用未主动触发的隐藏方法,或获取内存中对象数据(如解密密钥)
优势:直接操作运行时对象,无需依赖代码逻辑触发

1
2
3
4
5
6
7
8
9
Java.choose('com.example.MainActivity', {
onMatch: function(instance) {
console.log(`找到实例: ${instance}`);
instance.secretMethod(); // 调用隐藏方法
// 获取实例字段值
console.log(`私有字段值: ${instance.privateField.value}`);
},
onComplete: () => console.log('实例遍历完成')
});

四、Native 层 Hook(Native Function Interception)

场景:监控 C/C++ 原生函数(如文件操作、网络通信)
扩展:结合 Stalker 追踪代码执行路径

1
2
3
4
5
6
7
8
9
10
11
12
13
const openPtr = Module.findExportByName('libc.so', 'open'); // 定位原生函数地址
Interceptor.attach(openPtr, {
onEnter: function(args) {
// 读取 C 字符串参数
const filename = Memory.readUtf8String(args[0]);
console.log(`打开文件: ${filename}`);
// 修改参数(示例:拦截并返回特定文件描述符)
// args[0] = Memory.allocUtf8String('/dev/null');
},
onLeave: function(retval) { // retval 为原生函数返回值
console.log(`返回值(文件描述符): ${retval.toInt32()}`);
}
});

五、静态方法与全局变量操作(Static Methods & Variables)

注意:静态方法需正确匹配参数类型,避免因重载导致 Hook 失效

1
2
3
4
5
6
7
8
9
var MainActivity = Java.use('com.example.MainActivity');
// 修改静态变量(如全局配置项)
MainActivity.staticVar.value = 512; // 直接赋值

// 钩取静态方法
MainActivity.staticMethod.implementation = function() {
console.log('静态方法被 Hook');
return "Hijacked!"; // 替换返回值
};

六、批量 Hook 所有重载方法(Bulk Overload Hooking)

场景:快速覆盖混淆代码中的所有方法重载版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function hookAllOverloads(className, methodName) {
const clazz = Java.use(className);
clazz[methodName].overloads.forEach(overload => {
overload.implementation = function(...args) {
console.log(`[${methodName}] 调用参数: ${args}`);
// 可选:修改参数(如固定第一个参数为 0)
// args[0] = 0;
return this[methodName](...args); // 调用原始方法
};
});
}

// 使用示例:批量 Hook 所有重载的 `parse` 方法
hookAllOverloads('com.example.Parser', 'parse');

七、参数与返回值篡改(Argument & Return Value Manipulation)

技巧:结合 Frida Python 端 send() 实现动态策略调整

1
2
3
4
5
6
MyClass.check.implementation = function(a, b) {
// 修改输入参数(固定第二个参数为 100)
const result = this.check(a, 100);
// 反转校验结果(示例:通过校验时返回失败)
return result === 0 ? 1 : 0;
};

八、工具链扩展(Toolchain Integration)

1. Frida-trace 快速追踪

命令:追踪所有以 open 开头的原生函数,以及 Java 层 Socket 相关方法

1
frida-trace -U -i "open*" -j '*java.net.Socket*' com.example.app

2. 内存操作(Memory API)

场景:直接读写进程内存,绕过加密逻辑

1
2
3
4
// 读取指定地址的 4 字节整数
const value = Memory.readInt(ptr('0x7aabbcc0'));
// 写入字符串到内存(自动计算长度)
Memory.writeUtf8String(ptr('0x7aabbcc0'), 'hacked');

附:常用命令行参数

参数 说明
-U 通过 USB 连接设备(默认优先选择 USB 设备)
-f <包名> 启动指定应用并注入脚本(自动 attach)
-l <脚本.js> 加载指定 JavaScript 脚本
-D <设备ID> 连接指定 ID 的设备(多设备场景)