diff --git a/analyzer/binaries/main.dat b/analyzer/binaries/main.dat index 18c9117..2f89bbd 100644 Binary files a/analyzer/binaries/main.dat and b/analyzer/binaries/main.dat differ diff --git a/analyzer/main.py b/analyzer/main.py index a25fc7b..ed4ee07 100644 --- a/analyzer/main.py +++ b/analyzer/main.py @@ -106,9 +106,52 @@ def _encode_binary(binary: Binary) -> bytes: _write_u8(0) _write_u32(len(binary.starting_state)) - # TODO: No RLE for now - for b in binary.starting_state: - _write_u8(b) + + # == encode RLE == + def _pull_repeats(start: int, data: bytes) -> int | None: + i = 0 + first_byte = data[start + i] + while True: + if i >= 255: + break + if start + i >= len(data): + break + if data[start + i] != first_byte: + break + + i += 1 + + if i >= 2: + _write_u8(i) + _write_u8(first_byte) + return start + i + + return None + + def _pull_non_repeats(start: int, data: bytes): + i = 0 + while True: + if i >= 255: + break + if start + i >= len(data): + break + if i >= 1 and data[start + i] == data[start + i - 1]: + break + + i += 1 + + _write_u8(0) + _write_u8(i) + for j in range(i): + _write_u8(data[start + j]) + return start + i + + i = 0 + while i < len(binary.starting_state): + if new_i := _pull_repeats(i, binary.starting_state): + i = new_i + continue + i = _pull_non_repeats(i, binary.starting_state) return out.getbuffer() diff --git a/runner/src/main.dat b/runner/src/main.dat index 18c9117..2f89bbd 100644 Binary files a/runner/src/main.dat and b/runner/src/main.dat differ diff --git a/runner/src/main.rs b/runner/src/main.rs index 552f212..46001a9 100644 --- a/runner/src/main.rs +++ b/runner/src/main.rs @@ -164,12 +164,29 @@ unsafe fn write_imports( prelude.write(&[0xc9, 0xc3]); } -unsafe fn write_starting_state(binary: *mut u8, reader: &mut Reader) { +unsafe fn write_starting_state(mut out: *mut u8, reader: &mut Reader) { let length = reader.read::() as usize; - let ptr = reader.ptr; - println!("length: {:?}", length); - binary.copy_from(ptr, length); + let end = out.byte_add(length); + while out < end { + let code = reader.read::(); + if code > 0 { + // RLE: repeat + let byte = reader.read::(); + for i in 0..code { + *out = byte; + out = out.byte_add(1); + } + } else { + // N literal bytes + let count = reader.read::(); + for _ in 0..count { + let byte = reader.read::(); + *out = byte; + out = out.byte_add(1); + } + } + } } unsafe fn _main_remote() {