11/*
2- Windows API Hooking using Trampoline
2+ API Hooking Via Trampoline
33 @5mukx
44*/
55
6- use std:: {
7- ffi:: { CStr , CString } ,
8- ptr:: null_mut,
6+ use std:: ptr:: { null_mut, copy_nonoverlapping} ;
7+ use windows:: {
8+ core:: { s, PCSTR , PCWSTR } ,
9+ Win32 :: {
10+ Foundation :: HWND ,
11+ System :: {
12+ LibraryLoader :: { GetModuleHandleA , GetProcAddress } ,
13+ Memory :: { VirtualProtect , PAGE_EXECUTE_READWRITE , PAGE_PROTECTION_FLAGS } ,
14+ } , UI :: WindowsAndMessaging :: { MessageBoxA , MessageBoxW , MB_ICONINFORMATION , MB_OK } ,
15+ }
916} ;
1017
1118use widestring:: WideCString ;
12- use winapi:: {
13- shared:: {
14- minwindef:: { DWORD , LPVOID , UINT } ,
15- ntdef:: { LPCSTR , LPWSTR } ,
16- windef:: HWND ,
17- } ,
18- um:: {
19- errhandlingapi:: GetLastError ,
20- libloaderapi:: { GetModuleHandleA , GetProcAddress } ,
21- memoryapi:: VirtualProtect ,
22- winnt:: PAGE_EXECUTE_READWRITE ,
23- winuser:: { MB_ICONINFORMATION , MB_OK , MessageBoxA , MessageBoxW } ,
24- } ,
25- } ;
2619
2720const INTERCEPTOR_SIZE : usize = 14 ;
2821
2922#[ repr( C ) ]
3023struct ApiInterceptor {
31- target_function : LPVOID ,
32- replacement_function : LPVOID ,
24+ target_function : * mut std :: ffi :: c_void ,
25+ replacement_function : * mut std :: ffi :: c_void ,
3326 original_code : [ u8 ; INTERCEPTOR_SIZE ] ,
34- original_protection : DWORD ,
27+ original_protection : PAGE_PROTECTION_FLAGS ,
3528}
3629
3730impl ApiInterceptor {
@@ -40,51 +33,60 @@ impl ApiInterceptor {
4033 target_function : null_mut ( ) ,
4134 replacement_function : null_mut ( ) ,
4235 original_code : [ 0 ; INTERCEPTOR_SIZE ] ,
43- original_protection : 0 ,
36+ original_protection : PAGE_PROTECTION_FLAGS ( 0 ) ,
4437 }
4538 }
4639}
4740
48- fn main ( ) {
41+ fn main ( ) {
42+
4943 unsafe {
50- let user32 = GetModuleHandleA ( "user32.dll\0 " . as_ptr ( ) as * const i8 ) ;
51- let dialog_func = GetProcAddress ( user32, "MessageBoxA\0 " . as_ptr ( ) as * const i8 ) ;
44+ let user32 = GetModuleHandleA ( s ! ( "user32.dll" ) ) . expect ( "Failed to get user32.dll handle" ) ;
45+
46+ let dialog_func = GetProcAddress ( user32, s ! ( "MessageBoxA" ) ) . expect ( "Failed to get MessageBox Address" ) ;
5247
5348 let mut interceptor = ApiInterceptor :: new ( ) ;
49+
5450 if !setup_interceptor (
55- dialog_func as LPVOID ,
56- custom_dialog as LPVOID ,
51+ dialog_func as * mut std :: ffi :: c_void ,
52+ custom_dialog as * mut std :: ffi :: c_void ,
5753 & mut interceptor,
5854 ) {
5955 println ! ( "[ERROR] Interceptor setup failed" ) ;
6056 return ;
6157 }
6258
63- let text1 = CString :: new ( "Testing Smukx System" ) . unwrap ( ) ;
64- let caption1 = CString :: new ( "System Info" ) . unwrap ( ) ;
59+ let text1 = s ! ( "Testing 5mukx System" ) ;
60+ let caption1 = s ! ( "System Info" ) ;
6561
6662 MessageBoxA (
67- null_mut ( ) ,
68- text1. as_ptr ( ) ,
69- caption1. as_ptr ( ) ,
63+ None ,
64+ text1,
65+ caption1,
7066 MB_OK | MB_ICONINFORMATION ,
7167 ) ;
7268
73- println ! ( "[INFO] Activating API interceptor ..." ) ;
69+ println ! ( "[INFO] Activating API Interceptor ..." ) ;
7470
7571 if !activate_interceptor ( & mut interceptor) {
7672 println ! ( "[ERROR] Interceptor activation failed" ) ;
7773 return ;
7874 }
7975 println ! ( "[INFO] Interceptor activated" ) ;
8076
81- let text2 = CString :: new ( "Smukx Is Great" ) . unwrap ( ) ;
82- let caption2 = CString :: new ( "System Info" ) . unwrap ( ) ;
77+ if !activate_interceptor ( & mut interceptor) {
78+ println ! ( "[ERROR] Interceptor activation failed" ) ;
79+ return ;
80+ }
81+ println ! ( "[INFO] Interceptor activated" ) ;
82+
83+ let text2 = s ! ( "Smukx Is Bad Guy..." ) ;
84+ let caption2 = s ! ( "System Info" ) ;
8385
8486 MessageBoxA (
85- null_mut ( ) ,
86- text2. as_ptr ( ) ,
87- caption2. as_ptr ( ) ,
87+ None ,
88+ text2,
89+ caption2,
8890 MB_OK | MB_ICONINFORMATION ,
8991 ) ;
9092
@@ -95,50 +97,52 @@ fn main() {
9597 }
9698 println ! ( "[INFO] Interceptor deactivated" ) ;
9799
98- let text3 = CString :: new ( "Smukx System Restored" ) . unwrap ( ) ;
99- let caption3 = CString :: new ( "System Info" ) . unwrap ( ) ;
100+ let text3 = s ! ( "Smukx System Restored" ) ;
101+ let caption3 = s ! ( "System Info" ) ;
102+
100103 MessageBoxA (
101- null_mut ( ) ,
102- text3. as_ptr ( ) ,
103- caption3. as_ptr ( ) ,
104+ None ,
105+ text3,
106+ caption3,
104107 MB_OK | MB_ICONINFORMATION ,
105108 ) ;
106- }
107-
108- println ! ( "[INFO] PoC Demonstrated Successfully" ) ;
109+
110+ println ! ( "[INFO] PoC Demonstrated Successfully" ) ;
111+ }
109112
110113}
111114
112115fn setup_interceptor (
113- target_function : LPVOID ,
114- replacement_function : LPVOID ,
116+ target_function : * mut std :: ffi :: c_void ,
117+ replacement_function : * mut std :: ffi :: c_void ,
115118 interceptor : & mut ApiInterceptor ,
116- ) -> bool {
117- if target_function. is_null ( ) || replacement_function. is_null ( ) {
119+ ) -> bool {
120+ if target_function. is_null ( ) || replacement_function. is_null ( ) {
118121 return false ;
119122 }
120123
121124 interceptor. target_function = target_function;
122125 interceptor. replacement_function = replacement_function;
123126
124127 unsafe {
125- std :: ptr :: copy_nonoverlapping (
128+ copy_nonoverlapping (
126129 target_function as * const u8 ,
127130 interceptor. original_code . as_mut_ptr ( ) ,
128131 INTERCEPTOR_SIZE ,
129132 ) ;
130133
131- let mut old_protection: DWORD = 0 ;
132- if VirtualProtect (
134+ let mut old_protection = PAGE_PROTECTION_FLAGS ( 0 ) ;
135+ if let Err ( e ) = VirtualProtect (
133136 target_function,
134137 INTERCEPTOR_SIZE ,
135138 PAGE_EXECUTE_READWRITE ,
136139 & mut old_protection,
137- ) == 0
138- {
139- println ! ( "[!] Memory protection change failed: {}" , GetLastError ( ) ) ;
140+
141+ ) {
142+ println ! ( "[!] Memory Protection change failed: {:? }" , e ) ;
140143 return false ;
141144 }
145+
142146 interceptor. original_protection = old_protection;
143147 }
144148 true
@@ -150,24 +154,30 @@ fn activate_interceptor(interceptor: &mut ApiInterceptor) -> bool {
150154 }
151155
152156 unsafe {
153- {
154- let interceptor_code: [ u8 ; INTERCEPTOR_SIZE ] = [
155- 0xFF , 0x25 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
156- ] ;
157- let patch = interceptor. replacement_function as u64 ;
158- std:: ptr:: copy_nonoverlapping (
159- & patch as * const _ as * const u8 ,
160- ( interceptor. target_function as * mut u8 ) . offset ( 6 ) ,
161- std:: mem:: size_of :: < u64 > ( ) ,
162- ) ;
163-
164- std:: ptr:: copy_nonoverlapping (
165- interceptor_code. as_ptr ( ) ,
166- interceptor. target_function as * mut u8 ,
167- 6 ,
168- ) ;
169- }
157+ // far jump instruction (JMP)
158+ // 6 bytes for the JMP instruction (0xFF 0x25 0x00 0x00 0x00 0x00).
159+ // 8 bytes for the 64-bit address of the target function.
160+
161+ let interceptor_code: [ u8 ; INTERCEPTOR_SIZE ] = [
162+ // JMP [RIP + 0]
163+ 0xFF , 0x25 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
164+ ] ;
165+
166+ let patch = interceptor. replacement_function as u64 ;
167+
168+ copy_nonoverlapping (
169+ & patch as * const _ as * const u8 ,
170+ ( interceptor. target_function as * mut u8 ) . offset ( 6 ) ,
171+ std:: mem:: size_of :: < u64 > ( ) ,
172+ ) ;
173+
174+ copy_nonoverlapping (
175+ interceptor_code. as_ptr ( ) ,
176+ interceptor. target_function as * mut u8 ,
177+ 6 ,
178+ ) ;
170179 }
180+
171181 true
172182}
173183
@@ -177,59 +187,55 @@ fn deactivate_interceptor(interceptor: &mut ApiInterceptor) -> bool {
177187 }
178188
179189 unsafe {
180- std :: ptr :: copy_nonoverlapping (
190+ copy_nonoverlapping (
181191 interceptor. original_code . as_ptr ( ) ,
182192 interceptor. target_function as * mut u8 ,
183193 INTERCEPTOR_SIZE ,
184194 ) ;
185195
186196 std:: ptr:: write_bytes ( interceptor. original_code . as_mut_ptr ( ) , 0 , INTERCEPTOR_SIZE ) ;
187197
188- let mut old_protection: DWORD = 0 ;
189- if VirtualProtect (
198+ let mut old_protection = PAGE_PROTECTION_FLAGS ( 0 ) ;
199+ if let Err ( e ) = VirtualProtect (
190200 interceptor. target_function ,
191201 INTERCEPTOR_SIZE ,
192202 interceptor. original_protection ,
193203 & mut old_protection,
194- ) == 0
195- {
196- println ! (
197- "[!] Memory protection restoration failed: {}" ,
198- GetLastError ( )
199- ) ;
204+ ) {
205+ println ! ( "[!] Memory protection restoration failed: {:?}" , e) ;
200206 return false ;
201207 }
202208
203209 interceptor. target_function = null_mut ( ) ;
204210 interceptor. replacement_function = null_mut ( ) ;
205- interceptor. original_protection = 0 ;
211+ interceptor. original_protection = PAGE_PROTECTION_FLAGS ( 0 ) ;
206212 }
207213
208214 true
209215}
210216
211217unsafe extern "system" fn custom_dialog (
212218 hwnd : HWND ,
213- lp_text : LPCSTR ,
214- lp_caption : LPCSTR ,
215- u_type : UINT ,
219+ lp_text : PCSTR ,
220+ lp_caption : PCSTR ,
221+ u_type : u32 ,
216222) -> i32 {
217- let text = unsafe { CStr :: from_ptr ( lp_text) } . to_string_lossy ( ) ;
218- let caption = unsafe { CStr :: from_ptr ( lp_caption) } . to_string_lossy ( ) ;
223+ let text = unsafe { lp_text. to_string ( ) . unwrap_or_default ( ) } ;
224+ let caption = unsafe { lp_caption. to_string ( ) . unwrap_or_default ( ) } ;
219225
220226 println ! ( "[INFO] Dialog Parameters:" ) ;
221227 println ! ( "\t Text: {}" , text) ;
222228 println ! ( "\t Caption: {}" , caption) ;
223229
224- let new_text = WideCString :: from_str ( "Smukx Is Good" ) . unwrap ( ) ;
230+ let new_text = WideCString :: from_str ( "5mukx Is a Good Guy " ) . unwrap ( ) ;
225231 let new_caption = WideCString :: from_str ( "System Dialog" ) . unwrap ( ) ;
226232
227233 unsafe {
228234 MessageBoxW (
229- hwnd,
230- new_text. as_ptr ( ) as LPWSTR ,
231- new_caption. as_ptr ( ) as LPWSTR ,
232- u_type,
233- )
235+ Some ( hwnd) ,
236+ PCWSTR :: from_raw ( new_text. as_ptr ( ) ) ,
237+ PCWSTR :: from_raw ( new_caption. as_ptr ( ) ) ,
238+ windows :: Win32 :: UI :: WindowsAndMessaging :: MESSAGEBOX_STYLE ( u_type) ,
239+ ) . 0
234240 }
235- }
241+ }
0 commit comments