Skip to content

Instantly share code, notes, and snippets.

@d33tah
Last active December 16, 2015 03:08
Show Gist options
  • Save d33tah/5367285 to your computer and use it in GitHub Desktop.
Save d33tah/5367285 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
import sys #argv
import os #we'll need the following two to perform a "chmod +x" equivalent
import stat
import subprocess #to test our result
def error(message):
print("ERROR: "+message)
sys.exit(1)
def hex2bin(string):
"""this function expects a whitespace-separated chain of hex bytes and converts them to string"""
return "".join(map(lambda x: chr(int(x,16)), string.split()))
#see if we'll need a temporary file or the user provided us with some filename
if len(sys.argv) < 2:
deltmp = True
elif len(sys.argv) == 2:
filename = sys.argv[1]
deltmp = False
else:
error("Usage: %s [optional_output_binary_filename]" % sys.argv[0])
#ELF header generated with NASM
code_bin = hex2bin("""
7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
02 00 03 00 01 00 00 00 54 80 04 08 34 00 00 00
00 00 00 00 00 00 00 00 34 00 20 00 01 00 00 00
00 00 00 00 01 00 00 00 00 00 00 00 00 80 04 08
00 80 04 08 5f 00 00 00 5f 00 00 00 05 00 00 00
00 10 00 00
""")
#the heart of the assembler. instruction-parsing loop.
while True:
try:
ins = raw_input()
args = ins.split()
if args==[]:
continue #ignore blank lines
operation = args[0].upper()
if operation == "NOP":
code_bin += hex2bin("90")
elif operation == "INC":
if args[1].upper() == "BX":
code_bin += hex2bin("66 43")
elif args[1].upper() == "EBX":
code_bin += hex2bin("43")
elif args[1].upper() == "AX":
code_bin += hex2bin("66 40")
elif args[1].upper() == "EAX":
code_bin += hex2bin("40")
else:
error("Invalid INC argument: "+args[1])
elif operation == "MUL":
if args[1].upper() == "AX":
code_bin += hex2bin("66 f7 e0")
elif args[1].upper() == "BX":
code_bin += hex2bin("66 f7 e3")
elif args[1].upper() == "EAX":
code_bin += hex2bin("f7 e0")
elif args[1].upper() == "EBX":
code_bin += hex2bin("f7 e3")
else:
error("Invalid MUL argument: "+args[1])
elif operation == "MOV":
rest = ins.upper().lstrip("MOV")
comma_separated_spaces = rest.split(',')
comma_separated_nospaces = map(lambda x: x.strip(), comma_separated_spaces)
comma_separated = map(lambda x: x.upper(), comma_separated_nospaces)
if comma_separated[0] == "EAX" and comma_separated[1] == "EBX":
code_bin += hex2bin("89 d8")
elif comma_separated[0] == "AX" and comma_separated[1] == "BX":
code_bin += hex2bin("66 89 d8")
elif comma_separated[0] == "EBX" and comma_separated[1] == "EAX":
code_bin += hex2bin("89 c3")
elif comma_separated[0] == "BX" and comma_separated[1] == "AX":
code_bin += hex2bin("66 89 c3")
else:
error("Invalid MOV arguents: %s" % comma_separated)
else:
error("Invalid operation: "+ins)
except EOFError:
break
#in the end, return to system with BL's contents as exit code - calls int 80 with eax=1
code_bin += hex2bin("31 c0 40 cd 80")
#open a temporary file if we need one
if deltmp:
filename = subprocess.check_output("mktemp").rstrip('\n')
#save the code
f = open(filename, "w")
f.write(code_bin)
f.close()
#grant us with a permission to execute it
os.chmod(filename, os.stat(filename).st_mode | stat.S_IXUSR )
#run it and output the exit code
p = subprocess.Popen(filename)
p.wait()
print(p.returncode)
#if we used a temporary file, get rid of it
if deltmp:
os.unlink(filename)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment