mirror of
https://git.soft.fish/val/MicroCorruption.git
synced 2025-10-30 05:39:15 +00:00
Rename some directories, add initial chernobyl emu stuff
This commit is contained in:
59
17-Chernobyl/Code/Makefile
Normal file
59
17-Chernobyl/Code/Makefile
Normal 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)
|
||||
24
17-Chernobyl/Code/hashbrek.py
Normal file
24
17-Chernobyl/Code/hashbrek.py
Normal 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("")
|
||||
43
17-Chernobyl/Code/inc/chernobyl.h
Normal file
43
17-Chernobyl/Code/inc/chernobyl.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#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);
|
||||
|
||||
// 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
|
||||
21
17-Chernobyl/Code/inc/chernobyl_stdlib.h
Normal file
21
17-Chernobyl/Code/inc/chernobyl_stdlib.h
Normal 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
|
||||
32
17-Chernobyl/Code/inc/chernobyl_types.h
Normal file
32
17-Chernobyl/Code/inc/chernobyl_types.h
Normal 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
|
||||
130
17-Chernobyl/Code/src/chernobyl.c
Normal file
130
17-Chernobyl/Code/src/chernobyl.c
Normal 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;
|
||||
}
|
||||
87
17-Chernobyl/Code/src/chernobyl_stdlib.c
Normal file
87
17-Chernobyl/Code/src/chernobyl_stdlib.c
Normal 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];
|
||||
}
|
||||
Reference in New Issue
Block a user