-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpincher
executable file
·118 lines (87 loc) · 3.59 KB
/
pincher
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
112
113
114
115
116
117
118
#!/usr/bin/env python3
import argparse
import subprocess
import os
import re
filepath = os.path.dirname(os.path.realpath(__file__))
FLOATING_POINT_REGS = {"st0", "st1", "st2", "st3", "st4", "st5", "st6",
"st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"}
def fix_bpx(arg):
set_regex = r"set\(([a-zA-Z0-9]+),\ *([0-9a-fA-FxX]+)\)"
set_fp_regex = r"set\(([a-zA-Z0-9]+),\ *([0-9]+\.[0-9]+)\)"
dmp_reg_regex = r"dump\(([a-zA-Z0-9]+),\ *([0-9a-fA-FxX]+)\)"
set_matches = re.findall(set_regex, arg)
set_fp_matches = re.findall(set_fp_regex, arg)
dmp_reg_matches = re.findall(dmp_reg_regex, arg)
if (set([x[0] for x in set_fp_matches]) - FLOATING_POINT_REGS != set()):
not_valid_regs = set([x[0]
for x in set_fp_matches]) - FLOATING_POINT_REGS
print(not_valid_regs, "are not valid floating point registers")
exit(1)
address = arg.split(",")[0]
other_args = ','.join([x for x in arg.split(",") if ":" in x])
if other_args:
res = address + "," + other_args
else:
res = address
regs = '-'.join([x[0].lower() for x in set_matches])
vals = '-'.join([x[1].lower() for x in set_matches])
if (regs):
res += ",set_regs:" + regs
res += ",set_vals:" + vals
regs = '-'.join([x[0].lower() for x in set_fp_matches])
vals = '-'.join([x[1].lower() for x in set_fp_matches])
if (regs):
res += ",set_fp_regs:" + regs
res += ",set_fp_vals:" + vals
regs = '-'.join([x[0].lower() for x in dmp_reg_matches])
lens = '-'.join([x[1].lower() for x in dmp_reg_matches])
if (regs):
res += ",dump_regs:" + regs
res += ",dump_lengths:" + lens
return res
def fix_bpf(arg):
return arg.replace("skip", "skip:1").replace("bt", "bt:1")
def check_elf(arg):
with open(arg, "rb") as fin:
magic = fin.read(5)
if magic != b"\x7fELF\x02":
print("unsupported filetype")
exit(1)
def main(args):
check_elf(args.prog[0])
cmd = [os.path.join(filepath, "pin/pin"),
"-t",
os.path.join(filepath, "pintool/obj-intel64/tracer.so")]
if args.bpf is not None:
for bpf in args.bpf:
cmd.append("-bpf")
cmd.append(fix_bpf(bpf))
if args.bpx is not None:
for bpx in args.bpx:
cmd.append("-bpx")
cmd.append(fix_bpx(bpx))
if args.symbs is not None:
cmd.append("-print_symb")
cmd.append(args.symbs)
if args.callgraph is not None:
cmd.append("-dump_callgraph")
cmd.append(args.callgraph)
cmd.append("--")
cmd.extend(args.prog)
subprocess.call(cmd)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Reverse engineering tool for modifying/logging stuff during execution')
parser.add_argument('--bpf', metavar='dict', type=str, nargs='*',
help='function breakpoint, described as key:val,... list')
parser.add_argument('--bpx', metavar='dict', type=str, nargs='*',
help='instruction breakpoint, described as key:val,... list')
parser.add_argument('--symbs', metavar='regex', type=str,
nargs='?', help='print symbols that match the regex')
parser.add_argument('--callgraph', metavar='outfile.dot', type=str,
nargs='?', help='generate the callgraph and dump it in outfile')
parser.add_argument('prog', type=str, nargs='+',
help='command line of analyzed program')
args = parser.parse_args()
main(args)