finished!

This commit is contained in:
EvilMuffinHa 2022-07-13 13:03:54 -04:00
parent 4986e97e2b
commit ed259baee5
6 changed files with 355 additions and 79 deletions

1
flag.txt Normal file
View File

@ -0,0 +1 @@
dummy

Binary file not shown.

View File

@ -1,10 +1,11 @@
; vim: ft=nasm ; vim: ft=nasm
s:
%macro i_nop 0 %macro i_nop 0
db 0x00 db 0x00
%endmacro %endmacro
%define np i_nop %define np i_nop
%macro i_halt 1 %macro i_halt 1
db 0x01 db 0x01
db %1 db %1
@ -42,7 +43,8 @@
db 0x50 db 0x50
db %1 db %1
db %2 db %2
db %3 db (%3 >> 8) & 0xff
db %3 & 0xff
%endmacro %endmacro
%define jl i_less %define jl i_less
@ -53,10 +55,19 @@
db 0x51 db 0x51
db %1 db %1
db %2 db %2
db %3 db (%3 >> 8) & 0xff
db %3 & 0xff
%endmacro %endmacro
%define le i_leq %define le i_leq
%macro break 0
sd disp, 0x00
sd disp, 0x01
sd disp, 0x02
sd disp, 0x03
np
%endmacro
%define inp 0 %define inp 0
%define disp 1 %define disp 1
%define arith 2 %define arith 2
@ -69,72 +80,324 @@ gt 0x02, inp
gt 0x03, inp gt 0x03, inp
; [a, b, c, d] -> mem ; [a, b, c, d] -> mem
sd tape, 0x00 sd tape, 0x00
sd tape, 0x01
sd tape, 0x02 sd tape, 0x02
sd tape, 0x01
sd tape, 0x03 sd tape, 0x03
; {a, b, c, d} ; {a, b, c, d}
sd arith, 0x00
sd arith, 0x03
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x03, arith
; [i[0], i[1], i[2], i[3] + i[0]] ; [i[0], i[1], i[2], i[3] + i[0]]
; - add i[3] and i[0] ; - add i[3] and i[0]
sd arith, 0x01
sd arith, 0x03
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x03, arith
; [i[0], i[1], i[2], (i[3] + i[0]) ^ i[1]] ; [i[0], i[1], i[2], (i[3] + i[0]) ^ i[1]]
; - xor i[1] with i[3] + i[0], pop from arith ; - xor i[1] with i[3] + i[0], pop from arith
sd arith, 0x00
sd arith, 0x01
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [i[0] + i[1], i[1], i[2], (i[3] + i[0]) ^ i[1]] ; [i[0] + i[1], i[1], i[2], (i[3] + i[0]) ^ i[1]]
; - add i[0] and i[1], pop from arith ; - add i[0] and i[1], pop from arith
sd arith, 0x00
sd arith, 0x02
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x02, arith
; [i[0] + i[1], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[0] + i[1], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - xor i[0] + i[1] with i[2], pop from arith ; - xor i[0] + i[1] with i[2], pop from arith
sd arith, 0x00
sd arith, 0x02
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [i[2], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[2], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - xor (i[0] + i[1]) ^ i[2] with i[0] + i[1], pop from arith ; - xor (i[0] + i[1]) ^ i[2] with i[0] + i[1], pop from arith
sd arith, 0x00
sd arith, 0x01
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x01, arith
sd arith, 0x01
; [i[2], i[2] + i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[2], i[2] + i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - add i[2] + i[1], pop from arith | store i[2] + i[1] in arith ; - add i[2] + i[1], pop from arith | store i[2] + i[1] in arith
gt 0x01, tape
sd arith, 0x01
; [i[2], i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[2], i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - pop i[3] from tape use previous i[1] + i[2] from arith to xor ; - pop i[3] from tape use previous i[1] + i[2] from arith to xor
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x01, arith
; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - use previous i[1] + i[2] from arith to xor and pop ; - use previous i[1] + i[2] from arith to xor and pop
sd arith, 0x00
gt 0x00, tape
; [i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - put i[2] in arith, pop i[1] from tape ; - put i[2] in arith, pop i[1] from tape
sd arith, 0x00
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [i[2] + i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[2] + i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - put i[1] in arith, add, pop ; - put i[1] in arith, add, pop
sd arith, 0x00
sd arith, 0x01
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - xor i[2] + i[1] with (i[2] + i[1]) ^ i[3] ; - xor i[2] + i[1] with (i[2] + i[1]) ^ i[3]
sd arith, 0x00
gt 0x00, tape
; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - put i[3] in arith, pop i[2] from tape ; - put i[3] in arith, pop i[2] from tape
sd arith, 0x00
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [i[2] + i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[2] + i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - put i[2] in arith, add to i[3] ; - put i[2] in arith, add to i[3]
sd arith, 0x00
gt 0x00, tape
; [i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - put i[2] + i[3] in arith, pop i[0] from tape ; - put i[2] + i[3] in arith, pop i[0] from tape
sd arith, 0x00
sd tape, 0x00
ld 0x00, 0x03
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; [(i[2] + i[3]) ^ i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]] ; [(i[2] + i[3]) ^ i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
; - xor in arith ; - xor in arith
sd tape, 0x00
sd tape, 0x01
sd tape, 0x02
sd tape, 0x03
gt 0x01, tape
gt 0x02, tape
gt 0x03, tape
gt 0x00, tape
; push all to tape ; push all to tape
; pop all back into mem in correct spot ; pop all back into mem in correct spot
; stage 1 done
; :b [a, b, c, d] (, ,)
sd tape, 0x01
; :b [a, b, c, d] (b, , )
sd arith, 0x01
; :b [a, 0, c, d] (b, 0, +)
ld 0x01, 0x00
sd arith, 0x01
ld 0x01, 0x01
sd arith, 0x01
; :b [a, t, c, d] (b, 0, +)
sd tape, 0x03
gt 0x01, tape
; :b t [a, t, c, d] (b, 0, +)
sd tape, 0x01
; :b t [a, b, c, d] ()
gt 0x01, arith
loop:
; :b t c [a * c, b, 0, d] ()
sd tape, 0x02
sd tape, 0x03 ; :b t c d [a, b, c, d]
sd tape, 0x00
gt 0x03, tape ; :b t c d [a, b, c, a]
multip:
sd arith, 0x02
ld 0x02, 0x01
sd arith, 0x02
ld 0x02, 0x02 ; sub 1 from c
sd arith, 0x02
gt 0x02, arith
sd arith, 0x00
sd arith, 0x03
ld 0x00, 0x01 ; a + a
sd arith, 0x00
gt 0x00, arith
sd tape, 0x00 ; :b t c d a+a [a+a, b, c-1, a]
; routine for doing overflowing add ld 0x00, 0x01 ; :b t c d a+a [1, b, c-1, a]
; [a, b] le 0x02, 0x00, leavemul - s
; [255 - a, b] gt 0x00, tape ; put back a + a
; 255 - a < b
; a = b - [255 - a] ; :b t c d [a+a, b, c-1, a]
; 255 - a >= b le 0x00, 0x00, multip - s ; jump to mul
; a = a + b
; leavemul:
gt 0x00, tape
gt 0x03, tape
gt 0x02, tape
; :b t [a * c, b, c, d] ()
sd arith, 0x00
sd arith, 0x01
sd tape, 0x00
ld 0x00, 0x01
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
; :b t [a * c + b, b, c, d] ()
modulo:
jl 0x00, 0x03, leavemod - s
sd arith, 0x00
sd arith, 0x03
sd tape, 0x00
ld 0x00, 0x02
sd arith, 0x00
gt 0x00, tape
gt 0x00, arith
le 0x00, 0x00, modulo - s
leavemod:
; :b t [(ac + b) % d, b, c, d] ()
gt 0x01, tape
; :b [(ac + b) % d, t, c, d] ()
sd arith, 0x01
ld 0x01, 0x01
; :b [(ac + b) % d, 1, c, d] (t, )
sd arith, 0x01
ld 0x01, 0x02
sd arith, 0x01
; :b [(ac + b) % d, 1, c, d] (t, 1, -)
gt 0x01, arith
; :b [(ac + b) % d, t-1, c, d] ()
sd tape, 0x02
ld 0x02, 0x00
le 0x01, 0x02, finish - s
gt 0x02, tape
; if t - 1 leq 0 -> jump out
; else -> continue
sd arith, 0x02
; :b [(ac + b) % d, t-1, c, d] (c, ,)
ld 0x02, 0x00
sd arith, 0x02
ld 0x02, 0x01
sd arith, 0x02
; :b [(ac + b) % d, t-1, 0, d] (c, 0, +)
gt 0x02, tape
; : [(ac + b) % d, t-1, b, d] (c, 0, +)
sd tape, 0x02
; :b [(ac + b) % d, t-1, b, d] (c, 0, +)
sd tape, 0x01
; :b t-1 [(ac + b) % d, t-1, b, d] (c, 0, +)
sd tape, 0x02
; :b t-1 b [(ac + b) % d, t-1, b, d] (c, 0, +)
gt 0x02, arith
; :b t-1 b [(ac + b) % d, t-1, c, d] ()
gt 0x01, tape
; :b t-1 [(ac + b) % d, b, c, d] ()
le 0x03, 0x03, loop - s
; if d leq d -> jump loop
finish:
gt 0x02, tape
gt 0x01, tape
le 0x00, 0x01, label
sd disp, 0x00 sd disp, 0x00
label: sd disp, 0x01
sd disp, 0x01 sd disp, 0x02
sd disp, 0x03
; finish things
;le 0x00, 0x01, label
;sd disp, 0x00
;label:
; sd disp, 0x01

View File

@ -6,19 +6,21 @@ pub trait Device {
fn send_byte(&mut self, byte: u8); fn send_byte(&mut self, byte: u8);
} }
pub struct Reader<'a> { pub struct Reader<'a> {
pub reader: &'a mut dyn Read, pub reader: &'a mut dyn Read,
} }
impl Device for Reader<'_> { impl Device for Reader<'_> {
fn get_byte(&mut self) -> u8 { fn get_byte(&mut self) -> u8 {
self.reader.bytes().next().and_then(|result| result.ok()).map(|byte| byte as u8).unwrap() self.reader
.bytes()
.next()
.and_then(|result| result.ok())
.map(|byte| byte as u8)
.unwrap()
} }
fn send_byte(&mut self, _byte: u8) { fn send_byte(&mut self, _byte: u8) {}
}
} }
pub struct Tape { pub struct Tape {
@ -28,13 +30,12 @@ pub struct Tape {
impl Device for Tape { impl Device for Tape {
fn get_byte(&mut self) -> u8 { fn get_byte(&mut self) -> u8 {
let i = self.tape[self.index];
if self.index == 0 { if self.index == 0 {
self.index = 25000; self.index = 25000;
} }
self.index -= 1; self.index -= 1;
self.index %= 25000; self.index %= 25000;
i self.tape[self.index]
} }
fn send_byte(&mut self, byte: u8) { fn send_byte(&mut self, byte: u8) {
@ -42,7 +43,6 @@ impl Device for Tape {
self.index += 1; self.index += 1;
self.index %= 25000; self.index %= 25000;
} }
} }
pub struct Writer<'a> { pub struct Writer<'a> {
@ -67,10 +67,10 @@ pub struct Arithmetic {
impl Device for Arithmetic { impl Device for Arithmetic {
fn get_byte(&mut self) -> u8 { fn get_byte(&mut self) -> u8 {
match self.buffer[2] { match self.buffer[2] {
1 => self.buffer[0] + self.buffer[1], 1 => self.buffer[0].overflowing_add(self.buffer[1]).0,
2 => self.buffer[0] - self.buffer[1], 2 => self.buffer[0].overflowing_sub(self.buffer[1]).0,
3 => self.buffer[0] ^ self.buffer[1], 3 => self.buffer[0] ^ self.buffer[1],
_ => 0 _ => 0,
} }
} }
@ -80,5 +80,3 @@ impl Device for Arithmetic {
self.index %= 3; self.index %= 3;
} }
} }

View File

@ -3,57 +3,76 @@
mod device; mod device;
mod vm; mod vm;
use device::{Reader, Arithmetic, Tape, Writer}; use device::{Arithmetic, Reader, Tape, Writer};
use std::io::Cursor;
use rand::prelude::random; use rand::prelude::random;
use std::io::Read; use std::fs;
use std::io; use std::io;
use vm::{State, vm_run}; use std::io::Cursor;
use std::io::Read;
use vm::{vm_run, State};
fn main() { fn main() {
let program: Vec<u8> = io::stdin()
let program: Vec<u8> = io::stdin().bytes().map(|res| res.unwrap_or_else(|_| std::process::exit(1))).collect(); .bytes()
.map(|res| res.unwrap_or_else(|_| std::process::exit(1)))
.collect();
for _ in 0..10 { for _ in 0..10 {
let iv: [u8; 4] = random(); let iv: [u8; 4] = random();
let mut input = Cursor::new(iv); let mut input = Cursor::new(iv);
let mut output = Cursor::new(vec![0,0,0,0]); let mut output = Cursor::new(vec![0, 0, 0, 0]);
let state = State { let state = State {
ip: 0usize, ip: 0usize,
mem: [0; 4], mem: [0; 4],
program: program.clone(), program: program.clone(),
devices: vec![Box::new(Reader { reader: &mut input } ), devices: vec![
Box::new(Writer { writer: &mut output } ), Box::new(Reader { reader: &mut input }),
Box::new(Arithmetic { buffer: [0; 3], index: 0usize }), Box::new(Writer {
Box::new(Tape { tape: [0; 25000], index: 0usize }),] writer: &mut output,
}),
Box::new(Arithmetic {
buffer: [0; 3],
index: 0usize,
}),
Box::new(Tape {
tape: [0; 25000],
index: 0usize,
}),
],
}; };
vm_run(state); vm_run(state);
let ov: [u8; 4] = output.into_inner().try_into().unwrap(); let ov: [u8; 4] = output.into_inner().try_into().unwrap();
println!("{:?}", iv);
println!("{:?}", encrypt(iv));
println!("{:?}", ov);
if ov != encrypt(iv) { if ov != encrypt(iv) {
std::process::exit(1); std::process::exit(1);
} }
} }
println!(
"{}",
fs::read_to_string("flag.txt").unwrap_or_else(|_| {
println!("Couldn't open flag file, please contact an admin if on the server.");
std::process::exit(1)
})
);
} }
#[inline(never)]
fn encrypt(block: [u8; 4]) -> [u8; 4] { fn encrypt(block: [u8; 4]) -> [u8; 4] {
let mut block = block; let mut block = block;
#[allow(clippy::clone_on_copy)]
let mut b = block.clone();
let (i, _) = block[0].overflowing_add(block[3]); let (i, _) = block[0].overflowing_add(block[3]);
block[1] ^= i; b[1] ^= i;
let (i, _) = block[1].overflowing_add(block[0]); let (i, _) = block[1].overflowing_add(block[0]);
block[2] ^= i; b[2] ^= i;
let (i, _) = block[2].overflowing_add(block[1]); let (i, _) = block[2].overflowing_add(block[1]);
block[3] ^= i; b[3] ^= i;
let (i, _) = block[3].overflowing_add(block[2]); let (i, _) = block[3].overflowing_add(block[2]);
block[0] ^= i; b[0] ^= i;
block = b;
for _ in 0..block[3] { for _ in 0..block[3] {
let (mul, _) = block[2].overflowing_mul(block[0]); let (mul, _) = block[2].overflowing_mul(block[0]);

View File

@ -5,7 +5,7 @@ pub struct State<'a> {
pub ip: usize, pub ip: usize,
pub mem: [u8; 4], pub mem: [u8; 4],
pub program: Vec<u8>, pub program: Vec<u8>,
pub devices: Vec<Box<dyn Device + 'a>> pub devices: Vec<Box<dyn Device + 'a>>,
} }
impl State<'_> { impl State<'_> {
@ -25,10 +25,10 @@ impl State<'_> {
#[inline(never)] #[inline(never)]
fn next_dword(&mut self) -> u32 { fn next_dword(&mut self) -> u32 {
let result = (u32::from(self.program[self.ip]) << 24) | let result = (u32::from(self.program[self.ip]) << 24)
(u32::from(self.program[self.ip + 1]) << 16) | | (u32::from(self.program[self.ip + 1]) << 16)
(u32::from(self.program[self.ip + 2]) << 8) | | (u32::from(self.program[self.ip + 2]) << 8)
(u32::from(self.program[self.ip + 3])); | (u32::from(self.program[self.ip + 3]));
self.ip += 4; self.ip += 4;
result result
} }
@ -43,10 +43,8 @@ pub enum Opcode {
Get, Get,
Less, Less,
LessEq, LessEq,
} }
impl From<u8> for Opcode { impl From<u8> for Opcode {
fn from(v: u8) -> Self { fn from(v: u8) -> Self {
match v { match v {
@ -57,18 +55,16 @@ impl From<u8> for Opcode {
0x21 => Opcode::Get, 0x21 => Opcode::Get,
0x50 => Opcode::Less, 0x50 => Opcode::Less,
0x51 => Opcode::LessEq, 0x51 => Opcode::LessEq,
_ => Opcode::Halt _ => Opcode::Halt,
} }
} }
} }
pub fn vm_run(mut state: State) -> i32 { pub fn vm_run(mut state: State) -> i32 {
loop { loop {
if state.ip >= state.program.len() { if state.ip >= state.program.len() {
return 1 return 1;
} }
match Opcode::from(state.program[state.ip]) { match Opcode::from(state.program[state.ip]) {
Opcode::Nop => { Opcode::Nop => {
state.ip += 1; state.ip += 1;
@ -100,7 +96,7 @@ pub fn vm_run(mut state: State) -> i32 {
state.ip += 1; state.ip += 1;
let mem1 = state.mem[state.next_byte() as usize]; let mem1 = state.mem[state.next_byte() as usize];
let mem2 = state.mem[state.next_byte() as usize]; let mem2 = state.mem[state.next_byte() as usize];
let jump = state.next_byte() as usize; let jump = state.next_word() as usize;
if mem1 < mem2 { if mem1 < mem2 {
state.ip = jump; state.ip = jump;
} }
@ -109,12 +105,11 @@ pub fn vm_run(mut state: State) -> i32 {
state.ip += 1; state.ip += 1;
let mem1 = state.mem[state.next_byte() as usize]; let mem1 = state.mem[state.next_byte() as usize];
let mem2 = state.mem[state.next_byte() as usize]; let mem2 = state.mem[state.next_byte() as usize];
let jump = state.next_byte() as usize; let jump = state.next_word() as usize;
if mem1 <= mem2 { if mem1 <= mem2 {
state.ip = jump; state.ip = jump;
} }
} }
} }
} }
} }