1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
use anyhow::Result; use std::{io::stdin, num::Wrapping}; mod debruijn; pub struct MemoryBase<T> { base: Wrapping<T>, } impl<T> MemoryBase<T> where T: Copy, Wrapping<T>: std::ops::Sub<Output = Wrapping<T>> + std::ops::Add<Output = Wrapping<T>>, { pub fn new(documented: T, leaked: T) -> Self { Self { base: Wrapping(leaked) - Wrapping(documented), } } pub fn documented_to_leaked(&self, documented: T) -> T { (Wrapping(documented) + self.base).0 } pub fn leaked_to_documented(&self, leaked: T) -> T { (Wrapping(leaked) - self.base).0 } } pub fn pause() { println!("Paused, waiting on newline"); let mut pause = String::new(); stdin().read_line(&mut pause).unwrap(); } pub fn buf_to_str(buf: &[u8]) -> Result<String> { let parsed = std::str::from_utf8(buf)?.to_string(); Ok(parsed) } pub fn p32(addr: u32) -> [u8; 4] { addr.to_le_bytes() } pub fn u32(bytes: [u8; 4]) -> u32 { u32::from_le_bytes(bytes) } pub fn p64(addr: u64) -> [u8; 8] { addr.to_le_bytes() } pub fn u64(bytes: [u8; 8]) -> u64 { u64::from_le_bytes(bytes) } pub fn u32_from_bytes(buf: &[u8]) -> Result<u32> { let parsed = std::str::from_utf8(buf)?; let value = u32::from_str_radix(parsed, 16)?; Ok(value) } pub fn u64_from_bytes(buf: &[u8]) -> Result<u64> { let parsed = std::str::from_utf8(buf)?; let value = u64::from_str_radix(parsed, 16)?; Ok(value) } pub fn cyclic(size: usize) -> String { debruijn::debruijn(4, 26) .take(size) .map(|x| (x + b'A') as char) .collect() } pub fn lookup(needle: &str) -> usize { let needle = needle .as_bytes() .iter() .map(|x| x - b'A') .collect::<Vec<_>>(); debruijn::lookup(4, 26, &needle) }