frida-stalker-trace 使用并实战某音

我们自己写了一个app, 现在对这个app进行trace

先看看so名

1
cat /proc/$(pidof com.zj.my_md5 )/maps | grep checkout

img_1.png

这是一个 64位的so. 名为 libcheckout.so

ida 打开看看目标so

img_1.png

现在就使用 stalker 对这个函数进行trace

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function hook_native_stalker(){


var so_addr = Module.findBaseAddress("libcheckout.so");
if (so_addr)
{
console.log("so_addr:", so_addr);
var addr_13F91 = so_addr.add(0x1E658);
console.log("The addr_13F91:", addr_13F91);
var stalker_hook = false;
Interceptor.attach(addr_13F91,
{
onEnter: function (args) {
console.warn(JSON.stringify({
// fname: args[1].readCString(),
// text: new ObjC.Object(args[2]).toString(),
backtrace: Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).map(m => m.moduleName+'!'+m.name),
ctx: this.context
}, null, 2));
var tid = Process.getCurrentThreadId();
this.tid = tid;
Stalker.follow(tid, {
events: {
call: true
},
/*
onCallSummary: function (summary) {
Object.keys(summary).forEach(s => {
var sym = DebugSymbol.fromAddress(ptr(s));
if (sym.moduleName == 'Viber')
console.log(summary[s], sym.name);
})
}
*/
transform: function (iterator) {
var instruction;
while ((instruction = iterator.next()) !== null) {
iterator.keep();
if (instruction.mnemonic.startsWith('bl')) {
try {
console.log('#' + tid + ':' + DebugSymbol.fromAddress(ptr(instruction.operands[0].value)));
} catch (e) {
// ignoring branch&link to register
}
}
}
}
});
},
onLeave: function (retval) {
Stalker.unfollow(this.tid);
Stalker.garbageCollect();
console.log("=====================================================")

}


})

}

}

hook_native_stalker()

遇到bl指令 就打印调用地址.

结果如下

img_1.png

可以看到 0x43690 这个函数被调用。

ida看一下这个地址 正是关键函数.

img_1.png

使用frida stalker trace 一下某视频看看

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

function hook_native_stalker_dy(){

var so_name = "libmetaxxx.so"
var so_addr = Module.findBaseAddress(so_name);
var so_size = Process.getModuleByName(so_name).size;

if (so_addr)
{
console.log("so_addr:", so_addr);
// var hook_addr = so_addr.add(0xc167c);
var hook_addr = so_addr.add(0xbe040);
console.log("The addr_13F91:", hook_addr);

var stalker_hook = false;

var pre_regs = {}

Interceptor.attach(hook_addr,
{
onEnter: function (args) {
console.warn(JSON.stringify({
// fname: args[1].readCString(),
// text: new ObjC.Object(args[2]).toString(),
backtrace: Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).map(m => m.moduleName+'!'+m.name),
ctx: this.context
}, null, 2));
var tid = Process.getCurrentThreadId();
this.tid = tid;
Stalker.follow(tid, {
events: {
call: true
},
/*
onCallSummary: function (summary) {
Object.keys(summary).forEach(s => {
var sym = DebugSymbol.fromAddress(ptr(s));
if (sym.moduleName == 'Viber')
console.log(summary[s], sym.name);
})
}
*/
transform: function (iterator) {
var instruction = iterator.next();
const startAddress = instruction.address;
if (startAddress){
var isModule = startAddress.compare(so_addr.add(0xbe040)) >= 0 && startAddress.compare(so_addr.add(so_size)) < 0;
do{
if (isModule){
if (instruction.mnemonic.startsWith('bl')) {
// var uuid = getUuid()
// console.log("uuid 1", uuid)
try {

iterator.putCallout(function (context) {
var pc = context.pc; //获取pc寄存器,当前地址
var lr = context.lr; //获取pc寄存器,当前地址
var x0 = context.x0; //获取pc寄存器,当前地址
var module = Process.findModuleByAddress(pc);
if (module) {
//如果模块存在
// var diff_regs = get_diff_regs(context, pre_regs);

// console.log(module.name + "!" + ptr(pc).sub(module.base),
// Instruction.parse(ptr(pc)),
// // JSON.stringify(diff_regs)
// );
try{
console.log(Memory.readCString(ptr(x0)))
}
catch (e){

}

console.log("pc ====" + DebugSymbol.fromAddress(ptr(pc)))
// console.log("lr ====" + DebugSymbol.fromAddress(ptr(lr)))

}
});

// console.log('#' + tid + ':' + DebugSymbol.fromAddress(ptr(instruction.operands[0].value)));

// console.log(instruction.toString())
// console.log(context)
} catch (e) {
console.log("error", e)
// ignoring branch&link to register
}
}
}
iterator.keep();
} while ((instruction = iterator.next()) !== null);
}
},


});
},
onLeave: function (retval) {
Stalker.unfollow(this.tid);
Stalker.garbageCollect();
console.log("=====================================================")

}


})

}

}

每次执行bl指令时, 就打印当前pc, 并且尝试打印 cstring, x0

trace 结果如下

img_1.png

可以看到 核心算法结果已经出来了, 剩下得就是分析了.