├── README.md ├── fault_test ├── Cargo.toml └── src │ └── main.rs └── win_fault_test ├── Cargo.toml └── src └── main.rs /README.md: -------------------------------------------------------------------------------- 1 | # binary 2 | some AV / EDR / analysis related experiences 3 | 4 | ## fault_test: 5 | trigger a access violation, catch with a custom handler and continue the normal execution of the program, debugger will stop at the access violation (UNIX) 6 | 7 | ## win_fault_test 8 | trigger a access violation, catch with a custom handler and continue the normal execution of the program, debugger will stop at the access violation (Windows) 9 | 10 | ![image](https://github.com/demon-i386/evasions/assets/75624951/4122717d-774b-476c-8249-092d7e089702) 11 | 12 | ![image](https://github.com/demon-i386/evasions/assets/75624951/c23a0361-7cfb-4bb4-a41d-a74c7dfe5aeb) 13 | -------------------------------------------------------------------------------- /fault_test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fault_test" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | libc = "0.2.144" 10 | nix = "0.26.2" 11 | -------------------------------------------------------------------------------- /fault_test/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate libc; 2 | extern crate nix; 3 | 4 | use nix::sys::signal::*; 5 | use std::ptr; 6 | use std::arch::asm; 7 | 8 | #[no_mangle] 9 | fn doMath(){ 10 | let a = 1; 11 | let b = 2; 12 | println!("Result: {}", a+b); 13 | } 14 | 15 | #[no_mangle] 16 | unsafe fn segfault() { 17 | let p: *const u32 = ptr::null(); 18 | 19 | // read_volative não é otimizado, portanto será executado 20 | let _ = std::ptr::read_volatile(p); 21 | } 22 | 23 | #[no_mangle] 24 | extern "C" fn handle_sigsegv(_: libc::c_int, _: *mut libc::siginfo_t, context: *mut libc::c_void) { 25 | unsafe { 26 | let context = &mut *(context as *mut libc::ucontext_t); 27 | 28 | // definindo RIP para o nopslide 29 | context.uc_mcontext.gregs[libc::REG_RIP as usize] += 3; 30 | } 31 | println!("Caught segfault, but continuing execution!"); 32 | } 33 | 34 | fn main() { 35 | let sa = SigAction::new(SigHandler::SigAction(handle_sigsegv), SaFlags::SA_ONSTACK, SigSet::empty()); 36 | unsafe { sigaction(Signal::SIGSEGV, &sa).expect("Failed to set signal handler"); } 37 | 38 | unsafe { segfault(); } 39 | unsafe { 40 | asm!( 41 | "nop", 42 | "nop", 43 | "nop", 44 | "nop", 45 | "nop", 46 | "nop", 47 | "nop", 48 | "nop", 49 | "nop", 50 | "nop", 51 | "nop", 52 | "nop", 53 | "nop", 54 | "nop", 55 | "nop", 56 | "nop", 57 | "nop", 58 | "nop", 59 | "nop", 60 | "nop", 61 | "nop", 62 | "nop", 63 | ); 64 | } 65 | 66 | println!("Program continues running"); 67 | doMath(); 68 | } 69 | -------------------------------------------------------------------------------- /win_fault_test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "win_fault_test" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | winapi = { version = "0.3.9", features = ["excpt", "minwindef", "minwinbase", "winnt", "errhandlingapi"] } 10 | -------------------------------------------------------------------------------- /win_fault_test/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate winapi; 2 | use std::arch::asm; 3 | use winapi::vc::excpt::EXCEPTION_CONTINUE_EXECUTION; 4 | use winapi::um::winnt::PEXCEPTION_POINTERS; 5 | use winapi::um::errhandlingapi::AddVectoredExceptionHandler; 6 | use winapi::um::winnt::CONTEXT; 7 | use winapi::um::minwinbase::EXCEPTION_ACCESS_VIOLATION; 8 | use winapi::vc::excpt::ExceptionContinueExecution; 9 | use winapi::um::winnt::EXCEPTION_POINTERS; 10 | use winapi::um::winnt::EXCEPTION_RECORD; 11 | use winapi::vc::excpt::EXCEPTION_DISPOSITION; 12 | use std::ptr; 13 | 14 | #[no_mangle] 15 | pub unsafe extern "system" fn seh_handler(exception_info: PEXCEPTION_POINTERS) -> i32 { 16 | if (*(*exception_info).ExceptionRecord).ExceptionCode == EXCEPTION_ACCESS_VIOLATION { 17 | println!("Caught segfault, but continuing execution!"); 18 | 19 | // Define RIP to nopslide 20 | (*(*exception_info).ContextRecord).Rip += 3; 21 | 22 | return EXCEPTION_CONTINUE_EXECUTION; 23 | } 24 | // Return ExceptionContinueSearch if not EXCEPTION_ACCESS_VIOLATION 25 | 0 26 | } 27 | 28 | fn segfault() { 29 | unsafe { 30 | let p: *const u32 = ptr::null(); 31 | 32 | // Read_volatile is not optimized, so it will be executed 33 | let _ = std::ptr::read_volatile(p); 34 | } 35 | } 36 | 37 | fn main() { 38 | // Set up a Vectored Exception Handler 39 | unsafe { 40 | AddVectoredExceptionHandler(1, Some(seh_handler)); 41 | } 42 | segfault(); 43 | 44 | // A series of no operation (nop) instructions 45 | unsafe { 46 | asm!( 47 | "nop", 48 | "nop", 49 | "nop", 50 | "nop", 51 | "nop", 52 | "nop", 53 | "nop", 54 | "nop", 55 | "nop", 56 | "nop", 57 | "nop", 58 | "nop", 59 | "nop", 60 | "nop", 61 | "nop", 62 | "nop", 63 | "nop", 64 | "nop", 65 | "nop", 66 | "nop", 67 | "nop", 68 | "nop", 69 | ); 70 | } 71 | 72 | println!("Program continues running"); 73 | do_math(); 74 | segfault(); 75 | } 76 | 77 | #[no_mangle] 78 | pub fn do_math() { 79 | let a = 1; 80 | let b = 2; 81 | println!("Result: {}", a + b); 82 | } 83 | --------------------------------------------------------------------------------