From 08d3bbf4e122eef2d7923a2880d427538ff5ba82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Victor?= Date: Sun, 8 Sep 2024 01:14:54 -0300 Subject: [PATCH] Splitting callbacks into files --- driver/src/callback/callbacks/mod.rs | 3 + .../src/callback/callbacks/notify_routine.rs | 167 +++++ driver/src/callback/callbacks/object.rs | 236 +++++++ driver/src/callback/callbacks/registry.rs | 214 ++++++ .../{callbacks => callback}/find_callback.rs | 0 driver/src/{callbacks => callback}/ioctls.rs | 0 driver/src/callback/mod.rs | 67 ++ driver/src/callbacks/mod.rs | 645 ------------------ driver/src/lib.rs | 2 +- driver/src/utils/ioctls.rs | 2 +- driver/src/utils/macros.rs | 4 +- 11 files changed, 691 insertions(+), 649 deletions(-) create mode 100644 driver/src/callback/callbacks/mod.rs create mode 100644 driver/src/callback/callbacks/notify_routine.rs create mode 100644 driver/src/callback/callbacks/object.rs create mode 100644 driver/src/callback/callbacks/registry.rs rename driver/src/{callbacks => callback}/find_callback.rs (100%) rename driver/src/{callbacks => callback}/ioctls.rs (100%) create mode 100644 driver/src/callback/mod.rs delete mode 100644 driver/src/callbacks/mod.rs diff --git a/driver/src/callback/callbacks/mod.rs b/driver/src/callback/callbacks/mod.rs new file mode 100644 index 0000000..c82e133 --- /dev/null +++ b/driver/src/callback/callbacks/mod.rs @@ -0,0 +1,3 @@ +pub mod notify_routine; +pub mod object; +pub mod registry; \ No newline at end of file diff --git a/driver/src/callback/callbacks/notify_routine.rs b/driver/src/callback/callbacks/notify_routine.rs new file mode 100644 index 0000000..323364e --- /dev/null +++ b/driver/src/callback/callbacks/notify_routine.rs @@ -0,0 +1,167 @@ +use { + core::mem::size_of, + ntapi::ntldr::LDR_DATA_TABLE_ENTRY, + shared::structs::{CallbackInfoInput, CallbackInfoOutput}, + wdk_sys::{ + NTSTATUS, STATUS_SUCCESS, STATUS_UNSUCCESSFUL + }, + crate::{ + callback::{ + find_callback::{find_callback_address, CallbackResult}, + CallbackList, INFO_CALLBACK_RESTAURE + }, + includes::structs::CallbackRestaure, utils::return_module + }, +}; + +/// Structure representing the Callback. +pub struct Callback; + +/// Implement a feature for the callback PsSetCreateProcessNotifyRoutine / PsSetCreateThreadNotifyRoutine / PsSetLoadImageNotifyRoutine. +impl CallbackList for Callback { + unsafe fn restore_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { + let mut callback_info = INFO_CALLBACK_RESTAURE.lock(); + let callback_type = (*target_callback).callback; + let index = (*target_callback).index; + + if let Some(index) = callback_info.iter().position(|c| c.callback == callback_type && c.index == index) { + let address = match find_callback_address(&(*target_callback).callback) { + Some(CallbackResult::PsCreate(addr)) => addr, + _ => return STATUS_UNSUCCESSFUL, + }; + + let addr = address.offset((callback_info[index].index * 8) as isize); + *(addr as *mut u64) = callback_info[index].address; + callback_info.remove(index); + } else { + log::error!("Callback not found for type {:?} at index {}", callback_type, index); + return STATUS_UNSUCCESSFUL; + } + + STATUS_SUCCESS + } + + unsafe fn remove_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { + let address = match find_callback_address(&(*target_callback).callback) { + Some(CallbackResult::PsCreate(addr)) => addr, + _ => return STATUS_UNSUCCESSFUL, + }; + + let index = (*target_callback).index as isize; + let addr = address.offset(index * 8); + let callback_restaure = CallbackRestaure { + index: (*target_callback).index, + callback: (*target_callback).callback, + address: *(addr as *mut u64), + ..Default::default() + }; + + let mut callback_info = INFO_CALLBACK_RESTAURE.lock(); + callback_info.push(callback_restaure); + + *(addr as *mut u64) = 0; + + log::info!("Callback removed at index {}", index); + + STATUS_SUCCESS + } + + unsafe fn enumerate_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { + let address = match find_callback_address(&(*target_callback).callback) { + Some(CallbackResult::PsCreate(addr)) => addr, + _ => return Err(STATUS_UNSUCCESSFUL), + }; + + let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; + let start_entry = ldr_data; + + for i in 0..64 { + let addr = address.cast::().offset(i * 8); + let callback = *(addr as *const u64); + + if callback == 0 { + continue; + } + + // Iterate over the loaded modules + for _ in 0..module_count { + let start_address = (*ldr_data).DllBase; + let image_size = (*ldr_data).SizeOfImage; + let end_address = start_address as u64 + image_size as u64; + let raw_pointer = *((callback & 0xfffffffffffffff8) as *const u64); + + if raw_pointer > start_address as u64 && raw_pointer < end_address { + let buffer = core::slice::from_raw_parts( + (*ldr_data).BaseDllName.Buffer, + ((*ldr_data).BaseDllName.Length / 2) as usize, + ); + + // Module name + let name = &mut (*callback_info.offset(i)).name[..buffer.len()]; + core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); + + // Module address + (*callback_info.offset(i)).address = raw_pointer as usize; + + // Module index + (*callback_info.offset(i)).index = i as u8; + + *information += size_of::(); + break; + } + + // Go to the next module in the list + ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; + } + + // Reset ldr_data for next callback + ldr_data = start_entry; + } + + Ok(()) + } + + unsafe fn enumerate_removed_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { + let callback_restaure = INFO_CALLBACK_RESTAURE.lock(); + + let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; + let start_entry = ldr_data; + + for (i, callback) in callback_restaure.iter().enumerate() { + for _ in 0..module_count { + let start_address = (*ldr_data).DllBase; + let image_size = (*ldr_data).SizeOfImage; + let end_address = start_address as u64 + image_size as u64; + let raw_pointer = *((callback.address & 0xfffffffffffffff8) as *const u64); + + if raw_pointer > start_address as u64 && raw_pointer < end_address { + let buffer = core::slice::from_raw_parts( + (*ldr_data).BaseDllName.Buffer, + ((*ldr_data).BaseDllName.Length / 2) as usize, + ); + + // Module name + let name = &mut (*callback_info.offset(i as isize)).name[..buffer.len()]; + core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); + + // Module address + (*callback_info.offset(i as isize)).address = raw_pointer as usize; + + // Module index + (*callback_info.offset(i as isize)).index = callback.index as u8; + + *information += size_of::(); + break; + } + + // Go to the next module in the list + ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; + } + + // Reset ldr_data for next callback + ldr_data = start_entry; + } + + Ok(()) + } +} \ No newline at end of file diff --git a/driver/src/callback/callbacks/object.rs b/driver/src/callback/callbacks/object.rs new file mode 100644 index 0000000..3c6ab5a --- /dev/null +++ b/driver/src/callback/callbacks/object.rs @@ -0,0 +1,236 @@ +use { + alloc::vec::Vec, + core::mem::size_of, + ntapi::ntldr::LDR_DATA_TABLE_ENTRY, + shared::structs::{CallbackInfoInput, CallbackInfoOutput}, + wdk_sys::{ + ntddk::{ExAcquirePushLockExclusiveEx, ExReleasePushLockExclusiveEx}, + NTSTATUS, STATUS_SUCCESS, STATUS_UNSUCCESSFUL + }, + crate::{ + callback::{ + find_callback::{find_callback_address, CallbackResult}, + CallbackList, INFO_CALLBACK_RESTAURE_OB + }, + includes::structs::{CallbackRestaureOb, OBCALLBACK_ENTRY}, utils::return_module + }, +}; + +/// Structure representing the Callback Object. +pub struct CallbackOb; + +/// Implement a feature for the callback ObRegisterCallbacks (PsProcessType / PsThreadType). +impl CallbackList for CallbackOb { + unsafe fn restore_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { + let mut callback_info = INFO_CALLBACK_RESTAURE_OB.lock(); + let callback_type = (*target_callback).callback; + let index = (*target_callback).index; + + if let Some(index) = callback_info.iter().position(|c| c.callback == callback_type && c.index == index) { + let object_type = match find_callback_address(&(*target_callback).callback) { + Some(CallbackResult::ObRegister(addr)) => addr, + _ => return STATUS_UNSUCCESSFUL, + }; + + let lock = &(*object_type).type_lock as *const _ as *mut u64; + ExAcquirePushLockExclusiveEx(lock, 0); + + let current = &mut ((*object_type).callback_list) as *mut _ as *mut OBCALLBACK_ENTRY; + let mut next = (*current).callback_list.Flink as *mut OBCALLBACK_ENTRY; + + while next != current { + if !(*next).enabled && !next.is_null() && (*next).entry as u64 == callback_info[index].entry { + (*next).enabled = true; + callback_info.remove(index); + ExReleasePushLockExclusiveEx(lock, 0); + return STATUS_SUCCESS; + } + + next = (*next).callback_list.Flink as *mut OBCALLBACK_ENTRY; + } + + ExReleasePushLockExclusiveEx(lock, 0); + } else { + log::error!("Callback not found for type {:?} at index {}", callback_type, index); + return STATUS_UNSUCCESSFUL; + } + + STATUS_UNSUCCESSFUL + } + + unsafe fn remove_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { + let object_type = match find_callback_address(&(*target_callback).callback) { + Some(CallbackResult::ObRegister(addr)) => addr, + _ => return STATUS_UNSUCCESSFUL, + }; + + let lock = &(*object_type).type_lock as *const _ as *mut u64; + ExAcquirePushLockExclusiveEx(lock, 0); + + let mut i = 0; + let index = (*target_callback).index; + let current = &mut ((*object_type).callback_list) as *mut _ as *mut OBCALLBACK_ENTRY; + let mut next = (*current).callback_list.Flink as *mut OBCALLBACK_ENTRY; + let mut callback_info = INFO_CALLBACK_RESTAURE_OB.lock(); + + while next != current { + if i == index { + if (*next).enabled { + let mut callback_restaure = CallbackRestaureOb { + index, + callback: (*target_callback).callback, + entry: (*next).entry as u64, + pre_operation: 0, + post_operation: 0 + }; + + if let Some(pre_op) = (*next).pre_operation { + callback_restaure.pre_operation = pre_op as _; + } + + if let Some(post_op) = (*next).post_operation { + callback_restaure.post_operation = post_op as _; + } + + (*next).enabled = false; + + callback_info.push(callback_restaure); + log::info!("Callback removed at index {}", index); + } + + ExReleasePushLockExclusiveEx(lock, 0); + + return STATUS_SUCCESS; + } + + next = (*next).callback_list.Flink as *mut OBCALLBACK_ENTRY; + i += 1; + } + + ExReleasePushLockExclusiveEx(lock, 0); + + STATUS_UNSUCCESSFUL + } + + unsafe fn enumerate_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { + let object_type = match find_callback_address(&(*target_callback).callback) { + Some(CallbackResult::ObRegister(addr)) => addr, + _ => return Err(STATUS_UNSUCCESSFUL), + }; + + let current = &mut ((*object_type).callback_list) as *mut _ as *mut OBCALLBACK_ENTRY; + let mut next = (*current).callback_list.Flink as *mut OBCALLBACK_ENTRY; + let mut list_objects = Vec::new(); + + while next != current { + let mut addrs = (0, 0); + if let Some(pre_op) = (*next).pre_operation { + addrs.0 = pre_op as u64; + } + + if let Some(post_op) = (*next).post_operation { + addrs.1 = post_op as u64; + } + + list_objects.push(((*next).enabled, addrs)); + + next = (*next).callback_list.Flink as *mut OBCALLBACK_ENTRY; + } + + let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; + let start_entry = ldr_data; + let mut current_index = 0; + + for (i, (enabled, addrs)) in list_objects.iter().enumerate() { + if !enabled { + current_index += 1; + continue; + } + + for _ in 0..module_count { + let start_address = (*ldr_data).DllBase; + let image_size = (*ldr_data).SizeOfImage; + let end_address = start_address as u64 + image_size as u64; + let pre = addrs.0; + let post = addrs.1; + + if pre > start_address as u64 && pre < end_address || + post > start_address as u64 && post < end_address + { + let buffer = core::slice::from_raw_parts( + (*ldr_data).BaseDllName.Buffer, + ((*ldr_data).BaseDllName.Length / 2) as usize, + ); + + // Module name + let name = &mut (*callback_info.offset(i as isize)).name[..buffer.len()]; + core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); + + // Module address + (*callback_info.offset(i as isize)).pre_operation = pre as usize; + (*callback_info.offset(i as isize)).post_operation = post as usize; + + // Module index + (*callback_info.offset(i as isize)).index = current_index as u8; + + *information += size_of::(); + current_index += 1; + break; + } + + // Go to the next module in the list + ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; + } + + // Reset ldr_data for next callback + ldr_data = start_entry; + } + + Ok(()) + } + + unsafe fn enumerate_removed_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { + let callback_restaure = INFO_CALLBACK_RESTAURE_OB.lock(); + + let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; + let start_entry = ldr_data; + + for (i, callback) in callback_restaure.iter().enumerate() { + for _ in 0..module_count { + let start_address = (*ldr_data).DllBase; + let image_size = (*ldr_data).SizeOfImage; + let end_address = start_address as u64 + image_size as u64; + + if callback.pre_operation > start_address as u64 && callback.pre_operation < end_address + || callback.post_operation > start_address as u64 && callback.post_operation < end_address + { + let buffer = core::slice::from_raw_parts( + (*ldr_data).BaseDllName.Buffer, + ((*ldr_data).BaseDllName.Length / 2) as usize, + ); + + // Module name + let name = &mut (*callback_info.offset(i as isize)).name[..buffer.len()]; + core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); + + // Module address + (*callback_info.offset(i as isize)).pre_operation = callback.pre_operation as usize; + (*callback_info.offset(i as isize)).post_operation = callback.post_operation as usize; + + // Module index + (*callback_info.offset(i as isize)).index = callback.index as u8; + + *information += size_of::(); + break; + } + // Go to the next module in the list + ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; + } + + // Reset ldr_data for next callback + ldr_data = start_entry; + } + + Ok(()) + } +} \ No newline at end of file diff --git a/driver/src/callback/callbacks/registry.rs b/driver/src/callback/callbacks/registry.rs new file mode 100644 index 0000000..4e93359 --- /dev/null +++ b/driver/src/callback/callbacks/registry.rs @@ -0,0 +1,214 @@ +use { + core::mem::size_of, + ntapi::ntldr::LDR_DATA_TABLE_ENTRY, + shared::structs::{CallbackInfoInput, CallbackInfoOutput}, + wdk_sys::{ + ntddk::{ExAcquirePushLockExclusiveEx, ExReleasePushLockExclusiveEx}, + NTSTATUS, STATUS_SUCCESS, STATUS_UNSUCCESSFUL + }, + crate::{ + callback::{ + find_callback::{find_callback_address, CallbackResult}, + CallbackList, INFO_CALLBACK_RESTAURE_REGISTRY + }, + includes::structs::{CallbackRestaure, CM_CALLBACK}, utils::return_module}, +}; + +/// Structure representing the Callback Registry. +pub struct CallbackRegistry; + +/// Implement a feature for the callback CmRegisterCallbackEx. +impl CallbackList for CallbackRegistry { + unsafe fn restore_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { + let mut callback_info = INFO_CALLBACK_RESTAURE_REGISTRY.lock(); + let callback_type = (*target_callback).callback; + let index = (*target_callback).index; + + if let Some(x) = callback_info.iter().position(|c| c.callback == callback_type && c.index == index) { + let (callback_list_header, callback_count, callback_list_lock) = match find_callback_address(&(*target_callback).callback) { + Some(CallbackResult::Registry(addr)) => addr, + _ => return STATUS_UNSUCCESSFUL, + }; + + ExAcquirePushLockExclusiveEx(callback_list_lock as _, 0); + + let count = *(callback_count as *mut u32) + 1; + let mut pcm_callback = callback_list_header as *mut CM_CALLBACK; + + for i in 0..count { + if pcm_callback.is_null() { + break; + } + + if i == index as u32 { + (*pcm_callback).function = callback_info[x].address; + callback_info.remove(x); + + ExReleasePushLockExclusiveEx(callback_list_lock as _, 0); + return STATUS_SUCCESS; + } + + pcm_callback = (*pcm_callback).list.Flink as *mut CM_CALLBACK; + } + + ExReleasePushLockExclusiveEx(callback_list_lock as _, 0); + + } else { + log::error!("Callback not found for type {:?} at index {}", callback_type, index); + return STATUS_UNSUCCESSFUL; + } + + STATUS_SUCCESS + } + + unsafe fn remove_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { + let (callback_list_header, callback_count, callback_list_lock) = match find_callback_address(&(*target_callback).callback) { + Some(CallbackResult::Registry(addr)) => addr, + _ => return STATUS_UNSUCCESSFUL, + }; + + ExAcquirePushLockExclusiveEx(callback_list_lock as _, 0); + + let index = (*target_callback).index as isize; + let count = *(callback_count as *mut u32) + 1; + let mut pcm_callback = callback_list_header as *mut CM_CALLBACK; + let mut callback_info = INFO_CALLBACK_RESTAURE_REGISTRY.lock(); + let mut prev_addr = 0; + + for i in 0..count { + if i == 1 { + prev_addr = (*pcm_callback).function as u64; // WdFilter.sys + } + + if pcm_callback.is_null() { + break; + } + + if i == index as u32 { + let addr = (*pcm_callback).function as u64; + let callback_restaure = CallbackRestaure { + index: (*target_callback).index, + callback: (*target_callback).callback, + address: addr, + ..Default::default() + }; + + (*pcm_callback).function = prev_addr; + callback_info.push(callback_restaure); + + log::info!("Callback removed at index {}", index); + ExReleasePushLockExclusiveEx(callback_list_lock as _, 0); + + return STATUS_SUCCESS; + } + + pcm_callback = (*pcm_callback).list.Flink as *mut CM_CALLBACK; + } + + ExReleasePushLockExclusiveEx(callback_list_lock as _, 0); + + STATUS_UNSUCCESSFUL + } + + unsafe fn enumerate_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { + let (callback_list_header, callback_count, callback_list_lock) = match find_callback_address(&(*target_callback).callback) { + Some(CallbackResult::Registry(addr)) => addr, + _ => return Err(STATUS_UNSUCCESSFUL), + }; + + let count = *(callback_count as *mut u32) + 1; + let mut pcm_callback = callback_list_header as *mut CM_CALLBACK; + let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; + let start_entry = ldr_data; + + ExAcquirePushLockExclusiveEx(callback_list_lock as _, 0); + + for i in 0..count as isize { + if pcm_callback.is_null() { + break; + } + // Iterate over the loaded modules + for _ in 0..module_count { + let start_address = (*ldr_data).DllBase; + let image_size = (*ldr_data).SizeOfImage; + let end_address = start_address as u64 + image_size as u64; + let addr = (*pcm_callback).function as u64; + + if addr > start_address as u64 && addr < end_address { + let buffer = core::slice::from_raw_parts( + (*ldr_data).BaseDllName.Buffer, + ((*ldr_data).BaseDllName.Length / 2) as usize, + ); + + // Module name + let name = &mut (*callback_info.offset(i)).name[..buffer.len()]; + core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); + + // Module address + (*callback_info.offset(i)).address = addr as usize; + + // Module index + (*callback_info.offset(i)).index = i as u8; + + *information += size_of::(); + break; + } + + // Go to the next module in the list + ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; + } + + // Reset ldr_data for next callback + ldr_data = start_entry; + + pcm_callback = (*pcm_callback).list.Flink as *mut CM_CALLBACK; + } + + ExReleasePushLockExclusiveEx(callback_list_lock as _, 0); + + Ok(()) + } + + unsafe fn enumerate_removed_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { + let callback_restaure = INFO_CALLBACK_RESTAURE_REGISTRY.lock(); + + let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; + + let start_entry = ldr_data; + + for (i, callback) in callback_restaure.iter().enumerate() { + for _ in 0..module_count { + let start_address = (*ldr_data).DllBase; + let image_size = (*ldr_data).SizeOfImage; + let end_address = start_address as u64 + image_size as u64; + + if callback.address > start_address as u64 && callback.address < end_address { + let buffer = core::slice::from_raw_parts( + (*ldr_data).BaseDllName.Buffer, + ((*ldr_data).BaseDllName.Length / 2) as usize, + ); + + // Module name + let name = &mut (*callback_info.offset(i as isize)).name[..buffer.len()]; + core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); + + // Module address + (*callback_info.offset(i as isize)).address = callback.address as usize; + + // Module index + (*callback_info.offset(i as isize)).index = callback.index as u8; + + *information += size_of::(); + break; + } + // Go to the next module in the list + ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; + } + + // Reset ldr_data for next callback + ldr_data = start_entry; + } + + Ok(()) + } +} diff --git a/driver/src/callbacks/find_callback.rs b/driver/src/callback/find_callback.rs similarity index 100% rename from driver/src/callbacks/find_callback.rs rename to driver/src/callback/find_callback.rs diff --git a/driver/src/callbacks/ioctls.rs b/driver/src/callback/ioctls.rs similarity index 100% rename from driver/src/callbacks/ioctls.rs rename to driver/src/callback/ioctls.rs diff --git a/driver/src/callback/mod.rs b/driver/src/callback/mod.rs new file mode 100644 index 0000000..14e95fa --- /dev/null +++ b/driver/src/callback/mod.rs @@ -0,0 +1,67 @@ +use { + alloc::vec::Vec, + crate::includes::structs::{CallbackRestaure, CallbackRestaureOb}, + shared::structs::{CallbackInfoInput, CallbackInfoOutput}, + spin::{lazy::Lazy, Mutex}, wdk_sys::NTSTATUS, +}; + +mod find_callback; +pub mod ioctls; +pub mod callbacks; + +/// Variable that stores callbacks that have been removed. +pub static mut INFO_CALLBACK_RESTAURE: Lazy>> = Lazy::new(|| Mutex::new(Vec::with_capacity(40))); + +/// Variable that stores callbacks registry that have been removed. +static mut INFO_CALLBACK_RESTAURE_REGISTRY: Lazy>> = Lazy::new(|| Mutex::new(Vec::with_capacity(40))); + +/// Variable that stores callbacks Ob that have been removed. +static mut INFO_CALLBACK_RESTAURE_OB: Lazy>> = Lazy::new(|| Mutex::new(Vec::with_capacity(40))); + +/// Trait defining common operations for callback lists. +pub trait CallbackList { + /// Restore a callback from the specified routine. + /// + /// # Parameters + /// - `target_callback`: Pointer to the callback information input. + /// + /// # Returns + /// - `NTSTATUS`: Status of the operation. `STATUS_SUCCESS` if successful, `STATUS_UNSUCCESSFUL` otherwise. + /// + unsafe fn restore_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS; + + /// Removes a callback from the specified routine. + /// + /// # Parameters + /// - `target_callback`: Pointer to the callback information input. + /// + /// # Returns + /// - `NTSTATUS`: Status of the operation. `STATUS_SUCCESS` if successful, `STATUS_UNSUCCESSFUL` otherwise. + /// + unsafe fn remove_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS; + + /// Searches for a module associated with a callback and updates callback information. + /// + /// # Parameters + /// - `target_callback`: Pointer to the callback information input. + /// - `callback_info`: Pointer to the callback information output. + /// - `information`: Pointer to a variable to store information size. + /// + /// # Returns + /// - `NTSTATUS`: Status of the operation. `STATUS_SUCCESS` if successful, `STATUS_UNSUCCESSFUL` otherwise. + /// + unsafe fn enumerate_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS>; + + /// List of callbacks currently removed. + /// + /// # Parameters + /// - `target_callback`: Pointer to the callback information input. + /// - `callback_info`: Pointer to the callback information output. + /// - `information`: Pointer to a variable to store information size. + /// + /// # Returns + /// - `NTSTATUS`: Status of the operation. `STATUS_SUCCESS` if successful, `STATUS_UNSUCCESSFUL` otherwise. + /// + unsafe fn enumerate_removed_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS>; +} + diff --git a/driver/src/callbacks/mod.rs b/driver/src/callbacks/mod.rs deleted file mode 100644 index 0bd5cfb..0000000 --- a/driver/src/callbacks/mod.rs +++ /dev/null @@ -1,645 +0,0 @@ -use { - crate::{ - includes::structs::{CallbackRestaure, CallbackRestaureOb, CM_CALLBACK, OBCALLBACK_ENTRY}, - utils::return_module - }, - alloc::vec::Vec, - core::mem::size_of, - find_callback::{find_callback_address, CallbackResult}, - ntapi::ntldr::LDR_DATA_TABLE_ENTRY, - shared::structs::{CallbackInfoInput, CallbackInfoOutput}, - spin::{lazy::Lazy, Mutex}, - wdk_sys::{ - ntddk::{ExAcquirePushLockExclusiveEx, ExReleasePushLockExclusiveEx}, - NTSTATUS, STATUS_SUCCESS, STATUS_UNSUCCESSFUL - } -}; - -mod find_callback; -pub mod ioctls; - -/// Variable that stores callbacks that have been removed. -static mut INFO_CALLBACK_RESTAURE: Lazy>> = Lazy::new(|| Mutex::new(Vec::with_capacity(40))); - -/// Variable that stores callbacks registry that have been removed. -static mut INFO_CALLBACK_RESTAURE_REGISTRY: Lazy>> = Lazy::new(|| Mutex::new(Vec::with_capacity(40))); - -/// Variable that stores callbacks Ob that have been removed. -static mut INFO_CALLBACK_RESTAURE_OB: Lazy>> = Lazy::new(|| Mutex::new(Vec::with_capacity(40))); - -/// Trait defining common operations for callback lists. -pub trait CallbackList { - /// Restore a callback from the specified routine. - /// - /// # Parameters - /// - `target_callback`: Pointer to the callback information input. - /// - /// # Returns - /// - `NTSTATUS`: Status of the operation. `STATUS_SUCCESS` if successful, `STATUS_UNSUCCESSFUL` otherwise. - /// - unsafe fn restore_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS; - - /// Removes a callback from the specified routine. - /// - /// # Parameters - /// - `target_callback`: Pointer to the callback information input. - /// - /// # Returns - /// - `NTSTATUS`: Status of the operation. `STATUS_SUCCESS` if successful, `STATUS_UNSUCCESSFUL` otherwise. - /// - unsafe fn remove_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS; - - /// Searches for a module associated with a callback and updates callback information. - /// - /// # Parameters - /// - `target_callback`: Pointer to the callback information input. - /// - `callback_info`: Pointer to the callback information output. - /// - `information`: Pointer to a variable to store information size. - /// - /// # Returns - /// - `NTSTATUS`: Status of the operation. `STATUS_SUCCESS` if successful, `STATUS_UNSUCCESSFUL` otherwise. - /// - unsafe fn enumerate_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS>; - - /// List of callbacks currently removed. - /// - /// # Parameters - /// - `target_callback`: Pointer to the callback information input. - /// - `callback_info`: Pointer to the callback information output. - /// - `information`: Pointer to a variable to store information size. - /// - /// # Returns - /// - `NTSTATUS`: Status of the operation. `STATUS_SUCCESS` if successful, `STATUS_UNSUCCESSFUL` otherwise. - /// - unsafe fn enumerate_removed_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS>; -} - -/// Structure representing the Callback. -pub struct Callback; - -/// Implement a feature for the callback PsSetCreateProcessNotifyRoutine / PsSetCreateThreadNotifyRoutine / PsSetLoadImageNotifyRoutine. -impl CallbackList for Callback { - unsafe fn restore_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { - let mut callback_info = INFO_CALLBACK_RESTAURE.lock(); - let callback_type = (*target_callback).callback; - let index = (*target_callback).index; - - if let Some(index) = callback_info.iter().position(|c| c.callback == callback_type && c.index == index) { - let address = match find_callback_address(&(*target_callback).callback) { - Some(CallbackResult::PsCreate(addr)) => addr, - _ => return STATUS_UNSUCCESSFUL, - }; - - let addr = address.offset((callback_info[index].index * 8) as isize); - *(addr as *mut u64) = callback_info[index].address; - callback_info.remove(index); - } else { - log::error!("Callback not found for type {:?} at index {}", callback_type, index); - return STATUS_UNSUCCESSFUL; - } - - STATUS_SUCCESS - } - - unsafe fn remove_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { - let address = match find_callback_address(&(*target_callback).callback) { - Some(CallbackResult::PsCreate(addr)) => addr, - _ => return STATUS_UNSUCCESSFUL, - }; - - let index = (*target_callback).index as isize; - let addr = address.offset(index * 8); - let callback_restaure = CallbackRestaure { - index: (*target_callback).index, - callback: (*target_callback).callback, - address: *(addr as *mut u64), - ..Default::default() - }; - - let mut callback_info = INFO_CALLBACK_RESTAURE.lock(); - callback_info.push(callback_restaure); - - *(addr as *mut u64) = 0; - - log::info!("Callback removed at index {}", index); - - STATUS_SUCCESS - } - - unsafe fn enumerate_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { - let address = match find_callback_address(&(*target_callback).callback) { - Some(CallbackResult::PsCreate(addr)) => addr, - _ => return Err(STATUS_UNSUCCESSFUL), - }; - - let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; - let start_entry = ldr_data; - - for i in 0..64 { - let addr = address.cast::().offset(i * 8); - let callback = *(addr as *const u64); - - if callback == 0 { - continue; - } - - // Iterate over the loaded modules - for _ in 0..module_count { - let start_address = (*ldr_data).DllBase; - let image_size = (*ldr_data).SizeOfImage; - let end_address = start_address as u64 + image_size as u64; - let raw_pointer = *((callback & 0xfffffffffffffff8) as *const u64); - - if raw_pointer > start_address as u64 && raw_pointer < end_address { - let buffer = core::slice::from_raw_parts( - (*ldr_data).BaseDllName.Buffer, - ((*ldr_data).BaseDllName.Length / 2) as usize, - ); - - // Module name - let name = &mut (*callback_info.offset(i)).name[..buffer.len()]; - core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); - - // Module address - (*callback_info.offset(i)).address = raw_pointer as usize; - - // Module index - (*callback_info.offset(i)).index = i as u8; - - *information += size_of::(); - break; - } - - // Go to the next module in the list - ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; - } - - // Reset ldr_data for next callback - ldr_data = start_entry; - } - - Ok(()) - } - - unsafe fn enumerate_removed_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { - let callback_restaure = INFO_CALLBACK_RESTAURE.lock(); - - let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; - let start_entry = ldr_data; - - for (i, callback) in callback_restaure.iter().enumerate() { - for _ in 0..module_count { - let start_address = (*ldr_data).DllBase; - let image_size = (*ldr_data).SizeOfImage; - let end_address = start_address as u64 + image_size as u64; - let raw_pointer = *((callback.address & 0xfffffffffffffff8) as *const u64); - - if raw_pointer > start_address as u64 && raw_pointer < end_address { - let buffer = core::slice::from_raw_parts( - (*ldr_data).BaseDllName.Buffer, - ((*ldr_data).BaseDllName.Length / 2) as usize, - ); - - // Module name - let name = &mut (*callback_info.offset(i as isize)).name[..buffer.len()]; - core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); - - // Module address - (*callback_info.offset(i as isize)).address = raw_pointer as usize; - - // Module index - (*callback_info.offset(i as isize)).index = callback.index as u8; - - *information += size_of::(); - break; - } - - // Go to the next module in the list - ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; - } - - // Reset ldr_data for next callback - ldr_data = start_entry; - } - - Ok(()) - } -} - -/// Structure representing the Callback Registry. -pub struct CallbackRegistry; - -/// Implement a feature for the callback CmRegisterCallbackEx. -impl CallbackList for CallbackRegistry { - unsafe fn restore_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { - let mut callback_info = INFO_CALLBACK_RESTAURE_REGISTRY.lock(); - let callback_type = (*target_callback).callback; - let index = (*target_callback).index; - - if let Some(x) = callback_info.iter().position(|c| c.callback == callback_type && c.index == index) { - let (callback_list_header, callback_count, callback_list_lock) = match find_callback_address(&(*target_callback).callback) { - Some(CallbackResult::Registry(addr)) => addr, - _ => return STATUS_UNSUCCESSFUL, - }; - - ExAcquirePushLockExclusiveEx(callback_list_lock as _, 0); - - let count = *(callback_count as *mut u32) + 1; - let mut pcm_callback = callback_list_header as *mut CM_CALLBACK; - - for i in 0..count { - if pcm_callback.is_null() { - break; - } - - if i == index as u32 { - (*pcm_callback).function = callback_info[x].address; - callback_info.remove(x); - - ExReleasePushLockExclusiveEx(callback_list_lock as _, 0); - return STATUS_SUCCESS; - } - - pcm_callback = (*pcm_callback).list.Flink as *mut CM_CALLBACK; - } - - ExReleasePushLockExclusiveEx(callback_list_lock as _, 0); - - } else { - log::error!("Callback not found for type {:?} at index {}", callback_type, index); - return STATUS_UNSUCCESSFUL; - } - - STATUS_SUCCESS - } - - unsafe fn remove_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { - let (callback_list_header, callback_count, callback_list_lock) = match find_callback_address(&(*target_callback).callback) { - Some(CallbackResult::Registry(addr)) => addr, - _ => return STATUS_UNSUCCESSFUL, - }; - - ExAcquirePushLockExclusiveEx(callback_list_lock as _, 0); - - let index = (*target_callback).index as isize; - let count = *(callback_count as *mut u32) + 1; - let mut pcm_callback = callback_list_header as *mut CM_CALLBACK; - let mut callback_info = INFO_CALLBACK_RESTAURE_REGISTRY.lock(); - let mut prev_addr = 0; - - for i in 0..count { - if i == 1 { - prev_addr = (*pcm_callback).function as u64; // WdFilter.sys - } - - if pcm_callback.is_null() { - break; - } - - if i == index as u32 { - let addr = (*pcm_callback).function as u64; - let callback_restaure = CallbackRestaure { - index: (*target_callback).index, - callback: (*target_callback).callback, - address: addr, - ..Default::default() - }; - - (*pcm_callback).function = prev_addr; - callback_info.push(callback_restaure); - - log::info!("Callback removed at index {}", index); - ExReleasePushLockExclusiveEx(callback_list_lock as _, 0); - - return STATUS_SUCCESS; - } - - pcm_callback = (*pcm_callback).list.Flink as *mut CM_CALLBACK; - } - - ExReleasePushLockExclusiveEx(callback_list_lock as _, 0); - - STATUS_UNSUCCESSFUL - } - - unsafe fn enumerate_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { - let (callback_list_header, callback_count, callback_list_lock) = match find_callback_address(&(*target_callback).callback) { - Some(CallbackResult::Registry(addr)) => addr, - _ => return Err(STATUS_UNSUCCESSFUL), - }; - - let count = *(callback_count as *mut u32) + 1; - let mut pcm_callback = callback_list_header as *mut CM_CALLBACK; - let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; - let start_entry = ldr_data; - - ExAcquirePushLockExclusiveEx(callback_list_lock as _, 0); - - for i in 0..count as isize { - if pcm_callback.is_null() { - break; - } - // Iterate over the loaded modules - for _ in 0..module_count { - let start_address = (*ldr_data).DllBase; - let image_size = (*ldr_data).SizeOfImage; - let end_address = start_address as u64 + image_size as u64; - let addr = (*pcm_callback).function as u64; - - if addr > start_address as u64 && addr < end_address { - let buffer = core::slice::from_raw_parts( - (*ldr_data).BaseDllName.Buffer, - ((*ldr_data).BaseDllName.Length / 2) as usize, - ); - - // Module name - let name = &mut (*callback_info.offset(i)).name[..buffer.len()]; - core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); - - // Module address - (*callback_info.offset(i)).address = addr as usize; - - // Module index - (*callback_info.offset(i)).index = i as u8; - - *information += size_of::(); - break; - } - - // Go to the next module in the list - ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; - } - - // Reset ldr_data for next callback - ldr_data = start_entry; - - pcm_callback = (*pcm_callback).list.Flink as *mut CM_CALLBACK; - } - - ExReleasePushLockExclusiveEx(callback_list_lock as _, 0); - - Ok(()) - } - - unsafe fn enumerate_removed_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { - let callback_restaure = INFO_CALLBACK_RESTAURE_REGISTRY.lock(); - - let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; - - let start_entry = ldr_data; - - for (i, callback) in callback_restaure.iter().enumerate() { - for _ in 0..module_count { - let start_address = (*ldr_data).DllBase; - let image_size = (*ldr_data).SizeOfImage; - let end_address = start_address as u64 + image_size as u64; - - if callback.address > start_address as u64 && callback.address < end_address { - let buffer = core::slice::from_raw_parts( - (*ldr_data).BaseDllName.Buffer, - ((*ldr_data).BaseDllName.Length / 2) as usize, - ); - - // Module name - let name = &mut (*callback_info.offset(i as isize)).name[..buffer.len()]; - core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); - - // Module address - (*callback_info.offset(i as isize)).address = callback.address as usize; - - // Module index - (*callback_info.offset(i as isize)).index = callback.index as u8; - - *information += size_of::(); - break; - } - // Go to the next module in the list - ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; - } - - // Reset ldr_data for next callback - ldr_data = start_entry; - } - - Ok(()) - } -} - -/// Structure representing the Callback Object. -pub struct CallbackOb; - -/// Implement a feature for the callback ObRegisterCallbacks (PsProcessType / PsThreadType). -impl CallbackList for CallbackOb { - unsafe fn restore_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { - let mut callback_info = INFO_CALLBACK_RESTAURE_OB.lock(); - let callback_type = (*target_callback).callback; - let index = (*target_callback).index; - - if let Some(index) = callback_info.iter().position(|c| c.callback == callback_type && c.index == index) { - let object_type = match find_callback_address(&(*target_callback).callback) { - Some(CallbackResult::ObRegister(addr)) => addr, - _ => return STATUS_UNSUCCESSFUL, - }; - - let lock = &(*object_type).type_lock as *const _ as *mut u64; - ExAcquirePushLockExclusiveEx(lock, 0); - - let current = &mut ((*object_type).callback_list) as *mut _ as *mut OBCALLBACK_ENTRY; - let mut next = (*current).callback_list.Flink as *mut OBCALLBACK_ENTRY; - - while next != current { - if !(*next).enabled && !next.is_null() && (*next).entry as u64 == callback_info[index].entry { - (*next).enabled = true; - callback_info.remove(index); - ExReleasePushLockExclusiveEx(lock, 0); - return STATUS_SUCCESS; - } - - next = (*next).callback_list.Flink as *mut OBCALLBACK_ENTRY; - } - - ExReleasePushLockExclusiveEx(lock, 0); - } else { - log::error!("Callback not found for type {:?} at index {}", callback_type, index); - return STATUS_UNSUCCESSFUL; - } - - STATUS_UNSUCCESSFUL - } - - unsafe fn remove_callback(target_callback: *mut CallbackInfoInput) -> NTSTATUS { - let object_type = match find_callback_address(&(*target_callback).callback) { - Some(CallbackResult::ObRegister(addr)) => addr, - _ => return STATUS_UNSUCCESSFUL, - }; - - let lock = &(*object_type).type_lock as *const _ as *mut u64; - ExAcquirePushLockExclusiveEx(lock, 0); - - let mut i = 0; - let index = (*target_callback).index; - let current = &mut ((*object_type).callback_list) as *mut _ as *mut OBCALLBACK_ENTRY; - let mut next = (*current).callback_list.Flink as *mut OBCALLBACK_ENTRY; - let mut callback_info = INFO_CALLBACK_RESTAURE_OB.lock(); - - while next != current { - if i == index { - if (*next).enabled { - let mut callback_restaure = CallbackRestaureOb { - index, - callback: (*target_callback).callback, - entry: (*next).entry as u64, - pre_operation: 0, - post_operation: 0 - }; - - if let Some(pre_op) = (*next).pre_operation { - callback_restaure.pre_operation = pre_op as _; - } - - if let Some(post_op) = (*next).post_operation { - callback_restaure.post_operation = post_op as _; - } - - (*next).enabled = false; - - callback_info.push(callback_restaure); - log::info!("Callback removed at index {}", index); - } - - ExReleasePushLockExclusiveEx(lock, 0); - - return STATUS_SUCCESS; - } - - next = (*next).callback_list.Flink as *mut OBCALLBACK_ENTRY; - i += 1; - } - - ExReleasePushLockExclusiveEx(lock, 0); - - STATUS_UNSUCCESSFUL - } - - unsafe fn enumerate_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { - let object_type = match find_callback_address(&(*target_callback).callback) { - Some(CallbackResult::ObRegister(addr)) => addr, - _ => return Err(STATUS_UNSUCCESSFUL), - }; - - let current = &mut ((*object_type).callback_list) as *mut _ as *mut OBCALLBACK_ENTRY; - let mut next = (*current).callback_list.Flink as *mut OBCALLBACK_ENTRY; - let mut list_objects = Vec::new(); - - while next != current { - let mut addrs = (0, 0); - if let Some(pre_op) = (*next).pre_operation { - addrs.0 = pre_op as u64; - } - - if let Some(post_op) = (*next).post_operation { - addrs.1 = post_op as u64; - } - - list_objects.push(((*next).enabled, addrs)); - - next = (*next).callback_list.Flink as *mut OBCALLBACK_ENTRY; - } - - let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; - let start_entry = ldr_data; - let mut current_index = 0; - - for (i, (enabled, addrs)) in list_objects.iter().enumerate() { - if !enabled { - current_index += 1; - continue; - } - - for _ in 0..module_count { - let start_address = (*ldr_data).DllBase; - let image_size = (*ldr_data).SizeOfImage; - let end_address = start_address as u64 + image_size as u64; - let pre = addrs.0; - let post = addrs.1; - - if pre > start_address as u64 && pre < end_address || - post > start_address as u64 && post < end_address - { - let buffer = core::slice::from_raw_parts( - (*ldr_data).BaseDllName.Buffer, - ((*ldr_data).BaseDllName.Length / 2) as usize, - ); - - // Module name - let name = &mut (*callback_info.offset(i as isize)).name[..buffer.len()]; - core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); - - // Module address - (*callback_info.offset(i as isize)).pre_operation = pre as usize; - (*callback_info.offset(i as isize)).post_operation = post as usize; - - // Module index - (*callback_info.offset(i as isize)).index = current_index as u8; - - *information += size_of::(); - current_index += 1; - break; - } - - // Go to the next module in the list - ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; - } - - // Reset ldr_data for next callback - ldr_data = start_entry; - } - - Ok(()) - } - - unsafe fn enumerate_removed_callback(target_callback: *mut CallbackInfoInput, callback_info: *mut CallbackInfoOutput, information: &mut usize) -> Result<(), NTSTATUS> { - let callback_restaure = INFO_CALLBACK_RESTAURE_OB.lock(); - - let (mut ldr_data, module_count) = return_module().ok_or(STATUS_UNSUCCESSFUL)?; - let start_entry = ldr_data; - - for (i, callback) in callback_restaure.iter().enumerate() { - for _ in 0..module_count { - let start_address = (*ldr_data).DllBase; - let image_size = (*ldr_data).SizeOfImage; - let end_address = start_address as u64 + image_size as u64; - - if callback.pre_operation > start_address as u64 && callback.pre_operation < end_address - || callback.post_operation > start_address as u64 && callback.post_operation < end_address - { - let buffer = core::slice::from_raw_parts( - (*ldr_data).BaseDllName.Buffer, - ((*ldr_data).BaseDllName.Length / 2) as usize, - ); - - // Module name - let name = &mut (*callback_info.offset(i as isize)).name[..buffer.len()]; - core::ptr::copy_nonoverlapping(buffer.as_ptr(), name.as_mut_ptr(), buffer.len()); - - // Module address - (*callback_info.offset(i as isize)).pre_operation = callback.pre_operation as usize; - (*callback_info.offset(i as isize)).post_operation = callback.post_operation as usize; - - // Module index - (*callback_info.offset(i as isize)).index = callback.index as u8; - - *information += size_of::(); - break; - } - // Go to the next module in the list - ldr_data = (*ldr_data).InLoadOrderLinks.Flink as *mut LDR_DATA_TABLE_ENTRY; - } - - // Reset ldr_data for next callback - ldr_data = start_entry; - } - - Ok(()) - } -} \ No newline at end of file diff --git a/driver/src/lib.rs b/driver/src/lib.rs index 0fb380a..d74b2cf 100644 --- a/driver/src/lib.rs +++ b/driver/src/lib.rs @@ -23,7 +23,7 @@ use { #[cfg(not(feature = "mapper"))] mod registry; -mod callbacks; +mod callback; mod misc; mod driver; mod includes; diff --git a/driver/src/utils/ioctls.rs b/driver/src/utils/ioctls.rs index c313466..c389ef4 100644 --- a/driver/src/utils/ioctls.rs +++ b/driver/src/utils/ioctls.rs @@ -4,7 +4,7 @@ use { lazy_static::lazy_static, wdk_sys::{IO_STACK_LOCATION, IRP, NTSTATUS}, crate::{ - callbacks::ioctls::get_callback_ioctls, + callback::ioctls::get_callback_ioctls, driver::ioctls::get_driver_ioctls, process::ioctls::get_process_ioctls, thread::ioctls::get_thread_ioctls, diff --git a/driver/src/utils/macros.rs b/driver/src/utils/macros.rs index b58aaa7..ab41173 100644 --- a/driver/src/utils/macros.rs +++ b/driver/src/utils/macros.rs @@ -165,7 +165,7 @@ macro_rules! handle_module { macro_rules! handle_callback { ($irp:expr, $stack:expr, $input_type:ty, $output_type:ty, $information:expr, $ioctl:expr) => {{ use shared::vars::Callbacks; - use crate::callbacks::{Callback, CallbackRegistry, CallbackOb, CallbackList}; + use crate::callback::{callbacks::{notify_routine::Callback, registry::CallbackRegistry, object::CallbackOb}, CallbackList}; use wdk_sys::STATUS_UNSUCCESSFUL; let input_buffer = match crate::utils::get_input_buffer::<$input_type>($stack) { @@ -203,7 +203,7 @@ macro_rules! handle_callback { ($irp:expr, $type_:ty, $ioctl:expr) => {{ use shared::vars::Callbacks; - use crate::callbacks::{Callback, CallbackRegistry, CallbackOb, CallbackList}; + use crate::callback::{callbacks::{notify_routine::Callback, registry::CallbackRegistry, object::CallbackOb}, CallbackList}; let input_buffer = match crate::utils::get_input_buffer::<$type_>($irp) { Ok(buffer) => buffer,