659 lines
24 KiB
Python
659 lines
24 KiB
Python
|
import asm
|
||
|
|
||
|
def padBin(number,bit=8):
|
||
|
return asm.padBin(asm.toBin(number),bit=bit)
|
||
|
|
||
|
def toDec(binNumber):
|
||
|
return asm.toDec(binNumber)
|
||
|
|
||
|
doc = """
|
||
|
0000 NOP
|
||
|
0001 LDA memory > A
|
||
|
0010 ADD A + memspace
|
||
|
0011 SUB A - memspace
|
||
|
0100 STA A > memory
|
||
|
0101 OUT A > OUT
|
||
|
0110 JMP Jump to adress
|
||
|
0111 LDI par > A
|
||
|
1000 JIF Jump if greater
|
||
|
1001 JIE Jump if equal
|
||
|
1010 LDP memory[A] > A
|
||
|
1011 INP IN > A
|
||
|
1100 JMA Jump to A
|
||
|
1101 --- not implemented
|
||
|
1110 STP memory[par] > memory[A]
|
||
|
1111 HLT Halt
|
||
|
"""
|
||
|
|
||
|
def compile(cmd,par,memAddr):
|
||
|
# Every function creates unknown vars, even if it makes no sense in it case,
|
||
|
# because if the function sits inside a user-defined function vars may be
|
||
|
# defined later
|
||
|
#try:
|
||
|
if cmd=="newVar": # creates new var and allocates memory-adress for it
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
print("[i] newVar is obsolete in this version of tronScript")
|
||
|
elif cmd=="newArray": # creates new array and allocates memory-adress for it
|
||
|
print("Creating array '"+par[0].upper()+"' at memory-space "+padBin(len(varRec)+(2**8)/2)+" - "+padBin(len(varRec)+int(par[1])+(2**8)/2))
|
||
|
for i in range(int(par[1])):
|
||
|
varRec["array_"+par[0].upper()+"["+i+"]"] = len(varRec)+(2**8)/2
|
||
|
elif cmd=="jumpMark": # creates a jumpMark and saves current adress in the DB for later use by the jump-name-replacement
|
||
|
print("Creating jumpMark '"+par[0].upper()+"' at memory-address "+padBin(memAddr))
|
||
|
jumpMark[par[0].upper()] = memAddr
|
||
|
elif cmd=="jump": # creates dummy jump code for later replacement
|
||
|
# we have to do it this way, beacause a jumpMark may be defined after the jump-call
|
||
|
return [
|
||
|
# will be replaced after script-compilation
|
||
|
"Jump_"+par[0].upper()
|
||
|
]
|
||
|
elif cmd=="getVarAddress": # stores the memory-adress of a var into another
|
||
|
# maybe needed, if user want to access vars with
|
||
|
# custom asssembly code
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
try:
|
||
|
t = varRec[par[1].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[1].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[1].upper()] = len(varRec)+(2**8)/2
|
||
|
return [
|
||
|
## load the Var-Adress into A Register and save it into specified var
|
||
|
# LDI
|
||
|
toDec("0111"+padBin(varRec[par[0].upper()])),
|
||
|
# STA variable to store the current pointer in
|
||
|
toDec("0100"+padBin(varRec[par[1].upper()])),
|
||
|
]
|
||
|
elif cmd=="getArrayAddress": # like getVarAdress, but for arrays
|
||
|
# arrayName Index storeVar
|
||
|
try:
|
||
|
t = varRec["array_"+par[0].upper()+"["+par[1]+"]"]
|
||
|
except:
|
||
|
print("Undefined Array")
|
||
|
exit()
|
||
|
try:
|
||
|
_ = int(par[1])
|
||
|
except:
|
||
|
print("Expected array-index (integer)")
|
||
|
exit()
|
||
|
return [
|
||
|
## load the Var-Adress into A Register and save it into specified var
|
||
|
# LDI
|
||
|
toDec("0111"+padBin(varRec["array_"+par[0].upper()+"["+par[1]+"]"])),
|
||
|
# STA variable to store the current pointer in
|
||
|
toDec("0100"+padBin(varRec[par[2].upper()])),
|
||
|
]
|
||
|
elif cmd=="exec": # execute a user defined function
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating function-jumpback-var '"+par[0].upper()+"_JUMPBACK' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()+"_JUMPBACK"] = len(varRec)+(2**8)/2
|
||
|
return [
|
||
|
## remember current pointer, so you can jump back here after function execution is done
|
||
|
# LDI
|
||
|
toDec("0111"+padBin(pointer)),
|
||
|
# STA variable to store the current pointer in
|
||
|
toDec("0100"+padBin(varRec[par[0].upper()+"_JUMPBACK"])),
|
||
|
# will be replaced after script-compilation
|
||
|
"Exec_"+par[0].upper()# jumpback function-call-var
|
||
|
]
|
||
|
elif cmd=="setVar": # gives a var a defined value
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
if par[1][0]=="b":
|
||
|
par[1] = toDec(par[1][1:])
|
||
|
return [
|
||
|
## loads desired value into the A register and then stores it at the variables memory adress
|
||
|
# LDI value
|
||
|
toDec("0111" + padBin(int(par[1]))),
|
||
|
# STA var Name
|
||
|
toDec("0100" + padBin(varRec[par[0].upper()]))
|
||
|
]
|
||
|
elif cmd=="copyVar": # gives a var the value of another var
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
try:
|
||
|
t = varRec[par[1].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[1].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[1].upper()] = len(varRec)+(2**8)/2
|
||
|
return [
|
||
|
## load memory-space of var 1 into register A and the store it into memory-space of var 2
|
||
|
# LDA var 1
|
||
|
toDec("0001" + padBin(varRec[par[0].upper()])),
|
||
|
# STA var 2
|
||
|
toDec("0100" + padBin(varRec[par[1].upper()]))
|
||
|
]
|
||
|
elif cmd=="setArrayIndex": # defines the value of an array (par0) index (par1) to be (par2)
|
||
|
try:
|
||
|
t = varRec["array_"+par[0].upper()+"["+par[1]+"]"]
|
||
|
except:
|
||
|
print("Undefined array")
|
||
|
exit()
|
||
|
try:
|
||
|
_=int(par[1])
|
||
|
except:
|
||
|
print("Expected array-index (integer)")
|
||
|
exit()
|
||
|
if par[2][0]=="b":
|
||
|
par[2] = toDec(par[2][1:])
|
||
|
return [
|
||
|
## loads desired value into the A register and then stores it at the variables memory adress
|
||
|
# LDI value
|
||
|
toDec("0111" + padBin(int(par[2]))),
|
||
|
# STA var Name
|
||
|
toDec("0100" + padBin(varRec["array_"+par[0].upper()+"["+par[1]+"]"]))
|
||
|
]
|
||
|
elif cmd=="getArrayIndex": # puts the value of an array (par0) index (par1) into var (par2)
|
||
|
try:
|
||
|
t = varRec["array_"+par[0].upper()+"["+par[1]+"]"]
|
||
|
except:
|
||
|
print("Undefined Array")
|
||
|
exit()
|
||
|
try:
|
||
|
t = varRec[par[2].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[2].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[2].upper()] = len(varRec)+(2**8)/2
|
||
|
try:
|
||
|
_=int(par[1])
|
||
|
except:
|
||
|
print("Expected array-index (integer)")
|
||
|
exit()
|
||
|
return [
|
||
|
## load memory-space of var 1 into register A and the store it into memory-space of var 2
|
||
|
# LDA var 1
|
||
|
toDec("0001" + padBin(varRec["array_"+par[0].upper()+"["+par[1]+"]"])),
|
||
|
# STA var 2
|
||
|
toDec("0100" + padBin(varRec[par[2].upper()]))
|
||
|
]
|
||
|
elif cmd=="write": # writes to the console
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
return [
|
||
|
## load the variable into register A, then print it
|
||
|
# LDA var Name
|
||
|
toDec("0001" + padBin(varRec[par[0].upper()])),
|
||
|
# OUT null
|
||
|
toDec("0101" + "00000000")
|
||
|
]
|
||
|
elif cmd=="read": # reads from the console
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
return [
|
||
|
## input > register A; register A > var
|
||
|
# INP null
|
||
|
toDec("1011" + "00000000"),
|
||
|
# STA var Name
|
||
|
toDec("0100" + padBin(varRec[par[0].upper()]))
|
||
|
]
|
||
|
elif cmd=="add": # adds to numbers and stores the answer in another
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
try:
|
||
|
t = varRec[par[1].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[1].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[1].upper()] = len(varRec)+(2**8)/2
|
||
|
try:
|
||
|
t = varRec[par[2].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[2].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[2].upper()] = len(varRec)+(2**8)/2
|
||
|
return [
|
||
|
## load var 1 into register A; add var 2, store in var 3
|
||
|
# LDA var Name in1
|
||
|
toDec("0001" + padBin(varRec[par[0].upper()])),
|
||
|
# ADD var Name in2
|
||
|
toDec("0010" + padBin(varRec[par[1].upper()])),
|
||
|
# STA var Name out
|
||
|
toDec("0100" + padBin(varRec[par[2].upper()]))
|
||
|
]
|
||
|
elif cmd=="subtract": # in1 - in2 = out
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
try:
|
||
|
t = varRec[par[1].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[1].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[1].upper()] = len(varRec)+(2**8)/2
|
||
|
try:
|
||
|
t = varRec[par[2].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[2].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[2].upper()] = len(varRec)+(2**8)/2
|
||
|
return [
|
||
|
## laod var 1 into register A; subtract var 2; store in var 3
|
||
|
# LDA var Name in1
|
||
|
toDec("0001" + padBin(varRec[par[0]])),
|
||
|
# SUB var Name in2
|
||
|
toDec("0011" + padBin(varRec[par[1]])),
|
||
|
# STA var Name out
|
||
|
toDec("0100" + padBin(varRec[par[2]]))
|
||
|
]
|
||
|
elif cmd=="if": # if clause
|
||
|
#cmd p0 p1 p2 p3 p4:
|
||
|
#if VAR ?? VAR cmd pars
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
try:
|
||
|
t = varRec[par[2].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[2].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[2].upper()] = len(varRec)+(2**8)/2
|
||
|
comp1=par[0].upper()
|
||
|
comp2=par[2].upper()
|
||
|
comp=par[1]
|
||
|
shellcode=compile(par[3],par[4:],memAddr+4)
|
||
|
if not shellcode:
|
||
|
return ["Error","I had problems getting the internal shellcode. Sorry :("]
|
||
|
if shellcode[0]=="Error":
|
||
|
return ["Error","Internal shellcode compilation thew an Error:\n"+shellcode[1]]
|
||
|
## binary code that magicaly works:
|
||
|
if comp=="==":
|
||
|
ret = [
|
||
|
# LDI konst
|
||
|
toDec("0111" + "10000000"),
|
||
|
# STA temp
|
||
|
toDec("0100" + "11111111"),
|
||
|
# LDA comp1
|
||
|
toDec("0001" + padBin(varRec[comp1])),
|
||
|
# ADD konst
|
||
|
toDec("0010" + "11111111"),
|
||
|
# SUB comp2
|
||
|
toDec("0011" + padBin(varRec[comp2])),
|
||
|
# JIE
|
||
|
toDec("1001" + padBin(memAddr+7)),
|
||
|
# JMP
|
||
|
toDec("0110" + padBin(memAddr+7+len(shellcode)))
|
||
|
]
|
||
|
elif comp=="!=":
|
||
|
ret = [
|
||
|
# LDI konst
|
||
|
toDec("0111" + "10000000"),
|
||
|
# STA temp
|
||
|
toDec("0100" + "11111111"),
|
||
|
# LDA comp1
|
||
|
toDec("0001" + padBin(varRec[comp1])),
|
||
|
# ADD konst
|
||
|
toDec("0010" + "11111111"),
|
||
|
# SUB comp2
|
||
|
toDec("0011" + padBin(varRec[comp2])),
|
||
|
# JIE
|
||
|
toDec("1001" + padBin(memAddr+6+len(shellcode)))
|
||
|
]
|
||
|
elif comp==">=":
|
||
|
ret = [
|
||
|
# LDI konst
|
||
|
toDec("0111" + "10000000"),
|
||
|
# STA temp
|
||
|
toDec("0100" + "11111111"),
|
||
|
# LDA comp1
|
||
|
toDec("0001" + padBin(varRec[comp1])),
|
||
|
# ADD konst
|
||
|
toDec("0010" + "11111111"),
|
||
|
# SUB comp2
|
||
|
toDec("0011" + padBin(varRec[comp2])),
|
||
|
# JIF
|
||
|
toDec("1000" + padBin(memAddr+6+len(shellcode)))
|
||
|
]
|
||
|
elif comp==">":
|
||
|
ret = [
|
||
|
# LDI konst
|
||
|
toDec("0111" + "01111111"),
|
||
|
# STA temp
|
||
|
toDec("0100" + "11111111"),
|
||
|
# LDA comp1
|
||
|
toDec("0001" + padBin(varRec[comp1])),
|
||
|
# ADD konst
|
||
|
toDec("0010" + "11111111"),
|
||
|
# SUB comp2
|
||
|
toDec("0011" + padBin(varRec[comp2])),
|
||
|
# JIF
|
||
|
toDec("1000" + padBin(memAddr+6+len(shellcode)))
|
||
|
]
|
||
|
elif comp=="<=":
|
||
|
ret = [
|
||
|
# LDI konst
|
||
|
toDec("0111" + "10000000"),
|
||
|
# STA temp
|
||
|
toDec("0100" + "11111111"),
|
||
|
# LDA comp2
|
||
|
toDec("0001" + padBin(varRec[comp2])),
|
||
|
# ADD konst
|
||
|
toDec("0010" + "11111111"),
|
||
|
# SUB comp1
|
||
|
toDec("0011" + padBin(varRec[comp1])),
|
||
|
# JIF
|
||
|
toDec("1000" + padBin(memAddr+6+len(shellcode)))
|
||
|
]
|
||
|
elif comp=="<":
|
||
|
ret = [
|
||
|
# LDI konst
|
||
|
toDec("0111" + "01111111"),
|
||
|
# STA temp
|
||
|
toDec("0100" + "11111111"),
|
||
|
# LDA comp2
|
||
|
toDec("0001" + padBin(varRec[comp2])),
|
||
|
# ADD konst
|
||
|
toDec("0010" + "11111111"),
|
||
|
# SUB comp1
|
||
|
toDec("0011" + padBin(varRec[comp1])),
|
||
|
# JIF
|
||
|
toDec("1000" + padBin(memAddr+6+len(shellcode)))
|
||
|
]
|
||
|
for s in shellcode:
|
||
|
ret.append(s)
|
||
|
return ret
|
||
|
elif cmd=="for": # for loop: "for [goal] [counter] [step] [cmd] [pars]"
|
||
|
# == for [counter] in range(0,[goal],[step]):
|
||
|
# [cmd]([pars])
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
try:
|
||
|
t = varRec[par[1].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[1].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[1].upper()] = len(varRec)+(2**8)/2
|
||
|
try:
|
||
|
t = varRec[par[2].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[2].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[2].upper()] = len(varRec)+(2**8)/2
|
||
|
goal = par[0].upper()
|
||
|
clock = par[1].upper()
|
||
|
step = par[2].upper()
|
||
|
shellcode=compile(par[3],par[4:],memAddr+12)
|
||
|
ret = [
|
||
|
# LDI konst
|
||
|
toDec("0111" + "00000000"),
|
||
|
# STA temp
|
||
|
toDec("0100" + padBin(varRec[clock])),
|
||
|
# LDI konst <-- jump back to
|
||
|
toDec("0111" + "10000000"),
|
||
|
# STA temp
|
||
|
toDec("0100" + "11111111"),
|
||
|
# LDA clock
|
||
|
toDec("0001" + padBin(varRec[clock])),
|
||
|
# ADD konst
|
||
|
toDec("0010" + "11111111"),
|
||
|
# SUB goal
|
||
|
toDec("0011" + padBin(varRec[goal])),
|
||
|
# JIE
|
||
|
toDec("1001" + padBin(memAddr+12+len(shellcode)+1)),
|
||
|
# LDA clock
|
||
|
toDec("0001" + padBin(varRec[goal])),
|
||
|
# ADD step
|
||
|
toDec("0010" + padBin(varRec[step])),
|
||
|
# STA clock
|
||
|
toDec("0100" + padBin(varRec[goal]))
|
||
|
]
|
||
|
for s in shellcode:
|
||
|
ret.append(s)
|
||
|
# JMP
|
||
|
ret.append(toDec("0110" + padBin(memAddr+2)))
|
||
|
return ret
|
||
|
elif cmd=="asm" or cmd[0]==":": # compiles assembler to machine-code
|
||
|
if cmd=="asm":
|
||
|
opcode = par[0]
|
||
|
param = par[1]
|
||
|
else:
|
||
|
opcode = cmd[1:]
|
||
|
param = par[0]
|
||
|
if param[:2]=="b#":
|
||
|
param = toDec(param[2:])
|
||
|
elif param[:2]=="d#":
|
||
|
param = param[2:]
|
||
|
elif param[:2]=="v#":
|
||
|
try:
|
||
|
t = varRec[param[2:].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+param[2:].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[param[2:].upper()] = len(varRec)+(2**8)/2
|
||
|
param = varRec[param[2:].upper()]
|
||
|
elif param in ["-","none"]:
|
||
|
param = toDec("00000000")
|
||
|
elif param in ["~","all"]:
|
||
|
param = toDec("11111111")
|
||
|
else:
|
||
|
return ["Error","Invalid param supplied to asm-command (no valid prefix found)"]
|
||
|
for a in range(len(asm.asmMap)):
|
||
|
if asm.asmMap[a]==opcode:
|
||
|
print("Found matching opcode")
|
||
|
return [toDec(padBin(a,bit=4)+padBin(param))]
|
||
|
elif cmd=="shellcode": # insertes raw shellcode into the programm
|
||
|
return [toDec("".join(par))]
|
||
|
elif cmd=="push":
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
ret = [
|
||
|
### value to temp
|
||
|
# LDA value
|
||
|
toDec("0001" + padBin(varRec[par[0]])),
|
||
|
# STA temp
|
||
|
toDec("0100" + padBin(varRec["temp"])),
|
||
|
|
||
|
### increment stackpointer
|
||
|
# LDI konst
|
||
|
toDec("0111" + "00000001"), # we are going to use a overflow to subtract (2's-complement)
|
||
|
# ADD stack_pointer
|
||
|
toDec("0010" + padBin(varRec["stack_pointer"])),
|
||
|
# STA stack_pointer
|
||
|
toDec("0100" + padBin(varRec["stack_pointer"])),
|
||
|
|
||
|
### A > write as new element
|
||
|
# STP temp
|
||
|
toDec("1110" + padBin(varRec["temp"]))
|
||
|
]
|
||
|
return ret
|
||
|
elif cmd=="pop":
|
||
|
try:
|
||
|
t = varRec[par[0].upper()]
|
||
|
except:
|
||
|
print("Creating var '"+par[0].upper()+"' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[par[0].upper()] = len(varRec)+(2**8)/2
|
||
|
ret = [
|
||
|
### read the last element > A
|
||
|
# LDI stack-base
|
||
|
toDec("0111" + "11111111"),
|
||
|
# SUB stack_pointer
|
||
|
toDec("0011" + padBin(varRec["stack_pointer"])),
|
||
|
# LDP konst
|
||
|
toDec("1010" + "00000000"),
|
||
|
# STA stack_pointer
|
||
|
toDec("0100" + padBin(varRec[par[0]])),
|
||
|
|
||
|
### decrement stackpointer
|
||
|
# LDI konst
|
||
|
toDec("0111" + "11111111"), # we are going to use a overflow to subtract (2's-complement)
|
||
|
# ADD stack_pointer
|
||
|
toDec("0010" + padBin(varRec["stack_pointer"])),
|
||
|
# STA stack_pointer
|
||
|
toDec("0100" + padBin(varRec["stack_pointer"]))
|
||
|
]
|
||
|
return ret
|
||
|
elif cmd=="nop": # nothing...
|
||
|
return [toDec("0000" + "00000000")]
|
||
|
elif cmd=="halt": # halts execution of programm
|
||
|
return [toDec("1111" + "11111111")]
|
||
|
else:
|
||
|
return ["Error","Unimplemented Function: "+str(cmd)]
|
||
|
#except Exception as e:
|
||
|
# return ["Error","Unknown Error: "+str(e)]
|
||
|
|
||
|
bits = 12
|
||
|
|
||
|
varRec = {"temp": (2**8)/2, "stack_pointer": (2**8)/2 + 1 } # to store VarName -> memory-address
|
||
|
jumpMark = {} # to store jumpMarkName -> jump-address
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
print("[tronScript-Compiler by CyberCodeDragon]")
|
||
|
print("! Unstable Beta-Version with stack")
|
||
|
memory = []
|
||
|
for i in range(2**bits): #expand memory
|
||
|
memory.append(0)
|
||
|
|
||
|
pointer = 0
|
||
|
funcTable = [] # [[funcName,funcCode],...]
|
||
|
|
||
|
for f in asm.os.listdir("tronScript"): #display all found scripts
|
||
|
if f[-5:]==".tron":
|
||
|
print("> "+"tronScript/"+f)
|
||
|
filePath = raw_input("file to compile> ")
|
||
|
inFile = filePath.split("\\")
|
||
|
inFile = inFile[len(inFile)-1]
|
||
|
tmp = inFile.split(".")
|
||
|
ext = tmp[len(tmp)-1]
|
||
|
name = inFile.split("."+ext)[0]
|
||
|
print("[*] Reading "+inFile)
|
||
|
with open(filePath) as f:
|
||
|
code = f.read().replace(" ","") #read file and remove tabs
|
||
|
c = code.split("\n") #c = lines of code
|
||
|
#detect functions
|
||
|
for l in range(len(c)): #for every line of code
|
||
|
elems = c[l].split(" ") #elems = [cmd,pa1,par2,...,parN]
|
||
|
if elems[0]=="function":
|
||
|
funcName = elems[1]
|
||
|
funcCode = code.split("function "+funcName+" {")[1].split("}")[0].split("\n") #get the function Code
|
||
|
funcName = funcName.upper()
|
||
|
print("detected function '"+funcName+"' in line "+str(l)+":\n"+"\n".join(funcCode))
|
||
|
for i in range(len(funcCode)+0):
|
||
|
c[l+i]="#function-code" #replace function with a comment -> dont mess up later parsing
|
||
|
funcTable.append([funcName,funcCode])
|
||
|
try: #create jumpback-var if not existing (does probably not exist)
|
||
|
t = varRec[funcName+"_JUMPBACK"]
|
||
|
except:
|
||
|
print("Creating function-jumpback-var '"+funcName+"_JUMPBACK' at memory-address "+padBin(len(varRec)+(2**8)/2))
|
||
|
varRec[funcName+"_JUMPBACK"] = len(varRec)+(2**8)/2
|
||
|
|
||
|
#parse code
|
||
|
for l in range(len(c)): #for every line in code
|
||
|
if c[l] not in ["","\n"]: #if lines is not empty
|
||
|
print("Parsing line "+str(l)+": "+c[l])
|
||
|
cmd = c[l].split(" ")[0]
|
||
|
if not cmd[0]=="#": #dont parse comments
|
||
|
if cmd in ["halt","nop"]: #cmds without params
|
||
|
par = []
|
||
|
else:
|
||
|
par = c[l].split(cmd+" ")[1].split(" ")
|
||
|
r = compile(cmd,par,pointer) #compile
|
||
|
if r:
|
||
|
if r[0]=="Error": #print error
|
||
|
print("Error compiling line "+str(l)+" {"+c[l]+"}: \n"+str(r[1]))
|
||
|
exit()
|
||
|
for ret in r:
|
||
|
veryVerbose = False
|
||
|
if veryVerbose:
|
||
|
try:
|
||
|
print("Compiled to: "+padBin(ret,bit=12))
|
||
|
except:
|
||
|
print("Compiled to: "+str(ret))
|
||
|
memory[pointer] = ret #write code to memory
|
||
|
pointer+=1
|
||
|
try:
|
||
|
if padBin(memory[pointer-1],bit=12)[:4]!="1111": #if the last command is not a HLT command
|
||
|
print("Appending HLT-Command")
|
||
|
# HLT
|
||
|
memory[pointer] = toDec("1111"+"11111111")
|
||
|
print("HLT at "+padBin(pointer)+": "+padBin(memory[pointer],bit=12))
|
||
|
pointer+=1
|
||
|
except: #looks like the last command was a placeholder: not a HLT command
|
||
|
print("Appending HLT-Command")
|
||
|
# HLT
|
||
|
memory[pointer] = toDec("1111"+"11111111")
|
||
|
print("HLT at "+padBin(pointer)+": "+padBin(memory[pointer],bit=12))
|
||
|
pointer+=1
|
||
|
|
||
|
#replace jump-names
|
||
|
for m in range(len(memory)):
|
||
|
try:
|
||
|
if memory[m][:5]=="Jump_": #if at memory-adress is just a jump-dummy
|
||
|
print("Inserting Jump-Adress at "+padBin(m,bit=12))
|
||
|
memory[m]=toDec("0110"+padBin(jumpMark[memory[m][5:]])) #replace with real jump adress
|
||
|
except:
|
||
|
t=1
|
||
|
#append function-shellcode
|
||
|
funcMapper = {} #map funcName to funcCode
|
||
|
for f in range(len(funcTable)):
|
||
|
print("Appending shellcode for function "+str(funcTable[f][0])+" at adress "+padBin(pointer))
|
||
|
funcMapper[funcTable[f][0]] = pointer #remember where you put dat function
|
||
|
for l in range(len(funcTable[f][1])):
|
||
|
if funcTable[f][1][l] not in ["","halt","nop"]:
|
||
|
ret=compile(funcTable[f][1][l].split(" ")[0],funcTable[f][1][l].split(" ")[1:],pointer)
|
||
|
try:
|
||
|
if ret[0]=="Error":
|
||
|
print("An Error occured, when compiling function shellcode for function '"+funcTable[f][0]+"':\n"+str(e))
|
||
|
else:
|
||
|
for r in range(len(ret)):
|
||
|
memory[pointer]=ret[r] #append compiled function memory
|
||
|
pointer+=1
|
||
|
except:
|
||
|
t=1
|
||
|
## jump back after function execution
|
||
|
# LDI konst=3
|
||
|
memory[pointer] = toDec("0111" + "00000011")
|
||
|
pointer+=1
|
||
|
# ADD jumpBackVar
|
||
|
memory[pointer] = toDec("0010" + padBin(varRec[funcTable[f][0]+"_JUMPBACK"]))
|
||
|
pointer+=1
|
||
|
# JMA null
|
||
|
memory[pointer] = toDec("1100" + "00000000")
|
||
|
pointer+=1
|
||
|
print("FuncMapper: "+str(funcMapper))
|
||
|
print("Var Assignment:")
|
||
|
varAss = str(varRec)[1:][:-1].split(", ")
|
||
|
print("#VAR-NAME# #ADDRESS#")
|
||
|
for va in range(len(varAss)): #print all vars with their memory-location
|
||
|
print(varAss[va].split("'")[1]+": "+" "*(12-len(varAss[va].split("'")[1]))+padBin(int(varAss[va].split("': ")[1])))
|
||
|
#replace func-names
|
||
|
for m in range(len(memory)):
|
||
|
try:
|
||
|
if memory[m][:5]=="Exec_": #if there is just a function-call-dummy
|
||
|
print("Inserting Exec-Call-Adress at "+padBin(m,bit=12))
|
||
|
memory[m]=toDec("0110"+padBin(funcMapper[memory[m][5:]])) #replace it with a jump to the function
|
||
|
except Exception as e:
|
||
|
if str(e) != "'int' object has no attribute '__getitem__'":
|
||
|
print "Error while replacing func-name: "+str(e)+"\n (I don't know why, sorry)"
|
||
|
try:
|
||
|
print("Removing old "+name+".asmTron")
|
||
|
os.remove(name+".asmTron")
|
||
|
except:
|
||
|
t=1
|
||
|
print("Saving as "+name+".asmTron")
|
||
|
with open(name+".asmTron", 'wb') as f:
|
||
|
t=asm.pickle.dumps([12,memory])
|
||
|
t=asm.zlib.compress(t)
|
||
|
f.write(t)
|
||
|
print("Done.")
|