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
|
#!/usr/bin/env python
import sys
import re
def index_pred(lst, pred):
for i, el in enumerate(lst):
if pred(el):
return i
def is_ida_addr(s):
return re.match(r'(.*:)?[0-9a-fA-F]+$', s) is not None
autonames = {
'db': ["byte", 0, "uint8_t"],
'dw': ["word", 0, "uint16_t"],
'dd': ["dword", 0, "uint32_t"],
}
def asm_int(s):
if s.endswith('h'):
return int(s[:-1], 16)
elif s.endswith('o'):
return int(s[:-1], 8)
else:
return int(s)
class Symb(object):
def __init__(self, op, name):
self.name = name
self.op = op
self.values = []
def push(self, line):
orig_line = line
line = re.sub(";.*$", "", line)
op_rol = line.split(None, 1)
if len(op_rol) < 2:
print >> sys.stderr, "WARN dummy op in line: %s" % orig_line
return
op, rol = op_rol
if op != self.op:
raise ValueError("op != self.op (%s != %s)" % (op, self.op))
elems = [el.strip() for el in rol.split(",")]
for el in elems:
if " " in el:
parts = el.split()
if len(parts) != 2 or not parts[0].isdigit() \
or not parts[1].startswith("dup(") \
or not parts[1].endswith(")"):
raise ValueError("bad arg %s for op %s" % (el, op))
nb = int(parts[0])
val = asm_int(parts[1][4:-1])
self.values.extend([val] * nb)
else:
self.values.append(asm_int(el))
def close(self):
pass
def out_lines(self):
yield "static const %s %s[%d] = {" % (autonames[self.op][2],
self.name,
len(self.values))
for i, v in enumerate(self.values):
if not i or i % 16:
yield "\t0x%X," % v
else:
yield "\t0x%X,\t\t/* 0x%X %d */" % (v, i, i)
yield "};"
yield ""
def new_symb(op, name):
if name is None:
auto = autonames[op]
name = auto[0] + '_' + str(auto[1])
auto[1] += 1
return Symb(op, name)
symbols = []
current_symb = None
# dismiss_first_words = None
lines = sys.stdin.readlines()
for line in lines:
line = line.strip()
elems = line.split()
pos = index_pred(elems, lambda a: a in autonames)
if pos is None:
print >> sys.stderr, "unrecognize line: %s" % line
continue
op = elems[pos]
named = pos > 0 and not is_ida_addr(elems[pos-1])
# if dimiss_first_words is None and named:
# dimiss_first_words = pos - 1
if named:
name = elems[pos-1]
if current_symb:
current_symb.close()
current_symb = new_symb(op, name)
symbols.append(current_symb)
current_symb.push(" ".join(elems[pos:]))
if current_symb:
current_symb.close()
for symb in symbols:
for line in symb.out_lines():
print line
|