Mercurial > repo
diff d/DCPUToolBot-master/dcpu.py @ 2775:4975968b0496
<ThatOtherPerson> cp -r DCPUToolBot-master d
author | HackBot |
---|---|
date | Mon, 22 Apr 2013 16:07:09 +0000 |
parents | 0e687eac0f29 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/d/DCPUToolBot-master/dcpu.py Mon Apr 22 16:07:09 2013 +0000 @@ -0,0 +1,175 @@ +import subprocess +import tempfile +import os +import re +import time +import threading + +def link(files): + out_fd, out_fname = tempfile.mkstemp() + os.fdopen(out_fd).close() + + process_flags = ["dtld", "-o", out_fname, "-k", "none"] + filenames = [] + for file in files: + fd, fname = tempfile.mkstemp() + f = os.fdopen(fd, 'wb') + f.write(file) + f.close() + filenames.append(fname) + process_flags.append(fname) + + proc = subprocess.Popen(process_flags, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + res, err = proc.communicate() + + for file in filenames: + os.remove(file) + + final = open(out_fname) + res = final.read() + final.close() + + return (res, err) + +def assemble_file(code, binary=False): + code = '\n'.join(code.split('/')) + code = '\n'.join(code.split('\\')) + + process_flags = ["dtasm", "-o", "-", "-"] + if binary: + process_flags.append("--binary") + process = subprocess.Popen(process_flags, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + results = process.communicate(code) + res = results[0] + err = results[1] + return (res, err) + +def assemble_binary(code): + + code = '///'.join(code.split('\\\\\\')) + files = code.split('///') + + if len(files) > 1: + file_binaries = [] + err = "" + for file in files: + assembled = assemble_file(file) + if assembled[0]: + file_binaries.append(assembled[0]) + if assembled[1]: + err += assembled[1] + res, link_err = link(file_binaries) + err += link_err + return (res, err) + else: + return assemble_file(code, True) + +def assemble(code): + res, err = assemble_binary(code) + words = [] + i = 0 + while i < len(res) / 2: + byte_one = ord(res[2*i]) + byte_two = ord(res[2*i+1]) + print "Bytes:", byte_one, byte_two + word = "0x%04x" % ((byte_one << 8) + byte_two) + words.append(word) + i += 1 + print "Assembly attempted" + return (words, err) + +def timeout(p): + if p.poll() == None: + p.kill() + +hex_re = re.compile("^0x[0-9a-fA-F]+") +disasm_re = re.compile("0x[0-9a-fA-F]{4} \(0x[0-9a-fA-F]{4}\): *(>>>)? *(.+)\r?\n?") +null_re = re.compile("<null>") + +def disassemble(binary_str): + byte_strings = binary_str.split(",") + + print byte_strings + + fd, filename = tempfile.mkstemp() + file = os.fdopen(fd, 'wb') + + for byte in byte_strings: + byte = byte.strip() + if hex_re.match(byte): + byte = int(byte, 16) + else: + byte = int(byte) + file.write(chr(byte >> 8)) + file.write(chr(byte & 0xff)) + + file.close() + + length = hex(len(byte_strings)) + print length + + args = 'dtdb -c "disasm 0x0 ' + length + '" ' + filename + print args + + proc = subprocess.Popen(args, stderr=subprocess.PIPE, shell=True) + proc.wait() + + res = proc.stderr.read() + + matches = disasm_re.findall(res) + + res = [] + + for match in matches: + if not null_re.match(match[1]): + res.append(match[1].replace('\r', '')) + + response = ' / '.join(res) + + os.remove(filename) + return response + +register_re = re.compile(r"([A-Z]{1,2}):\s*0x([\dA-F]+)") + +def execute(code): + binary, err = assemble_binary(code) + if err and not ("warning" in err): + return ("", err) + + num_words = len(binary) / 2 + + fd, filename = tempfile.mkstemp() + file = os.fdopen(fd, 'wb') + file.write(binary) + file.close() + + start = time.time() + proc = subprocess.Popen(['dtemu', '-t', '-h', filename], stderr=subprocess.PIPE) + t = threading.Timer(5, timeout, [proc]) + while proc.poll() == None: + if time.time() - start > 5: + proc.kill() + final = time.time() - start + + err = proc.stderr.read() + + err_lines = err.split("\n") + + for i in range(11): + err_lines.pop() + + errors = "\n".join(err_lines) + + os.remove(filename) + + register_matches = register_re.findall(err) + + changed_registers = [] + + for match in register_matches: + if match[1] != "0000": + changed_registers.append(match[0] + ":0x" + match[1]) + registers = ', '.join(changed_registers) + ms = final * 1000 + response = "[" + str(num_words) + " words][" + registers + "][%dms]" % round(ms) + return (response, errors)