Skip to content

Instantly share code, notes, and snippets.

@nazywam
Created May 31, 2020 18:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nazywam/bbe54957fb4bdc71709e6415cbcb642c to your computer and use it in GitHub Desktop.
Save nazywam/bbe54957fb4bdc71709e6415cbcb642c to your computer and use it in GitHub Desktop.
import sys
import struct
instructions = {0x00:("NOP",1),0x01:("PUSHC",3),0x05:("PUSHN",3),0x06:("POPF",3),0x07:("POPM",3),0x08:("POPQF",3),0x09:("PUSHA",3),0x0A:("PUSHF",3),0x0B:("PUSHM",3),0x0C:("PUSHMR",3),0x0D:("PUSHP",3),0x0E:("PUSHQF",3),0x0F:("PUSHV",3),0x10:("SFRAME",3),0x11:("SINIT",3),0x12:("SYMBOL",3),0x13:("SYMF",3),0x19:("BEGIN_SEQ",3),0x1A:("JDBG",3),0x1B:("JF",3),0x1C:("JFPT",3),0x1D:("JISW",3),0x1E:("JMP",3),0x1F:("JNEI",3),0x20:("JT",3),0x21:("JTPF",3),0x23:("PUSHBL",3),0x24:("ARRAYATI",3),0x25:("ARRAYPUTI",3),0x26:("CALL",3),0x27:("DO",3),0x28:("FRAME",3),0x29:("FUNC",3),0x2A:("LINE",3),0x2B:("MAKEA",3),0x2C:("MAKELA",3),0x2D:("PARAMS",3),0x2E:("POPFL",3),0x2F:("POPL",3),0x30:("POPS",3),0x31:("PRIVATES",3),0x33:("PUBLICS",3),0x34:("PUSHFL",3),0x35:("PUSHFLR",3),0x36:("PUSHI",3),0x37:("PUSHL",3),0x38:("PUSHLR",3),0x39:("PUSHS",3),0x3A:("PUSHSR",3),0x3B:("PUSHW",3),0x3C:("SEND",3),0x3D:("XBLOCK",3),0x4A:("MPOPF",5),0x4B:("MPOPM",5),0x4C:("MPOPQF",5),0x4D:("MPUSHA",5),0x4E:("MPUSHF",5),0x4F:("MPUSHM",5),0x50:("MPUSHMR",5),0x51:("MPUSHP",5),0x52:("MPUSHQF",5),0x53:("MPUSHV",5),0x54:("MSYMBOL",5),0x55:("MSYMF",5),0x56:("ABS",1),0x57:("AND",1),0x58:("ARRAYAT",1),0x59:("ARRAYPUT",1),0x5A:("BREAK",1),0x5B:("DEC",1),0x5C:("DIVIDE",1),0x5D:("DOOP",1),0x5E:("EEQ",1),0x5F:("ENDBLOCK",1),0x60:("ENDPROC",1),0x61:("END_SEQ",1),0x62:("EQ",1),0x63:("EVENTS",1),0x64:("FALSE",1),0x65:("GE",1),0x66:("GT",1),0x67:("INC",1),0x68:("LE",1),0x69:("LT",1),0x6A:("MINUS",1),0x6B:("MULT",1),0x6C:("NE",1),0x6E:("NEGATE",1),0x6F:("NOP2",1),0x70:("NOT",1),0x71:("NULL",1),0x72:("ONE1",1),0x73:("OR",1),0x74:("PCOUNT",1),0x75:("PLUS",1),0x76:("POP",1),0x77:("PUSHRV",1),0x78:("QSELF",1),0x79:("SAVE_RET",1),0x7A:("TRUE",1),0x7B:("UNDEF",1),0x7C:("ZER0",1),0x7D:("ZZBLOCK",1),0x7E:("AXPRIN",1),0x7F:("AXPROUT",1),0x80:("BOF",1),0x81:("DELETED",1),0x82:("EOF",1),0x83:("FCOUNT",1),0x84:("FIELDNAME",1),0x85:("FLOCK",1),0x86:("FOUND",1),0x87:("FSELECT0",1),0x88:("FSELECT1",1),0x89:("LASTREC",1),0x8A:("LOCK",1),0x8B:("RECNO",1),0x8C:("BNAMES",1),0x8D:("LNAMES",1),0x8E:("SNAMES",1),0x8F:("SRCNAME",1),0x90:("TYPE",1),0x91:("WAVE",1),0x92:("WAVEA",1),0x93:("WAVEF",1),0x94:("WAVEL",1),0x95:("WAVEP",1),0x96:("WAVEPOP",1),0x97:("WAVEPOPF",1),0x98:("WAVEPOPQ",1),0x99:("WAVEQ",1),0x9A:("WSYMBOL",1),0x9B:("AADD",1),0x9C:("ASC",1),0x9D:("AT",1),0x9E:("CDOW",1),0x9F:("CHR",1),0xA0:("CMONTH",1),0xA1:("CTOD",1),0xA2:("DATE",1),0xA3:("DAY",1),0xA4:("DOW",1),0xA5:("DTOC",1),0xA6:("DTOS",1),0xA7:("EMPTY",1),0xA8:("QEXP",1),0xA9:("EXPON",1),0xAA:("INSTR",1),0xAB:("INT",1),0xAC:("LEFT",1),0xAD:("LEN",1),0xAE:("LOGQ",1),0xAF:("LOWER",1),0xB0:("LTRIM",1),0xB1:("MAX",1),0xB2:("MIN",1),0xB3:("MODULUS",1),0xB4:("MONTH",1),0xB5:("REPLICATE",1),0xB6:("ROUND",1),0xB7:("SECONDS",1),0xB8:("SPACE",1),0xB9:("QSQRT",1),0xBA:("STR1",1),0xBB:("STR2",1),0xBC:("STR3",1),0xBD:("SUB2",1),0xBE:("SUB3",1),0xBF:("TIME",1),0xC0:("TRIM",1),0xC1:("UPPER",1),0xC2:("VAL",1),0xC3:("VALTYPE",1),0xC4:("WORD",1),0xC5:("YEAR",1),0xC6:("TRANS",1),0xC7:("COL",1),0xC8:("DEVPOS",1),0xC9:("INKEY0",1),0xCA:("INKEY1",1),0xCB:("PCOL",1),0xCC:("PROW",1),0xCD:("ROW",1),0xCE:("SETPOS",1),0xCF:("SETPOSBS",1)}
symbols = []
with open(sys.argv[1], "rb") as f:
data = f.read()
vm_code = data[0x24c00:]
vm_symbols = data[0x204e0:]
offset = 0
while True:
name = vm_symbols[offset:][:11]
if name.startswith(b"\x00"):
break
name = name.strip(b"\x00")
bScope, pVoid = struct.unpack_from("<HH", vm_symbols[offset:][11:])
offset += 16
try:
symbols.append(name.decode())
except UnicodeDecodeError:
break
offset = 0
while offset < len(vm_code):
opcode = vm_code[offset]
text, size = instructions[opcode]
# print(text)
if text == "LINE":
print("\n")
sys.stdout.write(f"{offset:04x}" + "\t")
if text == "LINE":
print("")
offset += size
elif text == "PUSHC":
offset += 2
char = b""
while not char.endswith(b"\x00"):
char += bytes([vm_code[offset]])
offset += 1
print(f"PUSHC {char[:-1]}")
else:
if size == 1:
print(text)
elif size == 3:
arg0 = struct.unpack_from("<H", vm_code[offset+1:])[0]
if text == "SYMF":
print(f"SYMF {symbols[arg0 - 1]}()")
elif text.startswith("J") and not text.endswith("I"):
arg0 = struct.unpack_from("<h", vm_code[offset+1:])[0]
print(f"{text} {hex(offset + arg0 + size)}")
else:
print(f"{text} {hex(arg0)}")
elif size == 5:
arg0, arg1 = struct.unpack_from("<HH", vm_code[offset+1:])[0]
print(f"{text} {hex(arg0)}, {hex(arg1)}")
else:
raise Exception("Fuck this shit")
offset += size
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment