#!/usr/bin/pythonfrom __future__ import print_functionimport timeimport sysimport readlineimport argparsefrom scarelib import * parser = argparse.ArgumentParser(description="")parser.add_argument('-a', dest='arch', help='Target architecture')parser.add_argument('-f', dest='inFile', help='File to read')parser.add_argument('--base', type=lambda x: int(x,0), dest='baseaddr', help='Base Address (default: 0x400000)')parser.add_argument('--stack', type=lambda x: int(x,0), dest='stackaddr', help='Stack Address (default: 0x401000)')parser.add_argument('--memsize', dest='memsize', help='Emulator Memory Size (default: 0x200000 [2MB])') ## CommandscmdQuit = ["/exit", "/x", "/quit", "/q"]cmdHelp = ["/", "/help", "/?", "/h"]cmdConf = ["/config", "/c"]cmdPList= ["/list", "/l"] # parseCmd# Commands must start with / to be parsed# If 0 is returned, the main command loop will not try to assemble the input# If 1 is returned, then the main command loop should try to assemble the input# If 2 is returned, the main command loop should not append the current command and just assemble and run# If 3 is returned, reinitialize the scaremudef parseCmd(cmd, smu): shouldAssemble = 1 if len(cmd) > 0: if cmd[0] == "/": shouldAssemble = 0 cmdList = cmd.split() cmdListLen = len(cmdList) if cmdList[0] in cmdQuit: sys.exit() if cmdList[0] in cmdHelp: print(helpfile) if cmdList[0] in cmdConf: if cmdListLen == 3: try: cfgOptName = cmdList[1] cfgOptVal = cmdList[2] if cfgOptName in sConfig.keys(): print(f"{cfgOptName}->{cfgOptVal}") # TODO: Keep better track of config option types if cfgOptName == "emu/arch": if cfgOptVal in archez.keys(): sConfig[cfgOptName] = cfgOptVal else: print(f"Invalid arch! Supported arches: {archez.keys()}") else: sConfig[cfgOptName] = int(cfgOptVal, 16) # Only support hex rn else: print("Invalid config opt name!") except: print("Error in /config") elif cmdListLen == 2: try: cfgOptName = cmdList[1] if cfgOptName in sConfig.keys(): print(f"{cfgOptName} = {sConfig[cfgOptName]}") except: print("Error in /config") else: configPrint(sConfig) if cmdList[0] == "/info": if smu: smu.info() else: print("No emulator running!") if cmdList[0] == "/regs": if smu: smu.printRegs() else: print("No emulator running!") if cmdList[0] == "/back": backAmount = int(cmdList[1]) if backAmount <= len(smu.asm_code): smu.asm_code = smu.asm_code[:-backAmount] print(f"Moved back {backAmount} lines to line {len(smu.asm_code)}") shouldAssemble = 2 # Reassemble and run else: print(f"Too far back! You're currently on line {len(smu.asm_code)}") if cmdList[0] == "/load": if cmdListLen > 1: smu.asm_code = loadAsm(cmdList[1]) currentAddr = sConfig["emu/baseaddr"] else: print("Please specify a filename!") if cmdList[0] == "/save": if cmdListLen > 1: saveAsm(smu.asm_code,cmdList[1]) else: print("Please specify a filename!") if cmdList[0] == "/run": shouldAssemble = 2 # Reassemble and run if cmdList[0] == "/reset": shouldAssemble = 3 # Reinitialize if cmdList[0] in cmdPList: printListing(smu, smu.asm_code) if cmdList[0] == "/read": if cmdListLen == 3: try: memout = 0 baseAddr = 0 if cmdList[1][0:2] == "0x": memout = smu.mu_ctx.mem_read(int(cmdList[1],16), int(cmdList[2])) baseAddr = int(cmdList[1],16) elif cmdList[1][0] == "$": regTarget = cmdList[1].split("$")[1] regValue = smu.readReg(regTarget) if regValue is not None: memout = smu.mu_ctx.mem_read(regValue, int(cmdList[2])) baseAddr = regValue if memout: dHex(memout, baseAddr) else: print("Usage: /read {0xaddress|$register} size") except Exception as e: print(e) print("Usage: /read {0xaddress|$register} size") else: print("Usage: /read {0xaddress|$register} size") if cmdList[0] == "/dis": try: if cmdListLen == 3: if cmdList[1][0:2] == "0x": smu.dis(int(cmdList[1],16), int(cmdList[2])) elif cmdList[1][0] == "$": regTarget = cmdList[1].split("$")[1] regValue = smu.readReg(regTarget) if regValue is not None: instructions4dis = smu.dis(regValue, int(cmdList[2])) printListing(smu, instructions4dis) else: print("Usage: /dis {0xaddress|$register} size") else: print("Usage: /dis {0xaddress|$register} size") except Exception as e: print(e) print("Usage: /dis {0xaddress|$register} size") if cmdList[0] == "/export": try: if cmdListLen == 3: fArch = smu.arch_name if cmdList[1] == "bin": mcLen = len(smu.machine_code) if mcLen > 0: print(f"Exporting {mcLen} bytes of code as raw binary") exportBin(smu.machine_code, "bin", fArch, cmdList[2]) else: print("No machine code to export!") elif cmdList[1] == "elf64": mcLen = len(smu.machine_code) if mcLen > 0: print(f"Exporting {mcLen} bytes of code as ELF64") exportBin(smu.machine_code, "elf64", fArch, cmdList[2]) else: print("No machine code to export!") else: print("Invalid binary type!") else: print("Usage: /export type filename") except Exception as e: print(f"Export Error: {e}") else: shouldAssemble = 0 # Don't do anything if there's no input return shouldAssemble if __name__ == '__main__': printSplash("cerulean") args = parser.parse_args() print("Type / for help\n") inFile = args.inFile if args.inFile else "" currentArch = args.arch.lower() if args.arch else "NoArch" if args.stackaddr: sConfig["emu/stackaddr"] = args.stackaddr if args.baseaddr: sConfig["emu/baseaddr"] = args.baseaddr if args.memsize: sConfig["emu/memsize"] = args.memsize if currentArch == "NoArch": print(f"Please select an architecture! Use `/c emu/arch ARCH`.\nSupported arches: {archez.keys()}") smu = False currentAddr = sConfig["emu/baseaddr"] else: sConfig["emu/arch"] = currentArch smu = scaremu(currentArch) currentAddr = sConfig["emu/baseaddr"] if inFile: smu.asm_code = loadAsm(inFile) while True: try: cmd = input(f"[{cArchP}{currentArch}]{cIP}{currentAddr:02x}{cEnd}> ") shouldAsm = parseCmd(cmd, smu) if ( smu == False ) and (sConfig["emu/arch"] != "NoArch"): smu = scaremu(sConfig["emu/arch"]) currentArch = sConfig["emu/arch"] currentAddr = sConfig["emu/baseaddr"] if sConfig["emu/arch"] != currentArch: smu = scaremu(sConfig["emu/arch"]) currentArch = sConfig["emu/arch"] currentAddr = sConfig["emu/baseaddr"] if shouldAsm == 3: smu = scaremu(sConfig["emu/arch"]) currentArch = sConfig["emu/arch"] currentAddr = sConfig["emu/baseaddr"] if shouldAsm: if shouldAsm == 1: smu.asm_code.append(cmd) if len(smu.asm_code) > 0: asmStatus = smu.asm(smu.asm_code) if asmStatus == 0: currentAddr, runStatus = smu.run() if runStatus == 0: smu.printRegs() else: print("run() returned a non-zero value") else: smu.asm_code.pop() # Gets rid of the last line of assembly else: currentAddr = sConfig["emu/baseaddr"] except EOFError: break
#!/usr/bin/python
from __future__ import print_function
import time
import sys
import readline
import argparse
from scarelib import *
parser = argparse.ArgumentParser(description="")
parser.add_argument('-a', dest='arch', help='Target architecture')
parser.add_argument('-f', dest='inFile', help='File to read')
parser.add_argument('--base', type=lambda x: int(x,0), dest='baseaddr', help='Base Address (default: 0x400000)')
parser.add_argument('--stack', type=lambda x: int(x,0), dest='stackaddr', help='Stack Address (default: 0x401000)')
parser.add_argument('--memsize', dest='memsize', help='Emulator Memory Size (default: 0x200000 [2MB])')
## Commands
cmdQuit = ["/exit", "/x", "/quit", "/q"]
cmdHelp = ["/", "/help", "/?", "/h"]
cmdConf = ["/config", "/c"]
cmdPList= ["/list", "/l"]
# parseCmd
# Commands must start with / to be parsed
# If 0 is returned, the main command loop will not try to assemble the input
# If 1 is returned, then the main command loop should try to assemble the input
# If 2 is returned, the main command loop should not append the current command and just assemble and run
# If 3 is returned, reinitialize the scaremu
def parseCmd(cmd, smu):
shouldAssemble = 1
if len(cmd) > 0:
if cmd[0] == "/":
shouldAssemble = 0
cmdList = cmd.split()
cmdListLen = len(cmdList)
if cmdList[0] in cmdQuit:
sys.exit()
if cmdList[0] in cmdHelp:
print(helpfile)
if cmdList[0] in cmdConf:
if cmdListLen == 3:
try:
cfgOptName = cmdList[1]
cfgOptVal = cmdList[2]
if cfgOptName in sConfig.keys():
print(f"{cfgOptName}->{cfgOptVal}")
# TODO: Keep better track of config option types
if cfgOptName == "emu/arch":
if cfgOptVal in archez.keys():
sConfig[cfgOptName] = cfgOptVal
else:
print(f"Invalid arch! Supported arches: {archez.keys()}")
else:
sConfig[cfgOptName] = int(cfgOptVal, 16) # Only support hex rn
else:
print("Invalid config opt name!")
except:
print("Error in /config")
elif cmdListLen == 2:
try:
cfgOptName = cmdList[1]
if cfgOptName in sConfig.keys():
print(f"{cfgOptName} = {sConfig[cfgOptName]}")
except:
print("Error in /config")
else:
configPrint(sConfig)
if cmdList[0] == "/info":
if smu:
smu.info()
else:
print("No emulator running!")
if cmdList[0] == "/regs":
if smu:
smu.printRegs()
else:
print("No emulator running!")
if cmdList[0] == "/back":
backAmount = int(cmdList[1])
if backAmount <= len(smu.asm_code):
smu.asm_code = smu.asm_code[:-backAmount]
print(f"Moved back {backAmount} lines to line {len(smu.asm_code)}")
shouldAssemble = 2 # Reassemble and run
else:
print(f"Too far back! You're currently on line {len(smu.asm_code)}")
if cmdList[0] == "/load":
if cmdListLen > 1:
smu.asm_code = loadAsm(cmdList[1])
currentAddr = sConfig["emu/baseaddr"]
else:
print("Please specify a filename!")
if cmdList[0] == "/save":
if cmdListLen > 1:
saveAsm(smu.asm_code,cmdList[1])
else:
print("Please specify a filename!")
if cmdList[0] == "/run":
shouldAssemble = 2 # Reassemble and run
if cmdList[0] == "/reset":
shouldAssemble = 3 # Reinitialize
if cmdList[0] in cmdPList:
printListing(smu, smu.asm_code)
if cmdList[0] == "/read":
if cmdListLen == 3:
try:
memout = 0
baseAddr = 0
if cmdList[1][0:2] == "0x":
memout = smu.mu_ctx.mem_read(int(cmdList[1],16), int(cmdList[2]))
baseAddr = int(cmdList[1],16)
elif cmdList[1][0] == "$":
regTarget = cmdList[1].split("$")[1]
regValue = smu.readReg(regTarget)
if regValue is not None:
memout = smu.mu_ctx.mem_read(regValue, int(cmdList[2]))
baseAddr = regValue
if memout:
dHex(memout, baseAddr)
else:
print("Usage: /read {0xaddress|$register} size")
except Exception as e:
print(e)
print("Usage: /read {0xaddress|$register} size")
else:
print("Usage: /read {0xaddress|$register} size")
if cmdList[0] == "/dis":
try:
if cmdListLen == 3:
if cmdList[1][0:2] == "0x":
smu.dis(int(cmdList[1],16), int(cmdList[2]))
elif cmdList[1][0] == "$":
regTarget = cmdList[1].split("$")[1]
regValue = smu.readReg(regTarget)
if regValue is not None:
instructions4dis = smu.dis(regValue, int(cmdList[2]))
printListing(smu, instructions4dis)
else:
print("Usage: /dis {0xaddress|$register} size")
else:
print("Usage: /dis {0xaddress|$register} size")
except Exception as e:
print(e)
print("Usage: /dis {0xaddress|$register} size")
if cmdList[0] == "/export":
try:
if cmdListLen == 3:
fArch = smu.arch_name
if cmdList[1] == "bin":
mcLen = len(smu.machine_code)
if mcLen > 0:
print(f"Exporting {mcLen} bytes of code as raw binary")
exportBin(smu.machine_code, "bin", fArch, cmdList[2])
else:
print("No machine code to export!")
elif cmdList[1] == "elf64":
mcLen = len(smu.machine_code)
if mcLen > 0:
print(f"Exporting {mcLen} bytes of code as ELF64")
exportBin(smu.machine_code, "elf64", fArch, cmdList[2])
else:
print("No machine code to export!")
else:
print("Invalid binary type!")
else:
print("Usage: /export type filename")
except Exception as e:
print(f"Export Error: {e}")
else:
shouldAssemble = 0 # Don't do anything if there's no input
return shouldAssemble
if __name__ == '__main__':
printSplash("cerulean")
args = parser.parse_args()
print("Type / for help\n")
inFile = args.inFile if args.inFile else ""
currentArch = args.arch.lower() if args.arch else "NoArch"
if args.stackaddr:
sConfig["emu/stackaddr"] = args.stackaddr
if args.baseaddr:
sConfig["emu/baseaddr"] = args.baseaddr
if args.memsize:
sConfig["emu/memsize"] = args.memsize
if currentArch == "NoArch":
print(f"Please select an architecture! Use `/c emu/arch ARCH`.\nSupported arches: {archez.keys()}")
smu = False
currentAddr = sConfig["emu/baseaddr"]
else:
sConfig["emu/arch"] = currentArch
smu = scaremu(currentArch)
currentAddr = sConfig["emu/baseaddr"]
if inFile:
smu.asm_code = loadAsm(inFile)
while True:
try:
cmd = input(f"[{cArchP}{currentArch}]{cIP}{currentAddr:02x}{cEnd}> ")
shouldAsm = parseCmd(cmd, smu)
if ( smu == False ) and (sConfig["emu/arch"] != "NoArch"):
smu = scaremu(sConfig["emu/arch"])
currentArch = sConfig["emu/arch"]
currentAddr = sConfig["emu/baseaddr"]
if sConfig["emu/arch"] != currentArch:
smu = scaremu(sConfig["emu/arch"])
currentArch = sConfig["emu/arch"]
currentAddr = sConfig["emu/baseaddr"]
if shouldAsm == 3:
smu = scaremu(sConfig["emu/arch"])
currentArch = sConfig["emu/arch"]
currentAddr = sConfig["emu/baseaddr"]
if shouldAsm:
if shouldAsm == 1:
smu.asm_code.append(cmd)
if len(smu.asm_code) > 0:
asmStatus = smu.asm(smu.asm_code)
if asmStatus == 0:
currentAddr, runStatus = smu.run()
if runStatus == 0:
smu.printRegs()
else:
print("run() returned a non-zero value")
else:
smu.asm_code.pop() # Gets rid of the last line of assembly
else:
currentAddr = sConfig["emu/baseaddr"]
except EOFError:
break