General updates
Driver is renamed to lpus.sys Pdb will be downloaded ino %APPDATA%/nganhkhoa/lpus And some little fixes
This commit is contained in:
@ -34,14 +34,14 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
let eprocess_size = driver.pdb_store.get_offset_r("_EPROCESS.struct_size")?;
|
||||
let eprocess_name_offset = driver.pdb_store.get_offset_r("_EPROCESS.ImageFileName")?;
|
||||
let eprocess_create_time_offset = driver.pdb_store.get_offset_r("_EPROCESS.CreateTime")?;
|
||||
let eprocess_exit_time_offset = driver.pdb_store.get_offset_r("_EPROCESS.ExitTime")?;
|
||||
// let eprocess_exit_time_offset = driver.pdb_store.get_offset_r("_EPROCESS.ExitTime")?;
|
||||
|
||||
let eprocess_valid_start = data_addr;
|
||||
let eprocess_valid_end = (pool_addr + chunk_size) - eprocess_size;
|
||||
let mut try_eprocess_ptr = eprocess_valid_start;
|
||||
|
||||
let mut create_time = 0u64;
|
||||
let mut exit_time = 0u64;
|
||||
// let mut exit_time = 0u64;
|
||||
while try_eprocess_ptr <= eprocess_valid_end {
|
||||
driver.deref_addr(try_eprocess_ptr + eprocess_create_time_offset, &mut create_time);
|
||||
// driver.deref_addr(try_eprocess_ptr + eprocess_exit_time_offset, &mut exit_time);
|
||||
@ -51,7 +51,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
try_eprocess_ptr += 0x4; // search exhaustively
|
||||
}
|
||||
if (try_eprocess_ptr > eprocess_valid_end) {
|
||||
if try_eprocess_ptr > eprocess_valid_end {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ pub struct DriverState {
|
||||
impl DriverState {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
pdb_store: parse_pdb(),
|
||||
pdb_store: parse_pdb().expect("Cannot get PDB file"),
|
||||
windows_ffi: WindowsFFI::new()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
extern crate chrono;
|
||||
extern crate app_dirs;
|
||||
|
||||
pub mod pdb_store;
|
||||
pub mod windows;
|
||||
|
@ -1,26 +1,25 @@
|
||||
use std::error::Error;
|
||||
use std::io;
|
||||
use std::io::{Read};
|
||||
use std::path::Path;
|
||||
use std::path::{PathBuf};
|
||||
use std::fs::File;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use pdb::PDB;
|
||||
use pdb::SymbolData;
|
||||
use pdb::TypeData;
|
||||
use pdb::ClassType;
|
||||
use pdb::ModifierType;
|
||||
use pdb::Rva;
|
||||
use pdb::{
|
||||
PDB, SymbolData, TypeData, ClassType, ModifierType, Rva,
|
||||
FallibleIterator, TypeFinder, TypeIndex
|
||||
};
|
||||
|
||||
use pdb::FallibleIterator;
|
||||
use pdb::TypeFinder;
|
||||
use pdb::TypeIndex;
|
||||
use app_dirs::{AppInfo, AppDataType, app_dir};
|
||||
|
||||
const APP_INFO: AppInfo = AppInfo { name: "lpus", author: "nganhkhoa" };
|
||||
|
||||
const PDBNAME: &str = "ntkrnlmp.pdb";
|
||||
const KERNEL_PDB_NAME: &str = "ntkrnlmp.pdb";
|
||||
const NTOSKRNL_PATH: &str = "C:\\Windows\\System32\\ntoskrnl.exe";
|
||||
const PDB_SERVER_PATH: &str = "http://msdl.microsoft.com/download/symbols";
|
||||
|
||||
type BoxResult<T> = Result<T, Box<dyn Error>>;
|
||||
|
||||
type SymbolStore = HashMap<String, u64>;
|
||||
type StructStore = HashMap<String, HashMap<String, (String, u64)>>;
|
||||
|
||||
@ -30,7 +29,7 @@ pub struct PdbStore {
|
||||
}
|
||||
|
||||
impl PdbStore {
|
||||
pub fn get_offset_r(&self, name: &str) -> Result<u64, Box<dyn Error>> {
|
||||
pub fn get_offset_r(&self, name: &str) -> BoxResult<u64> {
|
||||
self.get_offset(name)
|
||||
.ok_or(format!("{} is not found in PDB", name).into())
|
||||
}
|
||||
@ -57,7 +56,7 @@ impl PdbStore {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn addr_decompose(&self, addr: u64, full_name: &str) -> Result<u64, Box<dyn Error>>{
|
||||
pub fn addr_decompose(&self, addr: u64, full_name: &str) -> BoxResult<u64>{
|
||||
if !full_name.contains(".") {
|
||||
return Err("Not decomposable".into());
|
||||
}
|
||||
@ -258,11 +257,12 @@ fn get_type_as_str(type_finder: &TypeFinder, typ: &TypeIndex) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn download_pdb() {
|
||||
let mut ntoskrnl = File::open(NTOSKRNL_PATH).expect("Cannot open ntoskrnl.exe");
|
||||
fn get_guid_age(exe_file: &str) -> BoxResult<(String, u32)>{
|
||||
// TODO: Check file existance
|
||||
let mut file = File::open(exe_file)?;
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
ntoskrnl.read_to_end(&mut buffer).expect("Cannot read file ntoskrnl.exe");
|
||||
file.read_to_end(&mut buffer)?;
|
||||
|
||||
let mut buffiter = buffer.chunks(4);
|
||||
while buffiter.next().unwrap() != [0x52, 0x53, 0x44, 0x53] {
|
||||
@ -292,37 +292,54 @@ pub fn download_pdb() {
|
||||
raw_age[0], raw_age[1], raw_age[2], raw_age[3]
|
||||
]);
|
||||
|
||||
let downloadurl = format!("{}/{}/{}{:X}/{}", PDB_SERVER_PATH, PDBNAME, guid, age, PDBNAME);
|
||||
println!("{}", downloadurl);
|
||||
|
||||
let mut resp = reqwest::blocking::get(&downloadurl).expect("request failed");
|
||||
let mut out = File::create(PDBNAME).expect("failed to create file");
|
||||
io::copy(&mut resp, &mut out).expect("failed to copy content");
|
||||
Ok((guid, age))
|
||||
}
|
||||
|
||||
pub fn parse_pdb() -> PdbStore {
|
||||
// TODO: Detect pdb file and ntoskrnl file version differs
|
||||
fn pdb_exists(pdbname: &str, guid: &str, age: u32) -> BoxResult<(bool, PathBuf)> {
|
||||
// Use a folder at %APPDATA% to save pdb files
|
||||
// %APPDATA%\lpus
|
||||
// |--ntoskrnl
|
||||
// %APPDATA%\nganhkhoaa\lpus
|
||||
// |--ntkrnlmp.pdb
|
||||
// |--|--GUID
|
||||
// |--|--|--ntkrnlmp.pdb
|
||||
// |--file
|
||||
// |--file.pdb
|
||||
// |--|--GUID
|
||||
// |--|--|--file.pdb
|
||||
// TODO: Turn function to Result to handle error
|
||||
if !Path::new(PDBNAME).exists() {
|
||||
download_pdb();
|
||||
}
|
||||
let f = File::open("ntkrnlmp.pdb").expect("No such file ./ntkrnlmp.pdb");
|
||||
let mut pdb = PDB::open(f).expect("Cannot open as a PDB file");
|
||||
let mut pdb_location = app_dir(AppDataType::UserData, &APP_INFO,
|
||||
&format!("{}/{}/{}", pdbname, guid, age))?;
|
||||
pdb_location.push(pdbname);
|
||||
Ok((pdb_location.exists(), pdb_location))
|
||||
}
|
||||
|
||||
let info = pdb.pdb_information().expect("Cannot get pdb information");
|
||||
let dbi = pdb.debug_information().expect("cannot get debug information");
|
||||
fn download_pdb(pdbname: &str, guid: &str, age: u32, outfile: &PathBuf) -> BoxResult<()> {
|
||||
let downloadurl = format!("{}/{}/{}{:X}/{}", PDB_SERVER_PATH, pdbname, guid, age, pdbname);
|
||||
println!("{}", downloadurl);
|
||||
|
||||
let mut resp = reqwest::blocking::get(&downloadurl)?;
|
||||
let mut out = File::create(outfile)?;
|
||||
io::copy(&mut resp, &mut out)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn parse_pdb() -> BoxResult<PdbStore> {
|
||||
// TODO: Resolve pdb name
|
||||
// ntoskrnl.exe -> ntkrnlmp.pdb
|
||||
// tcpip.sys -> tcpip.pdb ?????
|
||||
// There may be more pdb files in the future
|
||||
let (guid, age) = get_guid_age(NTOSKRNL_PATH)?;
|
||||
let (exists, pdb_path) = pdb_exists(KERNEL_PDB_NAME, &guid, age)?;
|
||||
if !exists {
|
||||
println!("PDB not found, download into {:?}", pdb_path);
|
||||
download_pdb(KERNEL_PDB_NAME, &guid, age, &pdb_path)?;
|
||||
}
|
||||
let f = File::open(pdb_path)?;
|
||||
let mut pdb = PDB::open(f)?;
|
||||
|
||||
let info = pdb.pdb_information()?;
|
||||
let dbi = pdb.debug_information()?;
|
||||
println!("PDB for {}, guid: {}, age: {}\n",
|
||||
dbi.machine_type().unwrap(), info.guid, dbi.age().unwrap_or(0));
|
||||
|
||||
let type_information = pdb.type_information().expect("Cannot get type information");
|
||||
let type_information = pdb.type_information()?;
|
||||
let mut type_finder = type_information.type_finder();
|
||||
let mut iter = type_information.iter();
|
||||
while let Some(_typ) = iter.next().unwrap() {
|
||||
@ -330,8 +347,8 @@ pub fn parse_pdb() -> PdbStore {
|
||||
}
|
||||
|
||||
let mut symbol_extracted: SymbolStore = HashMap::new();
|
||||
let addr_map = pdb.address_map().expect("Cannot get address map");
|
||||
let glosym = pdb.global_symbols().expect("Cannot get global symbols");
|
||||
let addr_map = pdb.address_map()?;
|
||||
let glosym = pdb.global_symbols()?;
|
||||
let mut symbols = glosym.iter();
|
||||
while let Some(symbol) = symbols.next().unwrap() {
|
||||
match symbol.parse() {
|
||||
@ -370,8 +387,8 @@ pub fn parse_pdb() -> PdbStore {
|
||||
}
|
||||
}
|
||||
|
||||
PdbStore {
|
||||
Ok(PdbStore {
|
||||
symbols: symbol_extracted,
|
||||
structs: struct_extracted
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ use winapi::um::securitybaseapi::{AdjustTokenPrivileges};
|
||||
use winapi::um::winbase::{LookupPrivilegeValueA};
|
||||
use winapi::um::winreg::{RegCreateKeyExA, RegSetValueExA, RegCloseKey, HKEY_LOCAL_MACHINE};
|
||||
|
||||
const STR_DRIVER_REGISTRY_PATH: &str = "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\nganhkhoa";
|
||||
const STR_DRIVER_REGISTRY_PATH: &str = "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\lpus";
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@ -61,8 +61,8 @@ impl WindowsFFI {
|
||||
let str_rtl_get_version = CString::new("RtlGetVersion").unwrap();
|
||||
let str_se_load_driver_privilege = CString::new("SeLoadDriverPrivilege").unwrap();
|
||||
|
||||
let str_driver_path = CString::new("\\SystemRoot\\System32\\DRIVERS\\nganhkhoa.sys").unwrap();
|
||||
let str_registry_path = CString::new("System\\CurrentControlSet\\Services\\nganhkhoa").unwrap();
|
||||
let str_driver_path = CString::new("\\SystemRoot\\System32\\DRIVERS\\lpus.sys").unwrap();
|
||||
let str_registry_path = CString::new("System\\CurrentControlSet\\Services\\lpus").unwrap();
|
||||
let str_type = CString::new("Type").unwrap();
|
||||
let str_error_control = CString::new("ErrorControl").unwrap();
|
||||
let str_start = CString::new("Start").unwrap();
|
||||
|
Reference in New Issue
Block a user