#![allow(non_snake_case, non_camel_case_types)]
use core::ffi::c_void;
pub const UNW_FLAG_EHANDLER: u8 = 0x1;
pub const UNW_FLAG_CHAININFO: u8 = 0x4;
pub const IMAGE_DIRECTORY_ENTRY_EXCEPTION: usize = 3;
#[repr(C)]
#[derive(Clone, Copy, Default)]
pub struct ImageRuntimeFunction {
pub BeginAddress: u32,
pub EndAddress: u32,
pub UnwindData: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Default)]
pub struct ImageDataDirectory {
pub VirtualAddress: u32,
pub Size: u32,
}
#[repr(C)]
#[derive(Debug)]
pub struct Config {
pub rtl_user_addr: *const c_void,
pub rtl_user_thread_size: u64,
pub base_thread_addr: *const c_void,
pub base_thread_size: u64,
pub first_frame_fp: *const c_void,
pub second_frame_fp: *const c_void,
pub jmp_rbx_gadget: *const c_void,
pub add_rsp_gadget: *const c_void,
pub first_frame_size: u64,
pub second_frame_size: u64,
pub jmp_rbx_frame_size: u64,
pub add_rsp_frame_size: u64,
pub rbp_stack_offset: u64,
pub spoof_function: *const c_void,
pub return_address: *const c_void,
pub is_syscall: u32,
pub ssn: u32,
pub number_args: u64,
pub arg01: *const c_void,
pub arg02: *const c_void,
pub arg03: *const c_void,
pub arg04: *const c_void,
pub arg05: *const c_void,
pub arg06: *const c_void,
pub arg07: *const c_void,
pub arg08: *const c_void,
pub arg09: *const c_void,
pub arg10: *const c_void,
pub arg11: *const c_void,
}
impl Default for Config {
fn default() -> Self {
unsafe { core::mem::zeroed() }
}
}
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
#[allow(dead_code)]
pub enum Registers {
Rax = 0,
Rcx,
Rdx,
Rbx,
Rsp,
Rbp,
Rsi,
Rdi,
R8,
R9,
R10,
R11,
R12,
R13,
R14,
R15,
}
impl PartialEq<usize> for Registers {
fn eq(&self, other: &usize) -> bool {
*self as usize == *other
}
}
#[repr(C)]
pub union UnwindCode {
pub FrameOffset: u16,
pub Anonymous: UnwindCode0,
}
bitfield::bitfield! {
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct UnwindCode0(u16);
pub u8, CodeOffset, SetCodeOffset: 7, 0;
pub u8, UnwindOp, SetUnwindOp: 11, 8;
pub u8, OpInfo, SetOpInfo: 15, 12;
}
#[repr(C)]
pub union UnwindInfo0 {
pub ExceptionHandler: u32,
pub FunctionEntry: u32,
}
bitfield::bitfield! {
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct UnwindVersionFlags(u8);
pub u8, Version, SetVersion: 2, 0;
pub u8, Flags, SetFlags: 7, 3;
}
bitfield::bitfield! {
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct UnwindFrameInfo(u8);
pub u8, FrameRegister, SetFrameRegister: 3, 0;
pub u8, FrameOffset, SetFrameOffset: 7, 4;
}
#[repr(C)]
pub struct UnwindInfo {
pub VersionFlags: UnwindVersionFlags,
pub SizeOfProlog: u8,
pub CountOfCodes: u8,
pub FrameInfo: UnwindFrameInfo,
pub UnwindCode: UnwindCode,
pub Anonymous: UnwindInfo0,
pub ExceptionData: u32,
}
#[repr(u8)]
#[allow(dead_code)]
pub enum UnwindOpCode {
UWOP_PUSH_NONVOL = 0,
UWOP_ALLOC_LARGE = 1,
UWOP_ALLOC_SMALL = 2,
UWOP_SET_FPREG = 3,
UWOP_SAVE_NONVOL = 4,
UWOP_SAVE_NONVOL_BIG = 5,
UWOP_EPILOG = 6,
UWOP_SPARE_CODE = 7,
UWOP_SAVE_XMM128 = 8,
UWOP_SAVE_XMM128BIG = 9,
UWOP_PUSH_MACH_FRAME = 10,
}
impl TryFrom<u8> for UnwindOpCode {
type Error = ();
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0..=10 => Ok(unsafe { core::mem::transmute::<u8, UnwindOpCode>(value) }),
_ => Err(()),
}
}
}