Files
shadow-rs/crates/shadowx/src/utils/process_attach.rs
joaoviictorti 3e51fe4c11 refactor: Refactoring all code to improve documentation and operation of the kernel driver
- Updating module documentation
- Adding new features
- Refactoring all code to improve readability
2024-11-01 13:26:50 -03:00

76 lines
2.7 KiB
Rust

use wdk_sys::{ntddk::{KeStackAttachProcess, KeUnstackDetachProcess}, KAPC_STATE, PRKPROCESS};
/// A wrapper for managing the attachment to a process context in the Windows kernel.
///
/// This struct provides a safe abstraction for attaching to the context of a target process using
/// `KeStackAttachProcess` and ensures that the process is properly detached when no longer needed
/// (either manually or automatically when it goes out of scope).
///
/// When a `ProcessAttach` instance is dropped, it will automatically detach from the process
/// if still attached.
pub struct ProcessAttach {
/// The APC (Asynchronous Procedure Call) state used to manage process attachment.
apc_state: KAPC_STATE,
/// Indicates whether the process is currently attached.
attached: bool,
}
impl ProcessAttach {
/// Attaches to the context of a target process.
///
/// This function attaches the current thread to the address space of the specified
/// process using `KeStackAttachProcess`. This allows the current thread to operate within
/// the target process context.
///
/// # Arguments
///
/// * `target_process` - A pointer to the target process (`PRKPROCESS`) to attach to.
///
/// # Returns
///
/// * A new `ProcessAttach` instance representing the attached process context.
#[inline]
pub fn new(target_process: PRKPROCESS) -> Self {
let mut apc_state: KAPC_STATE = unsafe { core::mem::zeroed() };
unsafe {
KeStackAttachProcess(target_process, &mut apc_state);
}
Self {
apc_state,
attached: true,
}
}
/// Manually detaches from the process context.
///
/// This method can be called to explicitly detach the current thread from the target process's
/// address space, if it was previously attached.
#[inline]
pub fn detach(&mut self) {
if self.attached {
unsafe {
KeUnstackDetachProcess(&mut self.apc_state);
}
self.attached = false;
}
}
}
impl Drop for ProcessAttach {
/// Automatically detaches from the process context when the `ProcessAttach` instance is dropped.
///
/// This method ensures that the current thread is detached from the target process's address space
/// when the `ProcessAttach` object goes out of scope. If the process is still attached when `drop`
/// is called, it will be safely detached using `KeUnstackDetachProcess`.
fn drop(&mut self) {
// If it is still attached, it unattaches when it leaves the scope.
if self.attached {
unsafe {
KeUnstackDetachProcess(&mut self.apc_state);
}
}
}
}