Update scan for kernel modules and driver
Scan kernel modules Driver scan major functions' address
This commit is contained in:
parent
1707b301ff
commit
8cf91aef79
22
src/bin/kernel_module_scan.rs
Normal file
22
src/bin/kernel_module_scan.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use std::error::Error;
|
||||
|
||||
use lpus::{
|
||||
driver_state::{DriverState},
|
||||
scan_kernel_module
|
||||
};
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let mut driver = DriverState::new();
|
||||
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
|
||||
|
||||
let result = scan_kernel_module(&driver).unwrap_or(Vec::new());
|
||||
|
||||
for r in result.iter() {
|
||||
println!("{:#}", r.to_string());
|
||||
}
|
||||
|
||||
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,26 @@
|
||||
use std::error::Error;
|
||||
// use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use lpus::{
|
||||
driver_state::{DriverState},
|
||||
};
|
||||
|
||||
pub fn to_epoch(filetime: u64) -> u64 {
|
||||
// https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/
|
||||
let windows_epoch_diff = 11644473600000 * 10000;
|
||||
if filetime < windows_epoch_diff {
|
||||
return 0;
|
||||
}
|
||||
let process_time_epoch = (filetime - windows_epoch_diff) / 10000;
|
||||
// let now_ms = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_millis() as u64;
|
||||
|
||||
process_time_epoch
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let driver = DriverState::new();
|
||||
driver.windows_ffi.print_version();
|
||||
driver.pdb_store.print_default_information();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use std::clone::Clone;
|
||||
use std::error::Error;
|
||||
// use std::io::{Error, ErrorKind};
|
||||
use std::ffi::c_void;
|
||||
use std::mem::{size_of_val};
|
||||
use std::mem::{size_of_val, size_of};
|
||||
|
||||
use winapi::shared::ntdef::{NTSTATUS};
|
||||
use winapi::shared::minwindef::{DWORD};
|
||||
@ -233,7 +233,8 @@ impl DriverState {
|
||||
pub fn deref_array<T: Default + Clone>(&self, addr: &Address, len: u64) -> Vec<T> {
|
||||
let resolver = |p| { self.deref_addr_new(p) };
|
||||
let mut r: Vec<T> = vec![Default::default(); len as usize];
|
||||
self.deref_addr_ptr(addr.get(&resolver), r.as_mut_ptr(), len);
|
||||
let size_in_byte = (len as usize) * size_of::<T>();
|
||||
self.deref_addr_ptr(addr.get(&resolver), r.as_mut_ptr(), size_in_byte as u64);
|
||||
r
|
||||
}
|
||||
|
||||
@ -251,20 +252,20 @@ impl DriverState {
|
||||
}
|
||||
|
||||
// #[deprecated(note="use deref_array<T>")]
|
||||
pub fn deref_addr_ptr<T>(&self, addr: u64, outptr: *mut T, output_len: u64) {
|
||||
pub fn deref_addr_ptr<T>(&self, addr: u64, outptr: *mut T, output_len_as_byte: u64) {
|
||||
let code = DriverAction::DereferenceAddress.get_code();
|
||||
let mut input = InputData {
|
||||
deref_addr: DerefAddr {
|
||||
addr,
|
||||
size: output_len
|
||||
size: output_len_as_byte
|
||||
}
|
||||
};
|
||||
self.windows_ffi.device_io_raw(code,
|
||||
&mut input as *mut _ as *mut c_void, size_of_val(&input) as DWORD,
|
||||
outptr as *mut c_void, output_len as DWORD);
|
||||
outptr as *mut c_void, output_len_as_byte as DWORD);
|
||||
}
|
||||
|
||||
pub fn get_unicode_string(&self, unicode_str_addr: u64, deref: bool) -> BoxResult<String> {
|
||||
pub fn get_unicode_string(&self, unicode_str_addr: u64) -> BoxResult<String> {
|
||||
if unicode_str_addr == 0 {
|
||||
return Err("Not a valid address".into());
|
||||
}
|
||||
@ -283,10 +284,6 @@ impl DriverState {
|
||||
return Err("Unicode string is empty".into());
|
||||
}
|
||||
|
||||
if !deref {
|
||||
return Ok("".to_string());
|
||||
}
|
||||
|
||||
let mut buf = vec![0u16; (strlen / 2) as usize];
|
||||
self.deref_addr_ptr(bufaddr, buf.as_mut_ptr(), strlen as u64);
|
||||
// TODO: BUG with deref_array, len is wrong,
|
||||
|
55
src/lib.rs
55
src/lib.rs
@ -50,7 +50,7 @@ pub fn scan_eprocess(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
let binary_path = driver.get_unicode_string(unicode_str_ptr, true)
|
||||
let binary_path = driver.get_unicode_string(unicode_str_ptr)
|
||||
.unwrap_or("".to_string());
|
||||
|
||||
result.push(json!({
|
||||
@ -104,15 +104,15 @@ pub fn scan_file(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
if read_ok == 0 {
|
||||
"[NOT READABLE]".to_string()
|
||||
}
|
||||
else if let Ok(n) = driver.get_unicode_string(filename_ptr, true) {
|
||||
else if let Ok(n) = driver.get_unicode_string(filename_ptr) {
|
||||
n
|
||||
}
|
||||
else {
|
||||
"[NOT A VALID _UNICODE_STRING]".to_string()
|
||||
};
|
||||
let devicename = driver.get_unicode_string(devicename_ptr, true)
|
||||
let devicename = driver.get_unicode_string(devicename_ptr)
|
||||
.unwrap_or("".to_string());
|
||||
let hardware = driver.get_unicode_string(hardware_ptr, true)
|
||||
let hardware = driver.get_unicode_string(hardware_ptr)
|
||||
.unwrap_or("".to_string());
|
||||
result.push(json!({
|
||||
"pool": format!("0x{:x}", pool_addr.address()),
|
||||
@ -165,7 +165,7 @@ pub fn scan_ethread(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
let unicode_str_ptr: u64 = driver.address_of(ethread_ptr, "_ETHREAD.ThreadName")?;
|
||||
|
||||
let thread_name =
|
||||
if let Ok(name) = driver.get_unicode_string(unicode_str_ptr, true) {
|
||||
if let Ok(name) = driver.get_unicode_string(unicode_str_ptr) {
|
||||
name
|
||||
}
|
||||
else {
|
||||
@ -222,7 +222,7 @@ pub fn scan_mutant(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
let unicode_str_ptr: u64 = driver.address_of(ðread_ptr, "_ETHREAD.ThreadName")?;
|
||||
|
||||
let thread_name =
|
||||
if let Ok(name) = driver.get_unicode_string(unicode_str_ptr, true) {
|
||||
if let Ok(name) = driver.get_unicode_string(unicode_str_ptr) {
|
||||
name
|
||||
}
|
||||
else {
|
||||
@ -269,17 +269,54 @@ pub fn scan_driver(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
|
||||
let devicename_ptr = driver.address_of(dob_addr, "_DRIVER_OBJECT.DriverName")?;
|
||||
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 devicename = driver.get_unicode_string(devicename_ptr, true)
|
||||
let devicename = driver.get_unicode_string(devicename_ptr)
|
||||
.unwrap_or("".to_string());
|
||||
let hardware = driver.get_unicode_string(hardware_ptr, true)
|
||||
let hardware = driver.get_unicode_string(hardware_ptr)
|
||||
.unwrap_or("".to_string());
|
||||
result.push(json!({
|
||||
"pool": format!("0x{:x}", pool_addr.address()),
|
||||
"address": format!("0x{:x}", dob_addr.address()),
|
||||
"type": "_DRIVER_OBJECT",
|
||||
"device": devicename,
|
||||
"hardware": hardware
|
||||
"hardware": hardware,
|
||||
"major_function": major_function.into_iter()
|
||||
.map(|func| format!("0x{:x}", func))
|
||||
.collect::<Vec<String>>()
|
||||
}));
|
||||
Ok(true)
|
||||
})?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn scan_kernel_module(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
let mut result: Vec<Value> = Vec::new();
|
||||
|
||||
driver.scan_pool(b"MmLd", "_KLDR_DATA_TABLE_ENTRY", |pool_addr, _, data_addr| {
|
||||
// By reversing, this structure does not have any header
|
||||
let mod_addr = &data_addr;
|
||||
|
||||
let dllbase: u64 = driver.decompose(mod_addr, "_KLDR_DATA_TABLE_ENTRY.DllBase")?;
|
||||
let entry: u64 = driver.decompose(mod_addr, "_KLDR_DATA_TABLE_ENTRY.EntryPoint")?;
|
||||
let size: u64 = driver.decompose(mod_addr, "_KLDR_DATA_TABLE_ENTRY.SizeOfImage")?;
|
||||
let fullname_ptr = driver.address_of(mod_addr, "_KLDR_DATA_TABLE_ENTRY.FullDllName")?;
|
||||
let basename_ptr = driver.address_of(mod_addr, "_KLDR_DATA_TABLE_ENTRY.BaseDllName")?;
|
||||
|
||||
let fullname = driver.get_unicode_string(fullname_ptr)
|
||||
.unwrap_or("".to_string());
|
||||
let basename = driver.get_unicode_string(basename_ptr)
|
||||
.unwrap_or("".to_string());
|
||||
result.push(json!({
|
||||
"pool": format!("0x{:x}", pool_addr.address()),
|
||||
"address": format!("0x{:x}", mod_addr.address()),
|
||||
"type": "_KLDR_DATA_TABLE_ENTRY",
|
||||
"dllbase": format!("0x{:x}", dllbase),
|
||||
"entry": format!("0x{:x}", entry),
|
||||
"size": format!("0x{:x}", size),
|
||||
"FullName": fullname,
|
||||
"BaseName": basename
|
||||
}));
|
||||
Ok(true)
|
||||
})?;
|
||||
|
Loading…
Reference in New Issue
Block a user