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:
nganhkhoa 2020-05-20 15:02:09 +07:00
parent 5842ed216c
commit 7be3b2fc05
7 changed files with 105 additions and 47 deletions

39
Cargo.lock generated
View File

@ -5,6 +5,17 @@ name = "anyhow"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "app_dirs"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "1.0.0"
@ -341,6 +352,7 @@ dependencies = [
name = "lpus"
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)",
"hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -464,6 +476,15 @@ dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ole32-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl"
version = "0.10.28"
@ -762,6 +783,15 @@ dependencies = [
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "shell32-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "slab"
version = "0.4.2"
@ -1099,8 +1129,14 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "xdg"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c"
"checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d"
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
@ -1157,6 +1193,7 @@ dependencies = [
"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
"checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c"
"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"
@ -1191,6 +1228,7 @@ dependencies = [
"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
"checksum serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25"
"checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
"checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc"
"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3"
@ -1233,3 +1271,4 @@ dependencies = [
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"

View File

@ -11,6 +11,7 @@ name = "lpus"
doctest = false
[dependencies]
app_dirs = "1.2.1"
hex = "0.4.2"
pdb = "0.5.0"
chrono = "0.4"

View File

@ -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);
}

View File

@ -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()
}
}

View File

@ -1,4 +1,5 @@
extern crate chrono;
extern crate app_dirs;
pub mod pdb_store;
pub mod windows;

View File

@ -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
}
})
}

View File

@ -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();