use { crate::{cli::Callbacks, driver::open_driver}, std::{ptr::null_mut, mem::size_of, ffi::c_void}, shared::structs::{CallbackInfoInput, CallbackInfoOutput}, windows_sys::Win32::{Foundation::CloseHandle, System::IO::DeviceIoControl}, }; pub fn enumerate_callback(ioctl_code: u32, callback: &Callbacks) { let h_file = open_driver().expect("Failed to open driver"); let mut return_buffer = 0; let mut callback_info: [CallbackInfoOutput; 400] = unsafe { std::mem::zeroed() }; let mut input_callback = CallbackInfoInput { index: 0, callback: callback.to_shared() }; let status = unsafe { DeviceIoControl( h_file, ioctl_code, &mut input_callback as *mut _ as *mut c_void, size_of::() as u32, callback_info.as_mut_ptr() as *mut _, (callback_info.len() * size_of::()) as u32, &mut return_buffer, null_mut() ) }; if status == 0 { eprintln!("[!] DeviceIoControl Failed with status: 0x{:08X}", status); } else { let total_module = return_buffer as usize / size_of::(); println!("[+] Total modules: {}", total_module); for i in callback_info.iter() { if i.address > 0 { let name = match String::from_utf16(&i.name) { Ok(name) => name.trim_end_matches('\0').to_string(), Err(err) => { eprintln!("[!] UTF-16 decoding error: {:?}", err); continue; } }; println!("[{}] {:?} {}", i.index, i.address as *mut c_void, name); } else if i.post_operation > 0 || i.pre_operation > 0 { let name = match String::from_utf16(&i.name) { Ok(name) => name.trim_end_matches('\0').to_string(), Err(err) => { eprintln!("[!] UTF-16 decoding error: {:?}", err); continue; } }; println!("[{}] {}", i.index, name); println!("\tpre_operation: {:?}", i.pre_operation as *mut c_void); println!("\tpost_operation: {:?}", i.post_operation as *mut c_void); } } } unsafe { CloseHandle(h_file); }; } pub fn remove_callback(index: usize, ioctl_code: u32, callback: &Callbacks) { let h_file = open_driver().expect("Failed to open driver"); let mut callback_info = CallbackInfoInput { index, callback: callback.to_shared() }; let mut return_buffer = 0; let status = unsafe { DeviceIoControl( h_file, ioctl_code, &mut callback_info as *mut _ as *mut c_void, size_of::() as u32, null_mut(), 0, &mut return_buffer, null_mut() ) }; if status == 0 { eprintln!("[!] DeviceIoControl Failed with status: 0x{:08X}", status); } unsafe { CloseHandle(h_file); }; } pub fn restore_callback(index: usize, ioctl_code: u32, callback: &Callbacks) { let h_file = open_driver().expect("Failed to open driver"); let mut callback_info = CallbackInfoInput { index, callback: callback.to_shared() }; let mut return_buffer = 0; let status = unsafe { DeviceIoControl( h_file, ioctl_code, &mut callback_info as *mut _ as *mut c_void, size_of::() as u32, null_mut(), 0, &mut return_buffer, null_mut() ) }; if status == 0 { eprintln!("[!] DeviceIoControl Failed with status: 0x{:08X}", status); } unsafe { CloseHandle(h_file); }; }