From f777d9ecf82155f78f7c4468a76bd638dcde1467 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Fri, 25 Apr 2025 22:14:28 -0700 Subject: [PATCH] Trim, switch from std to core --- runner/Cargo.lock | 74 ---------------------------------------------- runner/Cargo.toml | 14 +++++++-- runner/build.rs | 21 +------------ runner/src/main.rs | 71 +++++++++++++++++--------------------------- 4 files changed, 39 insertions(+), 141 deletions(-) diff --git a/runner/Cargo.lock b/runner/Cargo.lock index 5829455..3fee2ef 100644 --- a/runner/Cargo.lock +++ b/runner/Cargo.lock @@ -2,78 +2,13 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "proc-macro2" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - [[package]] name = "runner" version = "0.1.0" dependencies = [ "windows-sys", - "winres", ] -[[package]] -name = "serde" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - [[package]] name = "windows-sys" version = "0.59.0" @@ -146,12 +81,3 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winres" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" -dependencies = [ - "toml", -] diff --git a/runner/Cargo.toml b/runner/Cargo.toml index 24ae140..199f958 100644 --- a/runner/Cargo.toml +++ b/runner/Cargo.toml @@ -3,8 +3,16 @@ name = "runner" version = "0.1.0" edition = "2021" +[profile.dev] +panic = "abort" + +[profile.release] +# source: https://github.com/johnthagen/min-sized-rust +panic = "abort" +opt-level = "z" +strip = true +lto = true +codegen-units = 1 + [dependencies] windows-sys = {version="0.59.0", features=["Win32_System_Memory", "Win32_System_LibraryLoader", "Win32_System_Diagnostics_ToolHelp", "Win32_System_Threading", "Win32_System_Diagnostics_Debug", "Win32_Security"]} - -[build-dependencies] -winres = "0.1.12" diff --git a/runner/build.rs b/runner/build.rs index 6752c62..a48ee3b 100644 --- a/runner/build.rs +++ b/runner/build.rs @@ -1,22 +1,3 @@ -extern crate winres; - fn main() { - /* - let mut res = winres::WindowsResource::new(); - res.set_manifest( - r#" - - - - - - - - - - "#, - ); - res.compile() - .expect("expected to be able to build resources"); - */ + println!("cargo:rustc-link-arg=-s") } diff --git a/runner/src/main.rs b/runner/src/main.rs index 46001a9..af29bcf 100644 --- a/runner/src/main.rs +++ b/runner/src/main.rs @@ -1,11 +1,13 @@ -use core::str; -use std::ffi::{c_void, CStr}; -use std::marker::PhantomData; -use std::mem::MaybeUninit; -use std::ptr; -use std::{fs::File, io::Read}; +#![no_std] +#![no_main] + +use core::ffi::{c_void, CStr}; +use core::marker::PhantomData; +use core::mem::MaybeUninit; +#[cfg(not(test))] +use core::panic::PanicInfo; +use core::ptr; -use windows_sys::Win32::Foundation::GetLastError; use windows_sys::Win32::System::Diagnostics::Debug; use windows_sys::Win32::System::Diagnostics::ToolHelp::{self, PROCESSENTRY32}; use windows_sys::Win32::System::Memory; @@ -15,8 +17,10 @@ use windows_sys::Win32::System::{LibraryLoader, Threading}; const LOAD_LIBRARY_A: *const c_void = LibraryLoader::LoadLibraryA as *const c_void; const GET_PROC_ADDRESS: *const c_void = LibraryLoader::GetProcAddress as *const c_void; -fn main() { +#[no_mangle] +pub extern "C" fn WinMain() -> i32 { unsafe { _main_remote() } + 0 } struct Reader<'a> { @@ -40,11 +44,11 @@ impl<'a> Reader<'a> { } self.ptr = self.ptr.byte_add(1); n += 1; // include the null terminator - return std::slice::from_raw_parts(start, n); + return core::slice::from_raw_parts(start, n); } } -struct LocalWriter { +struct Writer { binary: *mut u8, base: *mut u8, ptr: *mut u8, @@ -53,20 +57,18 @@ struct Measurer { count: usize, } -impl Measurer {} - trait CodeGen { unsafe fn write(&mut self, u8s: &[u8]) -> *const c_void; unsafe fn write_ptr(&mut self, ptr: *const c_void) -> *const c_void { - let bytes = unsafe { std::mem::transmute::<*const c_void, [u8; 8]>(ptr) }; + let bytes = unsafe { core::mem::transmute::<*const c_void, [u8; 8]>(ptr) }; self.write(&bytes) } unsafe fn address_in_binary(&mut self, offset: usize) -> *const c_void; } -impl CodeGen for LocalWriter { +impl CodeGen for Writer { unsafe fn write(&mut self, u8s: &[u8]) -> *const c_void { let addr = self.ptr; for u in u8s { @@ -98,7 +100,6 @@ unsafe fn write_imports( reader: &mut Reader, ) { let entry_point = reader.read::(); - println!("entry point: {}", entry_point); // push rbp prelude.write(&[0x55]); // mov rbp, rsp @@ -114,7 +115,6 @@ unsafe fn write_imports( if dll.len() == 1 { break; } - println!("import dll: {:?}", str::from_utf8(dll).unwrap()); let library_addr = strings.write(dll); strings.write(&[0]); @@ -123,7 +123,6 @@ unsafe fn write_imports( if symbol.len() == 1 { break; } - println!("import symbol: {:?}", str::from_utf8(symbol).unwrap()); let dest = reader.read::(); let symbol_addr = strings.write(symbol); @@ -173,7 +172,7 @@ unsafe fn write_starting_state(mut out: *mut u8, reader: &mut Reader) { if code > 0 { // RLE: repeat let byte = reader.read::(); - for i in 0..code { + for _ in 0..code { *out = byte; out = out.byte_add(1); } @@ -204,18 +203,12 @@ unsafe fn _main_remote() { &mut measuring_reader, ); let starting_state_len = measuring_reader.read::() as usize; - println!("starting state len: {}", starting_state_len); - // string_measurer.round_up(); - // code_measurer.round_up(); - // TODO: Alignment let Some(victim) = identify_victim() else { - println!("couldn't find victim"); return; }; let remote = Threading::OpenProcess(PROCESS_ALL_ACCESS, 0, victim); if remote == ptr::null_mut() { - println!("got null"); return; } let total_size = starting_state_len as usize + string_measurer.count + code_measurer.count; @@ -240,30 +233,22 @@ unsafe fn _main_remote() { let strings = local_address_space.byte_add(starting_state_len); let prelude = strings.byte_add(string_measurer.count); - let mut strings_writer = LocalWriter { + let mut strings_writer = Writer { binary: remote_address_space as *mut u8, base: local_address_space as *mut u8, ptr: strings as *mut u8, }; - let mut prelude_writer = LocalWriter { + let mut prelude_writer = Writer { binary: remote_address_space as *mut u8, base: local_address_space as *mut u8, ptr: prelude as *mut u8, }; - println!("writing imports"); write_imports( &mut strings_writer, &mut prelude_writer, &mut loading_reader, ); - println!("writing starting state"); write_starting_state(local_address_space as *mut u8, &mut loading_reader); - println!("done!"); - println!("error: {}", GetLastError()); - println!( - "Copying memory to foreign process (at {:?} from {:?} get {:?})", - remote_address_space, local_address_space, total_size - ); Debug::WriteProcessMemory( remote, remote_address_space, @@ -271,17 +256,13 @@ unsafe fn _main_remote() { total_size, ptr::null_mut(), ); - println!("error: {}", GetLastError()); - println!("Creating remote thread"); - let entry_point = remote_address_space.byte_offset(prelude.byte_offset_from(local_address_space)); - println!("Entry point: {:?}", entry_point); Threading::CreateRemoteThread( remote, ptr::null(), 0, - Some(std::mem::transmute::< + Some(core::mem::transmute::< *mut c_void, unsafe extern "system" fn(*mut c_void) -> u32, >(entry_point)), @@ -289,20 +270,16 @@ unsafe fn _main_remote() { 0, ptr::null_mut(), ); - println!("error: {}", GetLastError()); - println!("Done!"); } unsafe fn identify_victim() -> Option { let snapshot = ToolHelp::CreateToolhelp32Snapshot(ToolHelp::TH32CS_SNAPPROCESS, 0); let mut entry: MaybeUninit = MaybeUninit::uninit(); - entry.assume_init_mut().dwSize = std::mem::size_of::() as u32; + entry.assume_init_mut().dwSize = core::mem::size_of::() as u32; let mut process = ToolHelp::Process32First(snapshot, entry.as_mut_ptr()); - println!("error: {}; process: {}", GetLastError(), process); while process != 0 { let entry_ref = entry.assume_init_ref(); let name = CStr::from_ptr(entry_ref.szExeFile.as_ptr()); - println!("peeking: {:?}", name); if name.eq(CStr::from_bytes_with_nul_unchecked(b"notepad.exe\x00")) { return Some(entry_ref.th32ProcessID); } @@ -310,3 +287,9 @@ unsafe fn identify_victim() -> Option { } return None; } + +#[cfg(not(test))] +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop {} +}