2765
|
1 import subprocess
|
|
2 import tempfile
|
|
3 import os
|
|
4 import re
|
|
5 import time
|
|
6 import threading
|
|
7
|
|
8 def link(files):
|
|
9 out_fd, out_fname = tempfile.mkstemp()
|
|
10 os.fdopen(out_fd).close()
|
|
11
|
|
12 process_flags = ["dtld", "-o", out_fname, "-k", "none"]
|
|
13 filenames = []
|
|
14 for file in files:
|
|
15 fd, fname = tempfile.mkstemp()
|
|
16 f = os.fdopen(fd, 'wb')
|
|
17 f.write(file)
|
|
18 f.close()
|
|
19 filenames.append(fname)
|
|
20 process_flags.append(fname)
|
|
21
|
|
22 proc = subprocess.Popen(process_flags, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
23 res, err = proc.communicate()
|
|
24
|
|
25 for file in filenames:
|
|
26 os.remove(file)
|
|
27
|
|
28 final = open(out_fname)
|
|
29 res = final.read()
|
|
30 final.close()
|
|
31
|
|
32 return (res, err)
|
|
33
|
|
34 def assemble_file(code, binary=False):
|
|
35 code = '\n'.join(code.split('/'))
|
|
36 code = '\n'.join(code.split('\\'))
|
|
37
|
|
38 process_flags = ["dtasm", "-o", "-", "-"]
|
|
39 if binary:
|
|
40 process_flags.append("--binary")
|
|
41 process = subprocess.Popen(process_flags, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
42 results = process.communicate(code)
|
|
43 res = results[0]
|
|
44 err = results[1]
|
|
45 return (res, err)
|
|
46
|
|
47 def assemble_binary(code):
|
|
48
|
|
49 code = '///'.join(code.split('\\\\\\'))
|
|
50 files = code.split('///')
|
|
51
|
|
52 if len(files) > 1:
|
|
53 file_binaries = []
|
|
54 err = ""
|
|
55 for file in files:
|
|
56 assembled = assemble_file(file)
|
|
57 if assembled[0]:
|
|
58 file_binaries.append(assembled[0])
|
|
59 if assembled[1]:
|
|
60 err += assembled[1]
|
|
61 res, link_err = link(file_binaries)
|
|
62 err += link_err
|
|
63 return (res, err)
|
|
64 else:
|
|
65 return assemble_file(code, True)
|
|
66
|
|
67 def assemble(code):
|
|
68 res, err = assemble_binary(code)
|
|
69 words = []
|
|
70 i = 0
|
|
71 while i < len(res) / 2:
|
|
72 byte_one = ord(res[2*i])
|
|
73 byte_two = ord(res[2*i+1])
|
|
74 print "Bytes:", byte_one, byte_two
|
|
75 word = "0x%04x" % ((byte_one << 8) + byte_two)
|
|
76 words.append(word)
|
|
77 i += 1
|
|
78 print "Assembly attempted"
|
|
79 return (words, err)
|
|
80
|
|
81 def timeout(p):
|
|
82 if p.poll() == None:
|
|
83 p.kill()
|
|
84
|
|
85 hex_re = re.compile("^0x[0-9a-fA-F]+")
|
|
86 disasm_re = re.compile("0x[0-9a-fA-F]{4} \(0x[0-9a-fA-F]{4}\): *(>>>)? *(.+)\r?\n?")
|
|
87 null_re = re.compile("<null>")
|
|
88
|
|
89 def disassemble(binary_str):
|
|
90 byte_strings = binary_str.split(",")
|
|
91
|
|
92 print byte_strings
|
|
93
|
|
94 fd, filename = tempfile.mkstemp()
|
|
95 file = os.fdopen(fd, 'wb')
|
|
96
|
|
97 for byte in byte_strings:
|
|
98 byte = byte.strip()
|
|
99 if hex_re.match(byte):
|
|
100 byte = int(byte, 16)
|
|
101 else:
|
|
102 byte = int(byte)
|
|
103 file.write(chr(byte >> 8))
|
|
104 file.write(chr(byte & 0xff))
|
|
105
|
|
106 file.close()
|
|
107
|
|
108 length = hex(len(byte_strings))
|
|
109 print length
|
|
110
|
|
111 args = 'dtdb -c "disasm 0x0 ' + length + '" ' + filename
|
|
112 print args
|
|
113
|
|
114 proc = subprocess.Popen(args, stderr=subprocess.PIPE, shell=True)
|
|
115 proc.wait()
|
|
116
|
|
117 res = proc.stderr.read()
|
|
118
|
|
119 matches = disasm_re.findall(res)
|
|
120
|
|
121 res = []
|
|
122
|
|
123 for match in matches:
|
|
124 if not null_re.match(match[1]):
|
|
125 res.append(match[1].replace('\r', ''))
|
|
126
|
|
127 response = ' / '.join(res)
|
|
128
|
|
129 os.remove(filename)
|
|
130 return response
|
|
131
|
|
132 register_re = re.compile(r"([A-Z]{1,2}):\s*0x([\dA-F]+)")
|
|
133
|
|
134 def execute(code):
|
|
135 binary, err = assemble_binary(code)
|
|
136 if err and not ("warning" in err):
|
|
137 return ("", err)
|
|
138
|
|
139 num_words = len(binary) / 2
|
|
140
|
|
141 fd, filename = tempfile.mkstemp()
|
|
142 file = os.fdopen(fd, 'wb')
|
|
143 file.write(binary)
|
|
144 file.close()
|
|
145
|
|
146 start = time.time()
|
|
147 proc = subprocess.Popen(['dtemu', '-t', '-h', filename], stderr=subprocess.PIPE)
|
|
148 t = threading.Timer(5, timeout, [proc])
|
|
149 while proc.poll() == None:
|
|
150 if time.time() - start > 5:
|
|
151 proc.kill()
|
|
152 final = time.time() - start
|
|
153
|
|
154 err = proc.stderr.read()
|
|
155
|
|
156 err_lines = err.split("\n")
|
|
157
|
|
158 for i in range(11):
|
|
159 err_lines.pop()
|
|
160
|
|
161 errors = "\n".join(err_lines)
|
|
162
|
|
163 os.remove(filename)
|
|
164
|
|
165 register_matches = register_re.findall(err)
|
|
166
|
|
167 changed_registers = []
|
|
168
|
|
169 for match in register_matches:
|
|
170 if match[1] != "0000":
|
|
171 changed_registers.append(match[0] + ":0x" + match[1])
|
|
172 registers = ', '.join(changed_registers)
|
|
173 ms = final * 1000
|
|
174 response = "[" + str(num_words) + " words][" + registers + "][%dms]" % round(ms)
|
|
175 return (response, errors)
|