Update
- Driver scan device tree and output more data - Print ssdt scanning base on kernel modules traversing
This commit is contained in:
parent
199c3ca10b
commit
abb7a70b72
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -453,6 +453,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parse_int 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -639,6 +640,14 @@ dependencies = [
|
||||
"vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parse_int"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pdb"
|
||||
version = "0.5.0"
|
||||
@ -1456,6 +1465,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum openssl 0.10.28 (registry+https://github.com/rust-lang/crates.io-index)" = "973293749822d7dd6370d6da1e523b0d1db19f06c459134c658b2a4261378b52"
|
||||
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
"checksum openssl-sys 0.9.54 (registry+https://github.com/rust-lang/crates.io-index)" = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986"
|
||||
"checksum parse_int 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82db48cac18f0963b10ddad303fa88447b95bbe0e6dbe3385f98402b63d0cc48"
|
||||
"checksum pdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6b57b7067dc9dbd04b1305bb51a8ae7d0fc645956a73b6cb2807dd956ab6929"
|
||||
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
"checksum pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
|
@ -18,6 +18,7 @@ widestring = "0.4.0"
|
||||
winapi = { version = "0.3.8", features = ["libloaderapi", "processthreadsapi", "winbase", "securitybaseapi", "handleapi", "winnt", "winreg", "fileapi", "ioapiset", "winioctl", "errhandlingapi", "sysinfoapi"] }
|
||||
reqwest = { version = "0.10.1", features = ["blocking"] }
|
||||
serde_json = "1.0.55"
|
||||
parse_int = "0.4.0"
|
||||
# repl dependencies
|
||||
rustyline = "6.2.0"
|
||||
pest = "2.1.3"
|
||||
|
@ -1,5 +1,7 @@
|
||||
use std::error::Error;
|
||||
|
||||
use parse_int::parse;
|
||||
|
||||
use lpus::{
|
||||
driver_state::{DriverState},
|
||||
traverse_loadedmodulelist,
|
||||
@ -13,6 +15,19 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
let loaded = traverse_loadedmodulelist(&driver).unwrap_or(Vec::new());
|
||||
let unloaded = traverse_unloadeddrivers(&driver).unwrap_or(Vec::new());
|
||||
|
||||
// TODO: move to another place
|
||||
// From Vol3 SSDT scan
|
||||
// https://github.com/volatilityfoundation/volatility3/blob/master/volatility/framework/plugins/windows/ssdt.py
|
||||
let ntosbase = driver.get_kernel_base();
|
||||
let servicetable = ntosbase.clone() + driver.pdb_store.get_offset_r("KiServiceTable")?;
|
||||
let servicelimit_ptr = ntosbase.clone() + driver.pdb_store.get_offset_r("KiServiceLimit")?;
|
||||
|
||||
let servicelimit = driver.deref_addr_new::<u32>(servicelimit_ptr.address()) as u64;
|
||||
let ssdt: Vec<u64> = driver.deref_array::<u32>(&servicetable, servicelimit)
|
||||
.iter().map(|entry| {
|
||||
servicetable.address() + ((entry >> 4) as u64)
|
||||
}).collect();
|
||||
|
||||
for r in loaded.iter() {
|
||||
println!("{:#}", r.to_string());
|
||||
}
|
||||
@ -20,6 +35,34 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
for r in unloaded.iter() {
|
||||
println!("{:#}", r.to_string());
|
||||
}
|
||||
println!("=============================================");
|
||||
for func in ssdt {
|
||||
for r in loaded.iter() {
|
||||
let base = r["dllbase"].as_str().and_then(|b| parse::<u64>(b).ok()).unwrap_or(0);
|
||||
let size = r["size"].as_str().and_then(|s| parse::<u64>(s).ok()).unwrap_or(0);
|
||||
|
||||
if func > base && func < base + size {
|
||||
let offset = func - ntosbase.address();
|
||||
let funcname: String = {
|
||||
let mut n = "".to_string();
|
||||
for (name, o) in driver.pdb_store.symbols.iter() {
|
||||
if *o == offset {
|
||||
n = name.clone();
|
||||
}
|
||||
}
|
||||
if n == "" {
|
||||
"(??)".to_string()
|
||||
}
|
||||
else {
|
||||
n
|
||||
}
|
||||
};
|
||||
println!("SSDT 0x{:x} {}!{}", func, r["BaseName"], funcname);
|
||||
break; // next func
|
||||
}
|
||||
}
|
||||
// TODO: If not found, search other list
|
||||
}
|
||||
|
||||
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
|
||||
Ok(())
|
||||
|
152
src/lib.rs
152
src/lib.rs
@ -15,6 +15,110 @@ use address::Address;
|
||||
|
||||
type BoxResult<T> = Result<T, Box<dyn Error>>;
|
||||
|
||||
pub fn get_irp_name(idx: usize) -> String {
|
||||
let irp_names = vec![
|
||||
"IRP_MJ_CREATE",
|
||||
"IRP_MJ_CREATE_NAMED_PIPE",
|
||||
"IRP_MJ_CLOSE",
|
||||
"IRP_MJ_READ",
|
||||
"IRP_MJ_WRITE",
|
||||
"IRP_MJ_QUERY_INFORMATION",
|
||||
"IRP_MJ_SET_INFORMATION",
|
||||
"IRP_MJ_QUERY_EA",
|
||||
"IRP_MJ_SET_EA",
|
||||
"IRP_MJ_FLUSH_BUFFERS",
|
||||
"IRP_MJ_QUERY_VOLUME_INFORMATION",
|
||||
"IRP_MJ_SET_VOLUME_INFORMATION",
|
||||
"IRP_MJ_DIRECTORY_CONTROL",
|
||||
"IRP_MJ_FILE_SYSTEM_CONTROL",
|
||||
"IRP_MJ_DEVICE_CONTROL",
|
||||
"IRP_MJ_INTERNAL_DEVICE_CONTROL",
|
||||
"IRP_MJ_SHUTDOWN",
|
||||
"IRP_MJ_LOCK_CONTROL",
|
||||
"IRP_MJ_CLEANUP",
|
||||
"IRP_MJ_CREATE_MAILSLOT",
|
||||
"IRP_MJ_QUERY_SECURITY",
|
||||
"IRP_MJ_SET_SECURITY",
|
||||
"IRP_MJ_POWER",
|
||||
"IRP_MJ_SYSTEM_CONTROL",
|
||||
"IRP_MJ_DEVICE_CHANGE",
|
||||
"IRP_MJ_QUERY_QUOTA",
|
||||
"IRP_MJ_SET_QUOTA",
|
||||
"IRP_MJ_PNP"
|
||||
].iter().map(|x| x.to_string()).collect::<Vec<String>>();
|
||||
|
||||
if let Some(name) = irp_names.get(idx) {
|
||||
name.clone()
|
||||
}
|
||||
else {
|
||||
"UNKNOWN".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_device_type(typ: u32) -> String {
|
||||
match typ {
|
||||
0x00000027 => "FILE_DEVICE_8042_PORT",
|
||||
0x00000032 => "FILE_DEVICE_ACPI",
|
||||
0x00000029 => "FILE_DEVICE_BATTERY",
|
||||
0x00000001 => "FILE_DEVICE_BEEP",
|
||||
0x0000002a => "FILE_DEVICE_BUS_EXTENDER",
|
||||
0x00000002 => "FILE_DEVICE_CD_ROM",
|
||||
0x00000003 => "FILE_DEVICE_CD_ROM_FILE_SYSTEM",
|
||||
0x00000030 => "FILE_DEVICE_CHANGER",
|
||||
0x00000004 => "FILE_DEVICE_CONTROLLER",
|
||||
0x00000005 => "FILE_DEVICE_DATALINK",
|
||||
0x00000006 => "FILE_DEVICE_DFS",
|
||||
0x00000035 => "FILE_DEVICE_DFS_FILE_SYSTEM",
|
||||
0x00000036 => "FILE_DEVICE_DFS_VOLUME",
|
||||
0x00000007 => "FILE_DEVICE_DISK",
|
||||
0x00000008 => "FILE_DEVICE_DISK_FILE_SYSTEM",
|
||||
0x00000033 => "FILE_DEVICE_DVD",
|
||||
0x00000009 => "FILE_DEVICE_FILE_SYSTEM",
|
||||
0x0000003a => "FILE_DEVICE_FIPS",
|
||||
0x00000034 => "FILE_DEVICE_FULLSCREEN_VIDEO",
|
||||
0x0000000a => "FILE_DEVICE_INPORT_PORT",
|
||||
0x0000000b => "FILE_DEVICE_KEYBOARD",
|
||||
0x0000002f => "FILE_DEVICE_KS",
|
||||
0x00000039 => "FILE_DEVICE_KSEC",
|
||||
0x0000000c => "FILE_DEVICE_MAILSLOT",
|
||||
0x0000002d => "FILE_DEVICE_MASS_STORAGE",
|
||||
0x0000000d => "FILE_DEVICE_MIDI_IN",
|
||||
0x0000000e => "FILE_DEVICE_MIDI_OUT",
|
||||
0x0000002b => "FILE_DEVICE_MODEM",
|
||||
0x0000000f => "FILE_DEVICE_MOUSE",
|
||||
0x00000010 => "FILE_DEVICE_MULTI_UNC_PROVIDER",
|
||||
0x00000011 => "FILE_DEVICE_NAMED_PIPE",
|
||||
0x00000012 => "FILE_DEVICE_NETWORK",
|
||||
0x00000013 => "FILE_DEVICE_NETWORK_BROWSER",
|
||||
0x00000014 => "FILE_DEVICE_NETWORK_FILE_SYSTEM",
|
||||
0x00000028 => "FILE_DEVICE_NETWORK_REDIRECTOR",
|
||||
0x00000015 => "FILE_DEVICE_NULL",
|
||||
0x00000016 => "FILE_DEVICE_PARALLEL_PORT",
|
||||
0x00000017 => "FILE_DEVICE_PHYSICAL_NETCARD",
|
||||
0x00000018 => "FILE_DEVICE_PRINTER",
|
||||
0x00000019 => "FILE_DEVICE_SCANNER",
|
||||
0x0000001c => "FILE_DEVICE_SCREEN",
|
||||
0x00000037 => "FILE_DEVICE_SERENUM",
|
||||
0x0000001a => "FILE_DEVICE_SERIAL_MOUSE_PORT",
|
||||
0x0000001b => "FILE_DEVICE_SERIAL_PORT",
|
||||
0x00000031 => "FILE_DEVICE_SMARTCARD",
|
||||
0x0000002e => "FILE_DEVICE_SMB",
|
||||
0x0000001d => "FILE_DEVICE_SOUND",
|
||||
0x0000001e => "FILE_DEVICE_STREAMS",
|
||||
0x0000001f => "FILE_DEVICE_TAPE",
|
||||
0x00000020 => "FILE_DEVICE_TAPE_FILE_SYSTEM",
|
||||
0x00000038 => "FILE_DEVICE_TERMSRV",
|
||||
0x00000021 => "FILE_DEVICE_TRANSPORT",
|
||||
0x00000022 => "FILE_DEVICE_UNKNOWN",
|
||||
0x0000002c => "FILE_DEVICE_VDM",
|
||||
0x00000023 => "FILE_DEVICE_VIDEO",
|
||||
0x00000024 => "FILE_DEVICE_VIRTUAL_DISK",
|
||||
0x00000025 => "FILE_DEVICE_WAVE_IN",
|
||||
0x00000026 => "FILE_DEVICE_WAVE_OUT",
|
||||
_ => "UNKNOWN"
|
||||
}.to_string()
|
||||
}
|
||||
|
||||
pub fn scan_eprocess(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
let mut result: Vec<Value> = Vec::new();
|
||||
driver.scan_pool(b"Proc", "_EPROCESS", |pool_addr, header, data_addr| {
|
||||
@ -268,13 +372,53 @@ pub fn scan_driver(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
let dob_addr = &try_ptr;
|
||||
|
||||
let devicename_ptr = driver.address_of(dob_addr, "_DRIVER_OBJECT.DriverName")?;
|
||||
let servicekey_ptr = driver.address_of(dob_addr, "_DRIVER_OBJECT.DriverExtension.ServiceKeyName")?;
|
||||
let hardware_ptr: u64 = driver.decompose(dob_addr, "_DRIVER_OBJECT.HardwareDatabase")?;
|
||||
let major_function: Vec<u64> = driver.decompose_array(dob_addr, "_DRIVER_OBJECT.MajorFunction", 28)?;
|
||||
let start: u64 = driver.decompose(dob_addr, "_DRIVER_OBJECT.DriverStart")?;
|
||||
let init: u64 = driver.decompose(dob_addr, "_DRIVER_OBJECT.DriverInit")?;
|
||||
let unload: u64 = driver.decompose(dob_addr, "_DRIVER_OBJECT.DriverUnload")?;
|
||||
let size: u64 = driver.decompose(dob_addr, "_DRIVER_OBJECT.DriverSize")?;
|
||||
|
||||
let devicename = driver.get_unicode_string(devicename_ptr)
|
||||
.unwrap_or("".to_string());
|
||||
let hardware = driver.get_unicode_string(hardware_ptr)
|
||||
.unwrap_or("".to_string());
|
||||
let servicekey = driver.get_unicode_string(servicekey_ptr)
|
||||
.unwrap_or("".to_string());
|
||||
|
||||
// device tree walk
|
||||
let devices = {
|
||||
let mut driver_devices: Vec<Value> = Vec::new();
|
||||
let mut device_ptr: u64 = driver.decompose(dob_addr, "_DRIVER_OBJECT.DeviceObject")?;
|
||||
while device_ptr != 0 {
|
||||
let addr = Address::from_base(device_ptr);
|
||||
let device_type: u32 = driver.decompose(&addr, "_DEVICE_OBJECT.DeviceType")?;
|
||||
|
||||
// get attached devices
|
||||
let mut attached_ptr: u64 = driver.decompose(&addr, "_DEVICE_OBJECT.AttachedDevice")?;
|
||||
let mut attached_devices: Vec<Value> = Vec::new();
|
||||
while attached_ptr != 0 {
|
||||
let attached = Address::from_base(attached_ptr);
|
||||
let attached_device_type: u32 = driver.decompose(&attached, "_DEVICE_OBJECT.DeviceType")?;
|
||||
attached_devices.push(json!({
|
||||
"address": format!("0x{:x}", attached_ptr),
|
||||
"type": "_DEVICE_OBJECT",
|
||||
"devicetype": get_device_type(attached_device_type)
|
||||
}));
|
||||
attached_ptr = driver.decompose(&attached, "_DEVICE_OBJECT.AttachedDevice")?;
|
||||
}
|
||||
driver_devices.push(json!({
|
||||
"address": format!("0x{:x}", device_ptr),
|
||||
"type": "_DEVICE_OBJECT",
|
||||
"devicetype": get_device_type(device_type),
|
||||
"attached": attached_devices
|
||||
}));
|
||||
device_ptr = driver.decompose(&addr, "_DEVICE_OBJECT.NextDevice")?;
|
||||
}
|
||||
driver_devices
|
||||
};
|
||||
|
||||
result.push(json!({
|
||||
"pool": format!("0x{:x}", pool_addr.address()),
|
||||
"address": format!("0x{:x}", dob_addr.address()),
|
||||
@ -283,7 +427,13 @@ pub fn scan_driver(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
"hardware": hardware,
|
||||
"major_function": major_function.into_iter()
|
||||
.map(|func| format!("0x{:x}", func))
|
||||
.collect::<Vec<String>>()
|
||||
.collect::<Vec<String>>(),
|
||||
"servicekey": servicekey,
|
||||
"start": format!("0x{:x}", start),
|
||||
"init": format!("0x{:x}", init),
|
||||
"unload": format!("0x{:x}", unload),
|
||||
"size": format!("0x{:x}", size),
|
||||
"devicetree": devices
|
||||
}));
|
||||
Ok(true)
|
||||
})?;
|
||||
|
Loading…
Reference in New Issue
Block a user