-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathnetcore-bcc-trace.py
83 lines (67 loc) · 2.47 KB
/
netcore-bcc-trace.py
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
#!/usr/bin/python
from bcc import BPF
import argparse
parser = argparse.ArgumentParser('netcore-bcc-trace')
parser.add_argument('nativeImagePath', help='Full path to the native netcore image to trace.', type=str)
parser.add_argument('methodOffset', help='The offset of the method to trace.', type=lambda x: int(x,0))
parser.add_argument('type', help='The type of parameter or return value.', choices=['int', 'str'], type=str)
parser.add_argument('--len', help='The max length to print for string types.', default=50)
parser.add_argument('--ret', help='Pass this flag if you want to trace a return value instead of a parameter.', default=False, action='store_true')
args = parser.parse_args()
def generateBPF(type, maxLength, isReturn):
bpf="""
#include <uapi/linux/ptrace.h>
int trace(struct pt_regs *ctx) {
if (!PT_REGS_PARM1(ctx) ) {
bpf_trace_printk("arg error\\n");
return 0;
}
"""
if type == 'int':
if isReturn:
bpf += 'bpf_trace_printk("val %d\\n", PT_REGS_RC(ctx));'
else:
bpf += 'bpf_trace_printk("val %d\\n", PT_REGS_PARM2(ctx));'
elif type == 'str':
# print a string up to maxLength characters
if isReturn:
bpf += 'void *str = (void *)PT_REGS_RC(ctx);'
else:
bpf += 'void *str = (void *)PT_REGS_PARM2(ctx);'
bpf += """
if( !str ) {
bpf_trace_printk("null pointer\\n");
return 0;
}
int len;
bpf_probe_read(&len, sizeof(len), (void *)(str + 8));
"""
# create a large enough char buff
bpf += """
char buf[%d];
bpf_probe_read(buf, %d * sizeof(char), (void *)(str + 11));
""" % (maxLength * 2, maxLength * 2)
pos = 0
while pos < maxLength:
bpf += """
buf[%d] = buf[%d];
""" % (pos, pos * 2 + 1)
pos += 1
bpf += """
bpf_trace_printk("len %d : %s \\n", len, buf);
"""
bpf += """
return 0;
}
"""
return bpf
bpf = generateBPF(args.type, args.len, args.ret)
b = BPF(text=bpf)
print('Begin tracing. Hit Ctrl+C to exit.')
try:
if args.ret:
b.attach_uretprobe(name=args.nativeImagePath, addr=args.methodOffset, fn_name="trace").trace_print()
else:
b.attach_uprobe(name=args.nativeImagePath, addr=args.methodOffset, fn_name="trace").trace_print()
except KeyboardInterrupt:
print('Exiting...')