1#![allow(non_snake_case, non_camel_case_types)]
2
3use core::ffi::c_void;
4
5pub const UNW_FLAG_EHANDLER: u8 = 0x1;
7
8pub const UNW_FLAG_CHAININFO: u8 = 0x4;
10
11pub const IMAGE_DIRECTORY_ENTRY_EXCEPTION: usize = 3;
14
15#[repr(C)]
17#[derive(Clone, Copy, Default)]
18pub struct ImageRuntimeFunction {
19 pub BeginAddress: u32,
20 pub EndAddress: u32,
21 pub UnwindData: u32,
22}
23
24#[repr(C)]
26#[derive(Clone, Copy, Default)]
27pub struct ImageDataDirectory {
28 pub VirtualAddress: u32,
29 pub Size: u32,
30}
31
32#[repr(C)]
36#[derive(Debug)]
37pub struct Config {
38 pub rtl_user_addr: *const c_void,
39 pub rtl_user_thread_size: u64,
40 pub base_thread_addr: *const c_void,
41 pub base_thread_size: u64,
42 pub first_frame_fp: *const c_void,
43 pub second_frame_fp: *const c_void,
44 pub jmp_rbx_gadget: *const c_void,
45 pub add_rsp_gadget: *const c_void,
46 pub first_frame_size: u64,
47 pub second_frame_size: u64,
48 pub jmp_rbx_frame_size: u64,
49 pub add_rsp_frame_size: u64,
50 pub rbp_stack_offset: u64,
51 pub spoof_function: *const c_void,
52 pub return_address: *const c_void,
53 pub is_syscall: u32,
54 pub ssn: u32,
55 pub number_args: u64,
56 pub arg01: *const c_void,
57 pub arg02: *const c_void,
58 pub arg03: *const c_void,
59 pub arg04: *const c_void,
60 pub arg05: *const c_void,
61 pub arg06: *const c_void,
62 pub arg07: *const c_void,
63 pub arg08: *const c_void,
64 pub arg09: *const c_void,
65 pub arg10: *const c_void,
66 pub arg11: *const c_void,
67}
68
69impl Default for Config {
70 fn default() -> Self {
71 unsafe { core::mem::zeroed() }
72 }
73}
74
75#[derive(Debug, Clone, Copy)]
77#[repr(u8)]
78#[allow(dead_code)]
79pub enum Registers {
80 Rax = 0,
81 Rcx,
82 Rdx,
83 Rbx,
84 Rsp,
85 Rbp,
86 Rsi,
87 Rdi,
88 R8,
89 R9,
90 R10,
91 R11,
92 R12,
93 R13,
94 R14,
95 R15,
96}
97
98impl PartialEq<usize> for Registers {
99 fn eq(&self, other: &usize) -> bool {
100 *self as usize == *other
101 }
102}
103
104#[repr(C)]
107pub union UnwindCode {
108 pub FrameOffset: u16,
109 pub Anonymous: UnwindCode0,
110}
111
112bitfield::bitfield! {
113 #[repr(C)]
114 #[derive(Clone, Copy, Debug)]
115 pub struct UnwindCode0(u16);
116 pub u8, CodeOffset, SetCodeOffset: 7, 0;
117 pub u8, UnwindOp, SetUnwindOp: 11, 8;
118 pub u8, OpInfo, SetOpInfo: 15, 12;
119}
120
121#[repr(C)]
123pub union UnwindInfo0 {
124 pub ExceptionHandler: u32,
125 pub FunctionEntry: u32,
126}
127
128bitfield::bitfield! {
129 #[repr(C)]
130 #[derive(Clone, Copy, Debug)]
131 pub struct UnwindVersionFlags(u8);
132 pub u8, Version, SetVersion: 2, 0;
133 pub u8, Flags, SetFlags: 7, 3;
134}
135
136bitfield::bitfield! {
137 #[repr(C)]
138 #[derive(Clone, Copy, Debug)]
139 pub struct UnwindFrameInfo(u8);
140 pub u8, FrameRegister, SetFrameRegister: 3, 0;
141 pub u8, FrameOffset, SetFrameOffset: 7, 4;
142}
143
144#[repr(C)]
146pub struct UnwindInfo {
147 pub VersionFlags: UnwindVersionFlags,
148 pub SizeOfProlog: u8,
149 pub CountOfCodes: u8,
150 pub FrameInfo: UnwindFrameInfo,
151 pub UnwindCode: UnwindCode,
152 pub Anonymous: UnwindInfo0,
153 pub ExceptionData: u32,
154}
155
156#[repr(u8)]
159#[allow(dead_code)]
160pub enum UnwindOpCode {
161 UWOP_PUSH_NONVOL = 0,
162 UWOP_ALLOC_LARGE = 1,
163 UWOP_ALLOC_SMALL = 2,
164 UWOP_SET_FPREG = 3,
165 UWOP_SAVE_NONVOL = 4,
166 UWOP_SAVE_NONVOL_BIG = 5,
167 UWOP_EPILOG = 6,
168 UWOP_SPARE_CODE = 7,
169 UWOP_SAVE_XMM128 = 8,
170 UWOP_SAVE_XMM128BIG = 9,
171 UWOP_PUSH_MACH_FRAME = 10,
172}
173
174impl TryFrom<u8> for UnwindOpCode {
175 type Error = ();
176
177 fn try_from(value: u8) -> Result<Self, Self::Error> {
178 match value {
179 0..=10 => Ok(unsafe { core::mem::transmute::<u8, UnwindOpCode>(value) }),
180 _ => Err(()),
181 }
182 }
183}