()
| 29 | pub type DbgPrintFn = extern "C" fn(Format: *const u8, ...) -> NTSTATUS; |
| 30 | #[no_mangle] |
| 31 | pub extern "C" fn main() -> ! { |
| 32 | unsafe { |
| 33 | // clean argc and argv |
| 34 | asm!("mov rcx, 0", "mov rdx, 0",); |
| 35 | } |
| 36 | let KERNEL32_STR: [u16; 13] = [75, 69, 82, 78, 69, 76, 51, 50, 46, 68, 76, 76, 0]; |
| 37 | let kernel32_ptr = get_module_by_name(KERNEL32_STR.as_ptr()); |
| 38 | let dbg_addr = get_func_by_name(kernel32_ptr, OutputDebugStringA_.as_ptr()); |
| 39 | let load_library_ptr = get_func_by_name(kernel32_ptr, LoadLibraryA_.as_ptr()); |
| 40 | let get_proc = get_func_by_name(kernel32_ptr, GetProcAddress_.as_ptr()); |
| 41 | let LoadLibraryA: LoadLibraryAFn = unsafe { core::mem::transmute(load_library_ptr) }; |
| 42 | |
| 43 | // make stack align |
| 44 | unsafe { asm!("and rsp, ~0xf") }; |
| 45 | let u32_dll = LoadLibraryA(USER32_DLL.as_ptr() as *const i8); |
| 46 | let GetProcAddress: GetProcAddressFn = unsafe { core::mem::transmute(get_proc) }; |
| 47 | let message_box_ptr = GetProcAddress(u32_dll, MessageBoxA_.as_ptr() as *const i8); |
| 48 | let MessageBoxA: MessageBoxAFn = unsafe { core::mem::transmute(message_box_ptr) }; |
| 49 | |
| 50 | let OutputDebugStringA: OutputDebugStringAFn = unsafe { core::mem::transmute(dbg_addr) }; |
| 51 | #[macro_export] |
| 52 | macro_rules! debug_print { |
| 53 | ($msg:expr) => { |
| 54 | OutputDebugStringA(concat!($msg, "\n\0").as_ptr() as _) |
| 55 | }; |
| 56 | } |
| 57 | debug_print!("We made it! see me in DebugView or Debugger"); |
| 58 | debug_print!("Let's popup a messagebox"); |
| 59 | MessageBoxA( |
| 60 | null_mut(), |
| 61 | "Windows Shellcode with Rust!\0".as_ptr() as *const i8, |
| 62 | "rocks\0".as_ptr() as _, |
| 63 | 0x30, |
| 64 | ); |
| 65 | loop {} |
| 66 | } |
| 67 | |
| 68 | fn get_module_by_name(module_name: *const u16) -> PVOID { |
| 69 | let peb: *mut PEB; |
nothing calls this directly
no test coverage detected