jsonpiler 0.11.0

a Json syntax programming language for Windows
Documentation
pub(crate) use super::lc_segment::*;
use crate::prelude::*;
#[derive(Debug, Clone)]
pub(crate) enum LoadCmd {
  BuildVersion,
  CodeSign(u32, u32),
  DySymtab([(u32, u32); 3], (u32, u32)),
  DyldInfoOnly([Option<(u32, u32)>; 5]),
  LoadDyLinker,
  LoadDylib(Vec<u8>),
  Main(u32, u32),
  Segment(A64LcSegment),
  Symtab(u32, u32, u32, u32),
}
impl LoadCmd {
  pub(crate) fn lc_cmd(&self) -> ErrOR<Vec<u8>> {
    match self {
      BuildVersion => Ok(lc_build_version().to_vec()),
      CodeSign(offset, size) => Ok(lc_code_sign(*offset, *size).to_vec()),
      DySymtab(sym_idx_range, indirect) => Ok(lc_dy_symtab(*sym_idx_range, *indirect).to_vec()),
      DyldInfoOnly(dyld_info) => Ok(lc_dyld_info_only(*dyld_info).to_vec()),
      LoadDyLinker => Ok(lc_load_dy_linker().to_vec()),
      LoadDylib(lib_name) => lc_load_dylib(lib_name),
      Main(sizeof_header, entry_off) => Ok(lc_main(*sizeof_header, *entry_off).to_vec()),
      Segment(seg) => seg.lc_segment(),
      Symtab(sym_off, n_syms, str_off, str_size) => {
        Ok(lc_symtab(*sym_off, *n_syms, *str_off, *str_size).to_vec())
      }
    }
  }
  pub(crate) fn sizeof_cmd(&self) -> ErrOR<u32> {
    Ok(match self {
      BuildVersion => 0x18,
      CodeSign(_, _) => 0x10,
      DySymtab(_, _) => 0x50,
      DyldInfoOnly(_) => 0x30,
      LoadDyLinker => 0x20,
      LoadDylib(lib_name) => 0x18 + align_up_u32((lib_name.len() + 1) as u32, 8)?,
      Main(_, _) => 0x18,
      Segment(seg) => seg.sizeof_cmd()?,
      Symtab(_, _, _, _) => 0x18,
    })
  }
}
pub(crate) const fn lc_build_version() -> [u8; 0x18] {
  const LC_BUILD_VERSION: u32 = 0x32;
  const PLATFORM_MACOS: u32 = 1;
  const N_TOOLS: u32 = 0;
  const TOTAL: u32 = 0x18 + N_TOOLS * 8;
  const MIN_OS: u32 = 12 << 16;
  const SDK: u32 = MIN_OS;
  const _TOOL_VERSIONS: [u8; N_TOOLS as usize * 8] = [];
  le_bytes!(LC_BUILD_VERSION, TOTAL, PLATFORM_MACOS, MIN_OS, SDK, N_TOOLS)
}
pub(crate) const fn lc_load_dy_linker() -> [u8; 0x20] {
  const LC_LOAD_DY_LINKER: u32 = 0xE;
  const DYLD_OFF: u32 = 0xC;
  const TOTAL: u32 = 0x20;
  const NAME: [u8; 14] = *b"/usr/lib/dyld\0";
  let mut arr = le_bytes!(LC_LOAD_DY_LINKER, TOTAL, DYLD_OFF, 0u32, 0u128);
  let mut idx = 0;
  while idx < NAME.len() {
    arr[DYLD_OFF as usize + idx] = NAME[idx];
    idx += 1;
  }
  arr
}
pub(crate) fn dylib_version(lib_name: &[u8]) -> (u32, u32) {
  if lib_name == SYS_B.as_bytes() {
    (0x54Cu32 << 16, 1u32 << 16)
  } else if lib_name == OBJC_A.as_bytes() {
    (0xE4u32 << 16, 1u32 << 16)
  } else if lib_name == APP_KIT.as_bytes() {
    (0xA7D3C68u32, 0x2Du32 << 16)
  } else if lib_name == CORE_GRAPHICS.as_bytes() {
    (0x7AD0501u32, 0x40u32 << 16)
  } else {
    (0u32, 0u32)
  }
}
pub(crate) fn lc_load_dylib(lib_name: &[u8]) -> ErrOR<Vec<u8>> {
  const LC_LOAD_DYLIB: u32 = 0xC;
  let (dylib_ver, compat_ver) = dylib_version(lib_name);
  let mut arr = le_bytes!(LC_LOAD_DYLIB, 0u32, 0x18u32, 2u32, 0u32, 0u32).to_vec();
  let name_len = align_up(lib_name.len() + 1, 8)?;
  let total = arr.len() + name_len;
  arr.extend_from_slice(lib_name);
  arr.push(0);
  arr.resize(total, 0);
  arr[4..8].copy_from_slice(&u32::try_from(total)?.to_le_bytes());
  arr[16..20].copy_from_slice(&dylib_ver.to_le_bytes());
  arr[20..24].copy_from_slice(&compat_ver.to_le_bytes());
  Ok(arr)
}
pub(crate) fn lc_main(sizeof_header: u32, entry_off: u32) -> [u8; 0x18] {
  const LC_MAIN: u32 = 0x8000_0028;
  const TOTAL: u32 = 0x18;
  let mut bytes = le_bytes!(LC_MAIN, TOTAL, 0u64, 0u64);
  bytes[8..16].copy_from_slice(&((sizeof_header + entry_off) as u64).to_le_bytes());
  bytes
}
pub(crate) fn lc_dyld_info_only(dyld_info: [Option<(u32, u32)>; 5]) -> [u8; 0x30] {
  const LC_DYLD_INFO_ONLY: u32 = 0x8000_0022;
  const TOTAL: u32 = 0x30;
  let mut bytes = [0u8; 0x30];
  bytes[0..4].copy_from_slice(&LC_DYLD_INFO_ONLY.to_le_bytes());
  bytes[4..8].copy_from_slice(&TOTAL.to_le_bytes());
  for (i, info) in dyld_info.into_iter().enumerate() {
    if let Some((offset, size)) = info {
      bytes[8 + i * 8..0xC + i * 8].copy_from_slice(&offset.to_le_bytes());
      bytes[0xC + i * 8..0x10 + i * 8].copy_from_slice(&size.to_le_bytes());
    }
  }
  bytes
}
pub(crate) fn lc_symtab(sym_off: u32, n_syms: u32, str_off: u32, str_size: u32) -> [u8; 0x18] {
  const LC_SYMTAB: u32 = 0x2;
  const TOTAL: u32 = 0x18;
  let mut bytes = [0u8; 0x18];
  bytes[0..4].copy_from_slice(&LC_SYMTAB.to_le_bytes());
  bytes[4..8].copy_from_slice(&TOTAL.to_le_bytes());
  for (i, val) in [sym_off, n_syms, str_off, str_size].iter().enumerate() {
    bytes[8 + i * 4..0xC + i * 4].copy_from_slice(&val.to_le_bytes());
  }
  bytes
}
pub(crate) fn lc_dy_symtab(
  sym_idx_range: [(u32, u32); 3],
  (indirect_off, n_indirect): (u32, u32),
) -> [u8; 0x50] {
  const LC_DY_SYMTAB: u32 = 0xB;
  const TOTAL: u32 = 0x50;
  let mut bytes = [0u8; 0x50];
  bytes[0..4].copy_from_slice(&LC_DY_SYMTAB.to_le_bytes());
  bytes[4..8].copy_from_slice(&TOTAL.to_le_bytes());
  for (i, (idx, range)) in sym_idx_range.iter().enumerate() {
    bytes[8 + i * 8..0xC + i * 8].copy_from_slice(&idx.to_le_bytes());
    bytes[0xC + i * 8..0x10 + i * 8].copy_from_slice(&range.to_le_bytes());
  }
  bytes[0x38..0x3C].copy_from_slice(&indirect_off.to_le_bytes());
  bytes[0x3C..0x40].copy_from_slice(&n_indirect.to_le_bytes());
  bytes
}
pub(crate) fn lc_code_sign(offset: u32, size: u32) -> [u8; 0x10] {
  const LC_CODE_SIGN: u32 = 0x1D;
  const TOTAL: u32 = 0x10;
  let mut bytes = [0u8; 0x10];
  bytes[0..4].copy_from_slice(&LC_CODE_SIGN.to_le_bytes());
  bytes[4..8].copy_from_slice(&TOTAL.to_le_bytes());
  bytes[8..0xC].copy_from_slice(&offset.to_le_bytes());
  bytes[0xC..0x10].copy_from_slice(&size.to_le_bytes());
  bytes
}