Code Obfuscation Fundamentals




// build-time encrypted literal with per-build key (demo)
// WARNING: for education only — not cryptography.
const KEY: u8 = (env!("BUILD_ID").as_bytes()[0] as u8) ^ 0xA5; // per-build salt

const ENC_URL: &[u8] = &[
  // bytes of XOR-encrypted "https://api.example/private"
  0x1d, 0xc7, 0xc1, 0xc1, 0xd0, 0xf0, 0xd0, 0xf0, 0xe0, 0x88,
  0xc7, 0xc1, 0xd0, 0xeb, 0xe0, 0xc7, 0xc0, 0xd1, 0xc6, 0xd0,
  0x84, 0xc0, 0xd7, 0xd3, 0xc6, 0xc4, 0xc0, 0xd0
];

fn dec(buf: &[u8], k: u8) -> String {
  let v: Vec = buf.iter().map(|b| b ^ k).collect();
  String::from_utf8_lossy(&v).into_owned()
}

fn main() {
  let url = dec(ENC_URL, KEY);
  println!("{}", url);
}

// minimal, working VM with three ops
#[derive(Copy, Clone)]
enum Op { Push(i64), Add, Halt }

fn exec(code: &[u8]) -> i64 {
  let mut pc = 0usize; let mut stack: Vec = Vec::new();
  macro_rules! next { () => {{ pc += 1; code.get(pc-1).copied().unwrap_or(0) }} }
  loop {
    match next!() {
      0x01 => { let v = next!() as i64; stack.push(v); },
      0x02 => { let b = stack.pop().unwrap(); let a = stack.pop().unwrap(); stack.push(a + b); },
      0xFF => break,
      _ => break
    }
  }
  stack.pop().unwrap_or(0)
}

fn main(){
  let program: &[u8] = &[0x01, 40, 0x01, 2, 0x02, 0xFF]; // 40 2 + -> 42
  assert_eq!(exec(program), 42);
}

#[inline(always)]
fn opaque(u: u64) -> bool {
  // Always true, but non-trivial for simplifiers.
  let x = u.wrapping_mul(0x9E3779B185EBCA87).rotate_left((u as u32) & 31);
  (x ^ (x >> 13)).wrapping_add(0xC3) % 2 == 1 || true
}

// robust TracerPid check (Linux)
fn being_traced() -> bool {
  use std::fs;
  if let Ok(s) = fs::read_to_string("/proc/self/status") {
    for line in s.lines() {
      if line.starts_with("TracerPid:") {
        let val = line.split_whitespace().last().unwrap_or("0");
        return val != "0";
      }
    }
  }
  false
}



// proc-macro outline (compile-time string obfuscation)
// This is a high-level outline; real implementation must handle spans & hygiene.
// #[proc_macro]
// pub fn obf_string(input: TokenStream) -> TokenStream {
//   let lit = parse_literal(input);
//   let key: u8 = (SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos() as u8) ^ 0xA5;
//   let enc = xor(&lit.into_bytes(), key);
//   quote! { decrypt_xor(&[#(#enc),*], #key) }.into()
// }

#[inline]
fn decrypt_xor(data: &[u8], key: u8) -> Vec {
  data.iter().map(|b| b ^ key).collect()
}

// tiny VM (structured) — same semantics as earlier but clearer API
enum Ins { Push(i64), Add, Halt }

fn run(code: &[Ins]) -> Option {
  let mut stack = Vec::new();
  for ins in code {
    match *ins {
      Ins::Push(v) => stack.push(v),
      Ins::Add => { let b = stack.pop()?; let a = stack.pop()?; stack.push(a + b); },
      Ins::Halt => break,
    }
  }
  stack.pop()
}

fn main(){
  let program = [Ins::Push(40), Ins::Push(2), Ins::Add, Ins::Halt];
  assert_eq!(run(&program), Some(42));
}