1. 关键字搜索 'crack' 定位函数位置
2. 分析函数 查找调用位置
经测试只要 result = 0 即可破解弹窗
3. 分析汇编代码 寻找突破口
// hook_swift.js if (ObjC.available) { // 拦截 swift_dynamicCast 函数 Interceptor.attach(Module.findExportByName(null, 'swift_dynamicCast'), { onEnter: function(args){ console.log('onEnter'); var instance = args[0]; var targetType = args[1]; // 使用 Memory.readPointer 读取指针参数的值 var instanceValue = Memory.readPointer(instance); var targetValue = Memory.readPointer(targetType); console.log('instance 参数:', instanceValue); console.log('targetType 参数:', targetValue); }, onLeave: function (retval) { console.log('onLeave', retval); // 将返回值修改为 0 //retval.replace(ptr(0)); } }); } frida -U -f com.x1vpn.xiashijsq -l hook_swift.js
copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//sub_reg.js function get_func_addr(module, offset) { var base_addr = Module.findBaseAddress(module); var func_addr = base_addr.add(offset); if (Process.arch == 'arm') return func_addr.add(1); //如果是32位地址+1 else return func_addr; } if (ObjC.available) { var func_addr = get_func_addr('xiashiEasy', 0x000037320); Interceptor.attach(ptr(func_addr), { onEnter: function (args) { console.log("onEnter"); console.log("arg0=", args[0]); console.log("arg1=", args[1]); console.log("v0=", this.context.x0); console.log("v1=", this.context.x1); console.log("v2=", this.context.x2); console.log("v3=", this.context.x3); console.log("v4=", this.context.x4); console.log("v5=", this.context.x5); console.log("v6=", this.context.x6); console.log("v7=", this.context.x7); console.log("v8=", this.context.x8); console.log("v9=", this.context.x9); }, onLeave: function (retval) { console.log("onLeave", retval); retval.replace(0); //返回值替换成3 } }); }
copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// sub_patch.js function get_func_addr(module, offset) { var base_addr = Module.findBaseAddress(module); console.log('模块基址: ' + base_addr); // 一般以 cf fa ed fe 开头 表示 Match-o 应用程序 console.log(hexdump(ptr(base_addr), { length: 16, header: true, ansi: true })) var func_addr = base_addr.add(offset); if (Process.arch == 'arm') return func_addr.add(1); //如果是32位地址+1 else return func_addr; } if (ObjC.available) { // 可能需要去掉前面的 1 取决于 iDA 的 rebase 最好设为 0 即 0x00000000 var func_addr = get_func_addr('xiashiEasy', 0x37320); console.log('函数地址: ' + func_addr,'函数内部偏移地址: ' + func_addr.add(0xFC)); console.log(hexdump(ptr(func_addr.add(0xFC)), { length: 16, header: true, ansi: true })) // 修改成 汇编指令 MOV W0,#0 Memory.patchCode(func_addr.add(0xFC), 4, code => { var bytes = [0x00, 0x00, 0x80, 0x52]; code.writeByteArray(bytes); }); console.log('修改后:'); console.log(hexdump(ptr(func_addr.add(0xFC)), { length: 16, header: true, ansi: true })) }
copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41