一、处理重载方法(Overloads Handling)
场景:区分同名但参数类型不同的方法(如 int 和 String 输入的不同逻辑)
关键点:使用 .overload() 指定参数类型,或通过 .overloads 遍历所有版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var MyClass = Java.use('com.example.MyClass');
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) { const filename = Memory.readUtf8String(args[0]); console.log(`打开文件: ${filename}`); }, onLeave: function(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}`); return this[methodName](...args); }; }); }
hookAllOverloads('com.example.Parser', 'parse');
|
七、参数与返回值篡改(Argument & Return Value Manipulation)
技巧:结合 Frida Python 端 send() 实现动态策略调整
1 2 3 4 5 6
| MyClass.check.implementation = function(a, b) { const result = this.check(a, 100); return result === 0 ? 1 : 0; };
|
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
| const value = Memory.readInt(ptr('0x7aabbcc0'));
Memory.writeUtf8String(ptr('0x7aabbcc0'), 'hacked');
|
附:常用命令行参数
| 参数 |
说明 |
-U |
通过 USB 连接设备(默认优先选择 USB 设备) |
-f <包名> |
启动指定应用并注入脚本(自动 attach) |
-l <脚本.js> |
加载指定 JavaScript 脚本 |
-D <设备ID> |
连接指定 ID 的设备(多设备场景) |