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)