Java.perform(function(){console.log("[*] Start Hook SignUtils.generateSign");varSignUtils=Java.use("com.example.SignUtils");SignUtils.generateSign.implementation=function(params){console.log("\n[*] generateSign is called!");console.log(" InputParameter:");// Print HashMap
variterator=params.entrySet().iterator();while(iterator.hasNext()){varentry=iterator.next();console.log(" "+entry.getKey()+" = "+entry.getValue());}// Call original function
varresult=this.generateSign(params);console.log(" ReturnValue: "+result);console.log("");returnresult;};console.log("[*] Hook install completed");});
运行结果示例:
1
2
3
4
5
6
[*] generateSign is called!
InputParameter:
user = test123
timestamp = 1701234567
action = login
ReturnValue: a1b2c3d4e5f6g7h8i9j0
第 2 步:处理重载方法(10 分钟)
2.1 列出所有重载
1
2
3
4
5
6
7
8
9
Java.perform(function(){varCryptoUtil=Java.use("com.example.CryptoUtil");// List all encryption methods
console.log("[*] encrypt Method overloads:");CryptoUtil.encrypt.overloads.forEach(function(overload){console.log(" "+overload);});});
Java.perform(function(){varCryptoUtil=Java.use("com.example.CryptoUtil");// Hook the second overloaded version
CryptoUtil.encrypt.overload("java.lang.String","java.lang.String").implementation=function(data,key){console.log("[*] encrypt(String, String) is called");console.log(" Data:",data);console.log(" Key:",key);varresult=this.encrypt(data,key);console.log(" Result:",result);returnresult;};// Hook the third overloaded version
CryptoUtil.encrypt.overload("[B").implementation=function(bytes){console.log("[*] encrypt(byte[]) is called");console.log(" BytesLength:",bytes.length);varresult=this.encrypt(bytes);console.log(" ResultLength:",result.length);returnresult;};});
第 3 步:主动调用函数(15 分钟)
3.1 创建新实例
1
2
3
4
5
6
7
8
9
10
11
12
Java.perform(function(){varCryptoUtil=Java.use("com.example.CryptoUtil");// Constructor accessible
try{varinstance=CryptoUtil.$new();// Call no-arg constructor
varresult=instance.encrypt("Hello World","mykey");console.log("[*] MainCallResult:",result);}catch(e){console.log("[-] No way to create instance:",e);}});
Java.perform(function(){varRootDetector=Java.use("com.example.security.RootDetector");RootDetector.isRooted.implementation=function(){console.log("[*] Root Detection is Bypassed");returnfalse;// Force return false (not rooted)
};RootDetector.isXposedInstalled.implementation=function(){console.log("[*] Xposed Detection is Bypassed");returnfalse;};});
// Stalker trace function execution
Interceptor.attach(Module.findExportByName("libnative.so","Java_com_example_Native_encrypt"),{onEnter:function(args){console.log("[*] Start Tracking...");Stalker.follow(Process.getCurrentThreadId(),{events:{call:true,// Record Function Calls
ret:false,exec:false,},onReceive:function(events){console.log("[*] Captured",events.length,"events");// Parse events
varcalls=Stalker.parse(events,{annotate:true,stringify:false,});calls.forEach(function(call){console.log(" Call:",call);});},});},onLeave:function(retval){Stalker.unfollow(Process.getCurrentThreadId());Stalker.flush();console.log("[*] Tracking Ended");},});
7.2 只追踪特定模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
varbase=Module.findBaseAddress("libnative.so");varsize=Process.findModuleByName("libnative.so").size;Stalker.follow(Process.getCurrentThreadId(),{transform:function(iterator){varinstruction=iterator.next();do{// Only record instructions within libnative.so
if(instruction.address.compare(base)>=0&&instruction.address.compare(base.add(size))<0){iterator.keep();}instruction=iterator.next();}while(instruction!==null);},});
工具对比总结
工具
最佳场景
优点
缺点
Frida Hook
快速获取 I/O
不中断流程
只看单点
修改返回值
易于自动化
不知道细节
调试器
理解算法逻辑
完全控制
速度慢
(IDA/GDB)
单步跟踪
看所有变量
需要手动操作
Stalker
代码覆盖率
全自动
性能开销大
追踪执行路径
无需断点
输出量巨大
RPC 调用流程
1
2
3
4
5
6
7
8
9
10
11
12
Python 脚本 Frida 脚本
| |
| Send RPC Request |
| ---------------------------> |
| | Execute Java.perform()
| |
| | Call App Function
| |
| <--------------------------- |
| Receive Return Value | Return Result
| |
| Process Data | Completed
常见问题
问题 1: Hook 没有触发
检查清单:
确认类/方法名正确
1
2
3
4
5
6
7
8
9
// List all classes
Java.enumerateLoadedClasses({onMatch:function(className){if(className.includes("SignUtils")){console.log(className);}},onComplete:function(){},});
确认方法被调用
在 App 中触发相关操作
检查是否有其他代码路径
检查混淆
1
2
// If class name is obfuscated as a.b.c, use obfuscated name
varSignUtils=Java.use("a.b.c");
问题 2: RPC 调用超时
症状:script.exports_sync.func() 一直等待
解决:
1
2
3
4
5
6
7
8
9
10
11
# Use async calldefon_rpc_message(result,error):iferror:print(f"[-] Error: {error}")else:print(f"[+] Result: {result}")script.exports.func(params,on_rpc_message)# Or add timeoutresult=script.exports_sync.func(params,timeout=10)