1#![no_std]
2pub mod mem;
6pub use paste::paste;
7
8#[macro_export]
12macro_rules! import {
13 ($vis:vis $lib:ident!$func:ident ($($arg:ident :$arg_ty:ty ),* $(,)?) -> $ret:ty) => {
15 $crate::import!(
16 @impl $vis,
17 $func,
18 concat!("\x01__imp_", stringify!($lib), "$", stringify!($func)),
19 ( $( $arg : $arg_ty ),* ),
20 $ret
21 );
22 };
23
24 ($vis:vis $func:ident ($($arg:ident :$arg_ty:ty ),* $(,)?) -> $ret:ty) => {
26 $crate::import!(
27 @impl $vis,
28 $func,
29 concat!("\x01__imp_", stringify!($func)),
30 ( $( $arg : $arg_ty ),* ),
31 $ret
32 );
33 };
34
35 (@impl $vis:vis, $func:ident, $link_name:expr, ( $( $arg:ident : $arg_ty:ty ),* ), $ret:ty) => {
37 $crate::paste! {
38 unsafe extern {
40 #[link_name = $link_name]
41 static [<__ $func>]: u8; }
43
44 #[allow(non_snake_case, non_upper_case_globals, non_camel_case_types)]
46 #[cfg(target_arch = "x86_64")]
47 $vis type [<$func Fn>] = unsafe extern "C" fn( $( $arg_ty ),* ) -> $ret;
48
49 #[inline(always)]
50 #[allow(non_snake_case, non_upper_case_globals, non_camel_case_types)]
51 unsafe fn [<$func _ptr>]() -> [<$func Fn>] {
52 let f: [<$func Fn>];
53 core::arch::asm!(
54 "mov rax, [rip + {slot}]",
55 slot = sym [<__ $func>],
56 lateout("rax") f,
57 options(nostack, preserves_flags),
58 );
59 f
60 }
61
62 #[inline(always)]
64 #[allow(non_snake_case, non_upper_case_globals, non_camel_case_types)]
65 $vis unsafe fn $func( $( $arg : $arg_ty ),* ) -> $ret {
66 unsafe {
67 let f = [<$func _ptr>]();
68 f( $( $arg ),* )
69 }
70 }
71 }
72 };
73}
74
75#[macro_export]
76macro_rules! append_data {
77 ($sym:ident, $fn_name:ident) => {
79 $crate::append_data!(
80 $sym,
81 $fn_name,
82 concat!(".rdata$", stringify!($sym))
83 );
84 };
85
86 ($sym:ident, $fn_name:ident, $section:expr) => {
87 #[unsafe(no_mangle)]
89 #[unsafe(link_section = $section)]
90 static $sym: [u8; 0] = [];
91
92 #[allow(non_snake_case, non_upper_case_globals, non_camel_case_types)]
93 unsafe fn $fn_name() -> *const u8 {
94 let ptr: *const u8;
95 core::arch::asm!(
96 "lea {out}, [rip + {sym}]",
97 sym = sym $sym,
98 out = lateout(reg) ptr,
99 options(readonly, nostack, preserves_flags),
100 );
101 ptr
102 }
103 };
104}
105
106#[macro_export]
107macro_rules! patch {
108 ($type:ty, $name:ident) => {
109
110 };
111}
112
113#[repr(C)]
115struct _RESOURCE {
116 length: core::ffi::c_int,
117 value: [u8; 0],
118}
119
120pub unsafe fn get_resource<'a>(ptr: *const u8) -> &'a [u8] {
121 unsafe {
122 let header = &*(ptr as *const _RESOURCE);
123 core::slice::from_raw_parts(header.value.as_ptr(), header.length as _)
124 }
125}
126
127#[inline(always)]
129pub fn brk() { unsafe { core::arch::asm!("int3"); } }