25 Commits

Author SHA1 Message Date
c8ce82e8a7 Update lpus
File scan printing update
Update values sent to driver in ioctl for Windows 10 2019/2018
2020-06-02 16:27:29 +07:00
4bf2bb71ff check read access when dump file name in _FILE_OBJECT 2020-05-29 01:39:32 +07:00
ecc476c604 Update scan frontend
Reject invalid block size
Unicode string handle for empty ptr, empty size
Add _FILE_OBJECT scan
Add FileImage dump of _EPROCESS scan
2020-05-22 14:44:47 +07:00
ee13c6be58 Update non-paged pool range documentation 2020-05-21 17:36:06 +07:00
7be3b2fc05 General updates
Driver is renamed to lpus.sys
Pdb will be downloaded ino %APPDATA%/nganhkhoa/lpus
And some little fixes
2020-05-20 15:02:09 +07:00
5842ed216c Add Windows 10 2019 support 2020-05-20 13:51:38 +07:00
ff53a1a31c Fix runtime BOSD
Chunk size and tag is check before handle.
Check if heuristics search is not correct, and the try_ptr goes of the bound,
making dereference an invalid address.
2020-05-20 00:42:24 +07:00
dd16a31984 update READMME 2020-05-19 04:20:04 +07:00
5bddf90501 Merge pull request #2 from nganhkhoa/device_io_call 2020-05-19 04:00:32 +07:00
dae10a5312 multiple binary and code refactor 2020-05-19 03:52:18 +07:00
3214e79d63 code renew build ok 2020-05-18 04:04:40 +07:00
cbc3cb7e15 update new design in code call, no test build 2020-05-04 11:40:31 +00:00
862a5c0788 hide process call 2020-02-27 23:37:04 +07:00
d0c0161b06 find eprocess offset base on CreateTime 2020-02-27 08:25:39 +07:00
d08852af55 finish device io call to scan 2020-02-27 03:27:54 +07:00
0ca87a871c fix driver file name path 2020-02-25 01:33:16 +07:00
2ee77d16c7 Fix load driver issue
The Buffer pointer of UNICODE_STRING seems to be cleaned up after
routine, so we cannot store the string, but have to init the string when
needed.
2020-02-25 01:20:54 +07:00
8928e4e4cb add device io call 2020-02-24 22:53:30 +07:00
c036f3645a Merge pull request #1 from nganhkhoa/loaddriver
Load Driver and PdbStore
2020-02-24 00:36:04 +07:00
ebeea02962 remove warnings 2020-02-24 00:32:53 +07:00
f872b8e14a moved functions to modules 2020-02-24 00:10:00 +07:00
71b59861c5 add driver to registry 2020-02-23 03:06:01 +07:00
30da3fe60a load driver code 2020-02-23 02:04:09 +07:00
fc61c5e605 update sample ouput 2020-02-18 17:44:14 +07:00
0bb4ecd0e3 update 18/2/2020 2020-02-18 17:39:31 +07:00
16 changed files with 52563 additions and 307 deletions

101
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"
@ -48,6 +59,16 @@ name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chrono"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "core-foundation"
version = "0.6.4"
@ -197,6 +218,11 @@ dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hex"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "http"
version = "0.2.0"
@ -322,6 +348,19 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
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)",
"reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "matches"
version = "0.1.8"
@ -411,6 +450,23 @@ dependencies = [
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num_cpus"
version = "1.12.0"
@ -420,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"
@ -450,14 +515,6 @@ dependencies = [
"vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parse_pdb_for_offsets"
version = "0.1.0"
dependencies = [
"pdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pdb"
version = "0.5.0"
@ -726,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"
@ -1012,6 +1078,11 @@ dependencies = [
"nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "widestring"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.8"
@ -1058,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"
@ -1068,6 +1145,7 @@ dependencies = [
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
"checksum dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3"
@ -1088,6 +1166,7 @@ dependencies = [
"checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
"checksum hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
"checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b"
"checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
@ -1111,7 +1190,10 @@ dependencies = [
"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
"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"
@ -1146,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"
@ -1180,6 +1263,7 @@ dependencies = [
"checksum wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d"
"checksum web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b"
"checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164"
"checksum widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
@ -1187,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

@ -1,12 +1,20 @@
[package]
name = "parse_pdb_for_offsets"
name = "lpus"
version = "0.1.0"
authors = ["nganhkhoa <mail.nganhkhoa@gmail.com>"]
description = "Live pool tag scanning frontend"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "lpus"
doctest = false
[dependencies]
app_dirs = "1.2.1"
hex = "0.4.2"
pdb = "0.5.0"
chrono = "0.4"
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"] }

138
README.md
View File

@ -1,123 +1,35 @@
> If you came here for `MmNonPagedPoolStart`, `MmNonPagedPoolEnd`, you ended up at the right place.
# LPUS (A live pool-tag scanning solution)
`NonPagedPool` in Windows has two variables that defined the start and end of the section in kernel memory. Online blog posts and tutorials show an outdated version of these two variables.
This is the frontend to the live pool tag scanning solution, the backend is a driver (which is now closed source).
Take a look at [this old post](https://web.archive.org/web/20061110120809/http://www.rootkit.com/newsread.php?newsid=153). `_DBGKD_GET_VERSION64 KdVersionBlock` was a very important structure into the debugger block of Windows. However, if you try to find this structure in Windows 10, you will hit `KdVersionBlock == 0` (Ouch!!!). But this structure provides offset into `MmNonPagedPool{Start,End}`, how can we get those?
## How this works
Luckily, both `MmNonPagedPoolStart` and `MmNonPagedPoolEnd` in Windows XP, can be found by offseting from `ntoskrnl.exe`. Rekall team are very positive that their tools doesn't rely on profiles file like Volatility but use PDB provided by Windows to find these values.
In simple way, we use PDB files to get the global variable offsets and structure definitions.
The backend finds the kernel base and use these values to calculate the nonpaged-pool range.
A more detailed report is in [nonpaged-pool-range.md](nonpaged-pool-range.md)
The frontend calls the backend to scan for a specific tag.
In [Rekall source code](https://github.com/google/rekall/blob/c5d68e31705f4b5bd2581c1d951b7f6983f7089c/rekall-core/rekall/plugins/windows/pool.py#L87), the values of those variables are:
## How to use
- Windows XP: `MmNonPagedPool{Start,End}`
- Windows 7 and maybe 8: `MiNonPagedPoolStartAligned`, `MiNonPagedPoolEnd`, and `MiNonPagedPoolBitMap`
- Windows 10 below
Example is [here](./src/bin/eprocess_scan.rs).
In Windows 7, 8, another field was added to controll the allocation of `NonPagedPool`, which is why there is [this paper about pool tag quick scanning](https://www.sciencedirect.com/science/article/pii/S1742287616000062).
However, from Windows 10, the whole game change around when the global offset to those (similar) variables. Instead Windows 10 introduced a new structure `MiState`. `MiState` offset is available and we can get the variables by either:
- Windows 2015: `*((ntoskrnl.exe+MiState)->SystemNodeInformation->NonPagedPool{First,Last}Va)`
- Windows 2016: `*((ntoskrnl.exe+MiState)->Hardware.SystemNodeInformation->NonPagedPool{First,Last}Va)`
The `NonPagedBitMap` was still visible untill the May 2019 Update, here, take a look at these 2 consecutive update [`1809 Redstone 5 (October Update)`](https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/1809%20Redstone%205%20(October%20Update)/\_MI\_SYSTEM\_NODE\_INFORMATION) and [`1903 19H1 (May 2019 Update)`](https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/1903%2019H1%20(May%202019%20Update)/\_MI\_SYSTEM\_NODE\_INFORMATION).
Yeah, now `pool tag quick scanning` is useless (gah). Windows OS changes quite frequently right? Tell you more, I am using the Insider version of Windows in 2020, and guess what, I found out that they put another struct to point to those value. So now we need to go like this:
- Windows 2020 Insider preview: `*((ntoskrnl.exe+MiState)->SystemNodeNonPagedPool->NonPagedPool{First,Last}Va)`
Anyway, I create this project to help me with my thesis, following outdated structs online yields no result. Oh, yeah, a guy seems to be asking on [how to get `MmNonPagedPoolStart`](https://reverseengineering.stackexchange.com/q/6483) on `stackexchange`, too bad [the answer](https://reverseengineering.stackexchange.com/a/6487) is not so much helpful.
Take a look at my ntoskrnl.exe pdb file parsed.
```rust
use lpus::{
driver_state::{DriverState}
};
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
driver.scan_pool(b"Tag ", |pool_addr, header, data_addr| {
})?;
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
}
```
PDB for Amd64, guid: 3e7ee354-590f-ac1c-62a8-ccf0b6368989, age: 1,
MiState 0xc4f280 23:324224
KdDebuggerDataBlock 0xc00a30 23:2608
The closure is a mutable closure, so you can just put a vector and saves the result.
The function signature for the closure is: `FnMut(u64, &[u8], u64) -> Result<bool, std::error::Error>`
Parsing the struct data is up to you.
You can use `driver.deref_addr(addr, &value)` to dereference an address in kernel space
and `driver.pdb_store.get_offset_r("offset")?` to get an offset from PDB file.
struct _MI_SYSTEM_INFORMATION
- field _MI_POOL_STATE Pools at offset 0
- field _MI_SECTION_STATE Sections at offset c0
- field _MI_SYSTEM_IMAGE_STATE SystemImages at offset 400
- field _MI_SESSION_STATE Sessions at offset 4a8
- field _MI_PROCESS_STATE Processes at offset 1550
- field _MI_HARDWARE_STATE Hardware at offset 15c0
- field _MI_SYSTEM_VA_STATE SystemVa at offset 1780
- field _MI_COMBINE_STATE PageCombines at offset 1c40
- field _MI_PAGELIST_STATE PageLists at offset 1c60
- field _MI_PARTITION_STATE Partitions at offset 1d00
- field _MI_SHUTDOWN_STATE Shutdowns at offset 1dc0
- field _MI_ERROR_STATE Errors at offset 1e38
- field _MI_ACCESS_LOG_STATE AccessLog at offset 1f40
- field _MI_DEBUGGER_STATE Debugger at offset 1fc0
- field _MI_STANDBY_STATE Standby at offset 20e0
- field _MI_SYSTEM_PTE_STATE SystemPtes at offset 2180
- field _MI_IO_PAGE_STATE IoPages at offset 2380
- field _MI_PAGING_IO_STATE PagingIo at offset 2440
- field _MI_COMMON_PAGE_STATE CommonPages at offset 24f0
- field _MI_SYSTEM_TRIM_STATE Trims at offset 25c0
- field _MI_SYSTEM_ZEROING Zeroing at offset 2600
- field _MI_ENCLAVE_STATE Enclaves at offset 2620
- field U64 Cookie at offset 2668
- field Void** BootRegistryRuns at offset 2670
- field UNNOWN ZeroingDisabled at offset 2678
- field UChar FullyInitialized at offset 267c
- field UChar SafeBooted at offset 267d
- field UNNOWN* TraceLogging at offset 2680
- field _MI_VISIBLE_STATE Vs at offset 26c0
struct _MI_HARDWARE_STATE
- field U32 NodeMask at offset 0
- field U32 NumaHintIndex at offset 4
- field U32 NumaLastRangeIndexInclusive at offset 8
- field UChar NodeShift at offset c
- field UChar ChannelShift at offset d
- field U32 ChannelHintIndex at offset 10
- field U32 ChannelLastRangeIndexInclusive at offset 14
- field _MI_NODE_NUMBER_ZERO_BASED* NodeGraph at offset 18
- field _MI_SYSTEM_NODE_NONPAGED_POOL* SystemNodeNonPagedPool at offset 20
- field UNNOWN TemporaryNumaRanges at offset 28
- field _HAL_NODE_RANGE* NumaMemoryRanges at offset 48
- field _HAL_CHANNEL_MEMORY_RANGES* ChannelMemoryRanges at offset 50
- field U32 SecondLevelCacheSize at offset 58
- field U32 FirstLevelCacheSize at offset 5c
- field U32 PhysicalAddressBits at offset 60
- field U32 PfnDatabasePageBits at offset 64
- field U32 LogicalProcessorsPerCore at offset 68
- field UChar ProcessorCachesFlushedOnPowerLoss at offset 6c
- field U64 TotalPagesAllowed at offset 70
- field U32 SecondaryColorMask at offset 78
- field U32 SecondaryColors at offset 7c
- field U32 FlushTbForAttributeChange at offset 80
- field U32 FlushCacheForAttributeChange at offset 84
- field U32 FlushCacheForPageAttributeChange at offset 88
- field U32 CacheFlushPromoteThreshold at offset 8c
- field _LARGE_INTEGER PerformanceCounterFrequency at offset 90
- field U64 InvalidPteMask at offset c0
- field UNNOWN LargePageColors at offset 100
- field U64 FlushTbThreshold at offset 110
- field UNNOWN OptimalZeroingAttribute at offset 118
- field UChar AttributeChangeRequiresReZero at offset 158
- field UNNOWN ZeroCostCounts at offset 160
- field U64 HighestPossiblePhysicalPage at offset 180
- field U64 VsmKernelPageCount at offset 188
struct _MI_SYSTEM_NODE_NONPAGED_POOL
- field _MI_DYNAMIC_BITMAP DynamicBitMapNonPagedPool at offset 0
- field U64 CachedNonPagedPoolCount at offset 48
- field U64 NonPagedPoolSpinLock at offset 50
- field _MMPFN* CachedNonPagedPool at offset 58
- field Void NonPagedPoolFirstVa at offset 60
- field Void NonPagedPoolLastVa at offset 68
- field _MI_SYSTEM_NODE_INFORMATION* SystemNodeInformation at offset 70
struct _MI_SYSTEM_NODE_INFORMATION
- field UNNOWN CachedKernelStacks at offset 0
- field _GROUP_AFFINITY GroupAffinity at offset 40
- field U16 ProcessorCount at offset 50
- field Void BootZeroPageTimesPerProcessor at offset 58
- field U64 CyclesToZeroOneLargePage at offset 60
- field U64 ScaledCyclesToZeroOneLargePage at offset 68
- field _MI_WRITE_CALIBRATION WriteCalibration at offset 70
- field UNNOWN IoPfnLock at offset c0
```

View File

@ -0,0 +1,325 @@
PDB for Amd64, guid: 94add4fd-403f-5f1a-8d4b-aba8db5d5b7a, age: 1
NtLoadDriver() -> 0x0
pool: 0xffffa80e2cced000 | eprocess: 0xffffa80e2cced040 | | System
pool: 0xffffa80e2cd17000 | eprocess: 0xffffa80e2cd17080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e2cd3d010 | eprocess: 0xffffa80e2cd3d080 | | Registry
pool: 0xffffa80e2cd3e000 | eprocess: 0xffffa80e2cd3e080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e2cd79040 | eprocess: 0xffffa80e2cd79080 | | Secure System
pool: 0xffffa80e2cdc8000 | eprocess: 0xffffa80e2cdc8080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e2efcc000 | eprocess: 0xffffa80e2efcc080 | | svchost.exe
pool: 0xffffa80e2efcf000 | eprocess: 0xffffa80e2efcf080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e2efd1000 | eprocess: 0xffffa80e2efd1080 | \Program Files\Dell\SupportAssistAgent\PCDr\SupportAssist\6.0.7106.1428\DSAPI.exe | DSAPI.exe
pool: 0xffffa80e316cb0f0 | eprocess: 0xffffa80e316cb180 | \Windows\System32\dllhost.exe | dllhost.exe
pool: 0xffffa80e365b9000 | eprocess: 0xffffa80e365b9040 | \Windows\System32\smss.exe | smss.exe
pool: 0xffffa80e368ed000 | eprocess: 0xffffa80e368ed080 | | smss.exe
pool: 0xffffa80e369420c0 | eprocess: 0xffffa80e36942140 | \Windows\System32\csrss.exe | csrss.exe
pool: 0xffffa80e384c1000 | eprocess: 0xffffa80e384c1080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e38502040 | eprocess: 0xffffa80e385020c0 | \Windows\System32\wbem\WmiPrvSE.exe | WmiPrvSE.exe
pool: 0xffffa80e38772000 | eprocess: 0xffffa80e38772080 | | smss.exe
pool: 0xffffa80e3877e0c0 | eprocess: 0xffffa80e3877e140 | \Windows\System32\csrss.exe | csrss.exe
pool: 0xffffa80e3877f000 | eprocess: 0xffffa80e3877f080 | \Windows\System32\wininit.exe | wininit.exe
pool: 0xffffa80e387d4000 | eprocess: 0xffffa80e387d4080 | \Windows\System32\ibtsiva.exe | ibtsiva.exe
pool: 0xffffa80e387f2000 | eprocess: 0xffffa80e387f2080 | \Windows\System32\services.exe | services.exe
pool: 0xffffa80e387f4000 | eprocess: 0xffffa80e387f4080 | \Windows\System32\lsass.exe | lsass.exe
pool: 0xffffa80e387f6000 | eprocess: 0xffffa80e387f6080 | \Windows\System32\LsaIso.exe | LsaIso.exe
pool: 0xffffa80e38e88000 | eprocess: 0xffffa80e38e88080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e38eed000 | eprocess: 0xffffa80e38eed080 | \Windows\System32\fontdrvhost.exe | fontdrvhost.ex
pool: 0xffffa80e38ef9000 | eprocess: 0xffffa80e38ef9080 | \Windows\System32\WUDFHost.exe | WUDFHost.exe
pool: 0xffffa80e38fc1000 | eprocess: 0xffffa80e38fc1080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39005000 | eprocess: 0xffffa80e39005080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39006000 | eprocess: 0xffffa80e39006080 | \Windows\System32\winlogon.exe | winlogon.exe
pool: 0xffffa80e39102040 | eprocess: 0xffffa80e391020c0 | \Windows\System32\fontdrvhost.exe | fontdrvhost.ex
pool: 0xffffa80e39107000 | eprocess: 0xffffa80e39107080 | \Windows\System32\dwm.exe | dwm.exe
pool: 0xffffa80e3910a000 | eprocess: 0xffffa80e3910a080 | | LogonUI.exe
pool: 0xffffa80e391c10b0 | eprocess: 0xffffa80e391c1140 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e391c5000 | eprocess: 0xffffa80e391c5080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39259000 | eprocess: 0xffffa80e39259080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39264000 | eprocess: 0xffffa80e39264080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39289040 | eprocess: 0xffffa80e392890c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e392db000 | eprocess: 0xffffa80e392db080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e392de000 | eprocess: 0xffffa80e392de080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e392e4000 | eprocess: 0xffffa80e392e4080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39306000 | eprocess: 0xffffa80e39306080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3930d000 | eprocess: 0xffffa80e3930d080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3930f000 | eprocess: 0xffffa80e3930f080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e393bc040 | eprocess: 0xffffa80e393bc0c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e393c1000 | eprocess: 0xffffa80e393c1080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e393c2000 | eprocess: 0xffffa80e393c2080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e393d5000 | eprocess: 0xffffa80e393d5080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39423040 | eprocess: 0xffffa80e394230c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39430000 | eprocess: 0xffffa80e39430080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39454000 | eprocess: 0xffffa80e39454080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39580000 | eprocess: 0xffffa80e39580080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e395ab000 | eprocess: 0xffffa80e395ab080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e395af000 | eprocess: 0xffffa80e395af080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39613040 | eprocess: 0xffffa80e396130c0 | \Program Files (x86)\Dell\UpdateService\ServiceShell.exe | ServiceShell.e
pool: 0xffffa80e39637000 | eprocess: 0xffffa80e39637080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3965e000 | eprocess: 0xffffa80e3965e080 | \Windows\System32\vmms.exe | vmms.exe
pool: 0xffffa80e39677000 | eprocess: 0xffffa80e39677080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e396eb000 | eprocess: 0xffffa80e396eb080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39723040 | eprocess: 0xffffa80e397230c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3977a070 | eprocess: 0xffffa80e3977a100 | \Program Files\NVIDIA Corporation\Display.NvContainer\NVDisplay.Container.exe | NVDisplay.Cont
pool: 0xffffa80e39785000 | eprocess: 0xffffa80e39785080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3979d000 | eprocess: 0xffffa80e3979d080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e397a1000 | eprocess: 0xffffa80e397a1080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e397a8000 | eprocess: 0xffffa80e397a8080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e397f6000 | eprocess: 0xffffa80e397f6080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39829000 | eprocess: 0xffffa80e39829040 | | MemCompression
pool: 0xffffa80e3982f000 | eprocess: 0xffffa80e3982f080 | \Windows\System32\DriverStore\FileRepository\ki127176.inf_amd64_86c658cabfb17c9c\igfxCUIService.exe | igfxCUIService
pool: 0xffffa80e39842000 | eprocess: 0xffffa80e39842080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3984e000 | eprocess: 0xffffa80e3984e080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39853000 | eprocess: 0xffffa80e39853080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39983000 | eprocess: 0xffffa80e39983080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e399e3000 | eprocess: 0xffffa80e399e3080 | \Program Files\NVIDIA Corporation\Display.NvContainer\NVDisplay.Container.exe | NVDisplay.Cont
pool: 0xffffa80e39a47000 | eprocess: 0xffffa80e39a47080 | \Windows\System32\SettingSyncHost.exe | SettingSyncHos
pool: 0xffffa80e39a48000 | eprocess: 0xffffa80e39a48080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39a4c000 | eprocess: 0xffffa80e39a4c080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39a50000 | eprocess: 0xffffa80e39a50080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39a6d000 | eprocess: 0xffffa80e39a6d080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39a98000 | eprocess: 0xffffa80e39a98080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39ab5000 | eprocess: 0xffffa80e39ab5080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39b08000 | eprocess: 0xffffa80e39b08080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39b84000 | eprocess: 0xffffa80e39b84080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39c49000 | eprocess: 0xffffa80e39c49080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39c89000 | eprocess: 0xffffa80e39c89080 | \Windows\System32\wbem\WmiPrvSE.exe | WmiPrvSE.exe
pool: 0xffffa80e39dc5000 | eprocess: 0xffffa80e39dc5080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39dc7040 | eprocess: 0xffffa80e39dc70c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e39ea0000 | eprocess: 0xffffa80e39ea0080 | \Windows\System32\spoolsv.exe | spoolsv.exe
pool: 0xffffa80e39fc2040 | eprocess: 0xffffa80e39fc20c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a0ab000 | eprocess: 0xffffa80e3a0ab080 | \Program Files (x86)\Common Files\Adobe\Adobe Desktop Common\ElevationManager\AdobeUpdateService.exe | AdobeUpdateSer
pool: 0xffffa80e3a0ac000 | eprocess: 0xffffa80e3a0ac080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a0b11d0 | eprocess: 0xffffa80e3a0b1240 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a0b4000 | eprocess: 0xffffa80e3a0b4080 | \Program Files (x86)\Common Files\Adobe\ARM\1.0\armsvc.exe | armsvc.exe
pool: 0xffffa80e3a1a7000 | eprocess: 0xffffa80e3a1a7080 | \Program Files (x86)\Common Files\Adobe\AdobeGCClient\AGMService.exe | AGMService.exe
pool: 0xffffa80e3a1a8000 | eprocess: 0xffffa80e3a1a8080 | \Program Files\Common Files\microsoft shared\ClickToRun\OfficeClickToRun.exe | OfficeClickToR
pool: 0xffffa80e3a1ab000 | eprocess: 0xffffa80e3a1ab080 | \Program Files\Docker\Docker\com.docker.service | com.docker.ser
pool: 0xffffa80e3a1ac000 | eprocess: 0xffffa80e3a1ac080 | \Windows\System32\DriverStore\FileRepository\ki127176.inf_amd64_86c658cabfb17c9c\IntelCpHDCPSvc.exe | IntelCpHDCPSvc
pool: 0xffffa80e3a21b000 | eprocess: 0xffffa80e3a21b080 | \Windows\System32\CxAudMsg64.exe | CxAudMsg64.exe
pool: 0xffffa80e3a21c000 | eprocess: 0xffffa80e3a21c080 | \Program Files\CONEXANT\SA3\Dell-Notebook\CxUtilSvc.exe | CxUtilSvc.exe
pool: 0xffffa80e3a245000 | eprocess: 0xffffa80e3a245080 | \Windows\System32\DbxSvc.exe | DbxSvc.exe
pool: 0xffffa80e3a246000 | eprocess: 0xffffa80e3a246080 | \Windows\System32\wlanext.exe | wlanext.exe
pool: 0xffffa80e3a24d000 | eprocess: 0xffffa80e3a24d080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e3a251000 | eprocess: 0xffffa80e3a251080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a27a000 | eprocess: 0xffffa80e3a27a080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a2a1000 | eprocess: 0xffffa80e3a2a1080 | \Windows\System32\sihost.exe | sihost.exe
pool: 0xffffa80e3a2a9040 | eprocess: 0xffffa80e3a2a90c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a2ad1d0 | eprocess: 0xffffa80e3a2ad240 | \Windows\System32\ApplicationFrameHost.exe | ApplicationFra
pool: 0xffffa80e3a2b2000 | eprocess: 0xffffa80e3a2b2080 | \Windows\System32\Intel\DPTF\esif_uf.exe | esif_uf.exe
pool: 0xffffa80e3a2b4070 | eprocess: 0xffffa80e3a2b4100 | \Program Files\Intel\Intel(R) Online Connect Access\IntelTechnologyAccessService.exe | IntelTechnolog
pool: 0xffffa80e3a2b5000 | eprocess: 0xffffa80e3a2b5080 | \Program Files\Intel\WiFi\bin\EvtEng.exe | EvtEng.exe
pool: 0xffffa80e3a2b8000 | eprocess: 0xffffa80e3a2b8080 | \Windows\System32\FMService64.exe | FMService64.ex
pool: 0xffffa80e3a2d5000 | eprocess: 0xffffa80e3a2d5080 | \Program Files\Intel\Intel(R) Rapid Storage Technology\IAStorIcon.exe | IAStorIcon.exe
pool: 0xffffa80e3a362000 | eprocess: 0xffffa80e3a362080 | \Program Files (x86)\Common Files\Microsoft Shared\Phone Tools\CoreCon\11.0\bin\IpOverUsbSvc.exe | IpOverUsbSvc.e
pool: 0xffffa80e3a363000 | eprocess: 0xffffa80e3a363080 | \Program Files\Intel\Intel(R) Online Connect Access\LegacyCsLoaderService.exe | LegacyCsLoader
pool: 0xffffa80e3a36c080 | eprocess: 0xffffa80e3a36c100 | \Program Files (x86)\NVIDIA Corporation\NvTelemetry\NvTelemetryContainer.exe | NvTelemetryCon
pool: 0xffffa80e3a37d000 | eprocess: 0xffffa80e3a37d080 | \Windows\SysWOW64\PnkBstrA.exe | PnkBstrA.exe
pool: 0xffffa80e3a3a4000 | eprocess: 0xffffa80e3a3a4080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a3a5000 | eprocess: 0xffffa80e3a3a5080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a447000 | eprocess: 0xffffa80e3a447080 | \Program Files\Rivet Networks\SmartByte\SmartByteNetworkService.exe | SmartByteNetwo
pool: 0xffffa80e3a448000 | eprocess: 0xffffa80e3a448080 | \Program Files\Microsoft SQL Server\90\Shared\sqlwriter.exe | sqlwriter.exe
pool: 0xffffa80e3a44d000 | eprocess: 0xffffa80e3a44d080 | \Windows\ThunderboltService.exe | ThunderboltSer
pool: 0xffffa80e3a44f000 | eprocess: 0xffffa80e3a44f080 | \Windows\System32\RtkAudUService64.exe | RtkAudUService
pool: 0xffffa80e3a450000 | eprocess: 0xffffa80e3a450080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a514000 | eprocess: 0xffffa80e3a514080 | \Program Files\TrueColor\TrueColorALS.exe | TrueColorALS.e
pool: 0xffffa80e3a51a000 | eprocess: 0xffffa80e3a51a080 | \Program Files\Intel\WiFi\bin\ZeroConfigService.exe | ZeroConfigServ
pool: 0xffffa80e3a51b000 | eprocess: 0xffffa80e3a51b080 | \Program Files (x86)\TeamViewer\TeamViewer_Service.exe | TeamViewer_Ser
pool: 0xffffa80e3a520000 | eprocess: 0xffffa80e3a520080 | \Program Files (x86)\Western Digital\WD Drive Manager\WDDriveService.exe | WDDriveService
pool: 0xffffa80e3a521000 | eprocess: 0xffffa80e3a521080 | \Windows\System32\dasHost.exe | dasHost.exe
pool: 0xffffa80e3a522000 | eprocess: 0xffffa80e3a522080 | \Program Files\Waves\MaxxAudio\WavesSysSvc64.exe | WavesSysSvc64.
pool: 0xffffa80e3a562000 | eprocess: 0xffffa80e3a562080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a565000 | eprocess: 0xffffa80e3a565080 | \ProgramData\Microsoft\Windows Defender\Platform\4.18.2004.6-0\MsMpEng.exe | MsMpEng.exe
pool: 0xffffa80e3a586000 | eprocess: 0xffffa80e3a586080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a587000 | eprocess: 0xffffa80e3a587080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a588000 | eprocess: 0xffffa80e3a588080 | \Windows\System32\DriverStore\FileRepository\ki127176.inf_amd64_86c658cabfb17c9c\igfxext.exe | igfxext.exe
pool: 0xffffa80e3a589000 | eprocess: 0xffffa80e3a589080 | \Windows\System32\vmcompute.exe | vmcompute.exe
pool: 0xffffa80e3a58b000 | eprocess: 0xffffa80e3a58b080 | \Windows\System32\wbem\unsecapp.exe | unsecapp.exe
pool: 0xffffa80e3a58c000 | eprocess: 0xffffa80e3a58c080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a58d000 | eprocess: 0xffffa80e3a58d080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3a592040 | eprocess: 0xffffa80e3a5920c0 | \Windows\System32\DriverStore\FileRepository\ki127176.inf_amd64_86c658cabfb17c9c\IntelCpHeciSvc.exe | IntelCpHeciSvc
pool: 0xffffa80e3a593000 | eprocess: 0xffffa80e3a593080 | \Windows\System32\Intel\DPTF\dptf_helper.exe | dptf_helper.ex
pool: 0xffffa80e3abf7000 | eprocess: 0xffffa80e3abf7080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3ad6f000 | eprocess: 0xffffa80e3ad6f080 | \Windows\System32\dllhost.exe | dllhost.exe
pool: 0xffffa80e3b05e040 | eprocess: 0xffffa80e3b05e0c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e3b08b000 | eprocess: 0xffffa80e3b08b080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3b090000 | eprocess: 0xffffa80e3b090080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3b0be000 | eprocess: 0xffffa80e3b0be080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3b0bf000 | eprocess: 0xffffa80e3b0bf080 | | GoogleUpdate.e
pool: 0xffffa80e3b0e6040 | eprocess: 0xffffa80e3b0e60c0 | \Windows\System32\taskhostw.exe | taskhostw.exe
pool: 0xffffa80e3b0f1000 | eprocess: 0xffffa80e3b0f1080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3b0f3000 | eprocess: 0xffffa80e3b0f3080 | \Program Files (x86)\Dropbox\Update\DropboxUpdate.exe | DropboxUpdate.
pool: 0xffffa80e3b18a000 | eprocess: 0xffffa80e3b18a080 | \Windows\Microsoft.NET\Framework64\v3.0\WPF\PresentationFontCache.exe | PresentationFo
pool: 0xffffa80e3b206060 | eprocess: 0xffffa80e3b2060c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3b208000 | eprocess: 0xffffa80e3b208080 | \Windows\System32\ctfmon.exe | ctfmon.exe
pool: 0xffffa80e3b27b000 | eprocess: 0xffffa80e3b27b080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3b2d9000 | eprocess: 0xffffa80e3b2d9080 | | userinit.exe
pool: 0xffffa80e3b3b9040 | eprocess: 0xffffa80e3b3b90c0 | \Windows\explorer.exe | explorer.exe
pool: 0xffffa80e3b3f6000 | eprocess: 0xffffa80e3b3f6080 | | cmd.exe
pool: 0xffffa80e3b428000 | eprocess: 0xffffa80e3b428080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3b429000 | eprocess: 0xffffa80e3b429080 | \Windows\System32\InputMethod\CHS\ChsIME.exe | ChsIME.exe
pool: 0xffffa80e3b49d120 | eprocess: 0xffffa80e3b49d180 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3b4a00c0 | eprocess: 0xffffa80e3b4a0140 | \Windows\System32\SearchIndexer.exe | SearchIndexer.
pool: 0xffffa80e3b661000 | eprocess: 0xffffa80e3b661080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3b698000 | eprocess: 0xffffa80e3b698080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3b6cd000 | eprocess: 0xffffa80e3b6cd080 | \Windows\System32\DriverStore\FileRepository\ki127176.inf_amd64_86c658cabfb17c9c\igfxEM.exe | igfxEM.exe
pool: 0xffffa80e3b74f000 | eprocess: 0xffffa80e3b74f080 | \ProgramData\Microsoft\Windows Defender\Platform\4.18.2004.6-0\NisSrv.exe | NisSrv.exe
pool: 0xffffa80e3b8cf000 | eprocess: 0xffffa80e3b8cf080 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffffa80e3b9de000 | eprocess: 0xffffa80e3b9de080 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffffa80e3bac5040 | eprocess: 0xffffa80e3bac50c0 | | HxTsr.exe
pool: 0xffffa80e3bad6040 | eprocess: 0xffffa80e3bad60c0 | \Windows\SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\StartMenuExperienceHost.exe | StartMenuExper
pool: 0xffffa80e3bbbb000 | eprocess: 0xffffa80e3bbbb080 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffffa80e3bc0b000 | eprocess: 0xffffa80e3bc0b080 | \Program Files\WindowsApps\FACEBOOK.317180B0BB486_520.3.60.0_x64__8xx8rvfyw5nnt\app\Messenger.exe | Messenger.exe
pool: 0xffffa80e3bc83000 | eprocess: 0xffffa80e3bc83080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e3bccc040 | eprocess: 0xffffa80e3bccc0c0 | \Windows\SystemApps\ShellExperienceHost_cw5n1h2txyewy\ShellExperienceHost.exe | ShellExperienc
pool: 0xffffa80e3bd1e000 | eprocess: 0xffffa80e3bd1e080 | \Windows\SystemApps\MicrosoftWindows.Client.CBS_cw5n1h2txyewy\TextInputHost.exe | TextInputHost.
pool: 0xffffa80e3be13040 | eprocess: 0xffffa80e3be130c0 | \Windows\System32\MicrosoftEdgeCP.exe | MicrosoftEdgeC
pool: 0xffffa80e3be2a000 | eprocess: 0xffffa80e3be2a080 | \Program Files\WindowsApps\Microsoft.SkypeApp_14.56.102.0_x64__kzf8qxf38zg5c\SkypeApp.exe | SkypeApp.exe
pool: 0xffffa80e3be3f000 | eprocess: 0xffffa80e3be3f080 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffffa80e3bea3000 | eprocess: 0xffffa80e3bea3080 | \Windows\System32\RtkAudUService64.exe | RtkAudUService
pool: 0xffffa80e3bf6d000 | eprocess: 0xffffa80e3bf6d080 | \Windows\SystemApps\Microsoft.LockApp_cw5n1h2txyewy\LockApp.exe | LockApp.exe
pool: 0xffffa80e3bfd6000 | eprocess: 0xffffa80e3bfd6080 | \Program Files\WindowsApps\Microsoft.SkypeApp_14.56.102.0_x64__kzf8qxf38zg5c\SkypeBackgroundHost.exe | SkypeBackgroun
pool: 0xffffa80e442ac000 | eprocess: 0xffffa80e442ac080 | | IAStorIconLaun
pool: 0xffffa80e442b3000 | eprocess: 0xffffa80e442b3080 | \Program Files\CONEXANT\cAudioFilterAgent\CAudioFilterAgent64.exe | CAudioFilterAg
pool: 0xffffa80e443d8040 | eprocess: 0xffffa80e443d80c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e44480020 | eprocess: 0xffffa80e44480080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e444f5020 | eprocess: 0xffffa80e444f5080 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffffa80e4452f000 | eprocess: 0xffffa80e4452f080 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e445be000 | eprocess: 0xffffa80e445be080 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e445c4000 | eprocess: 0xffffa80e445c4080 | \Program Files\Dell\DellDataVault\DDVRulesProcessor.exe | DDVRulesProces
pool: 0xffffa80e445e6000 | eprocess: 0xffffa80e445e6080 | \Windows\System32\SecurityHealthService.exe | SecurityHealth
pool: 0xffffa80e445e8000 | eprocess: 0xffffa80e445e8080 | \Windows\System32\SecurityHealthSystray.exe | SecurityHealth
pool: 0xffffa80e44613040 | eprocess: 0xffffa80e446130c0 | \Windows\SystemApps\Microsoft.Windows.Search_cw5n1h2txyewy\SearchApp.exe | SearchApp.exe
pool: 0xffffa80e446fb000 | eprocess: 0xffffa80e446fb080 | \Program Files (x86)\Google\Update\1.3.35.452\GoogleCrashHandler.exe | GoogleCrashHan
pool: 0xffffa80e4474c000 | eprocess: 0xffffa80e4474c080 | \Program Files (x86)\Google\Update\1.3.35.452\GoogleCrashHandler64.exe | GoogleCrashHan
pool: 0xffffa80e44771140 | eprocess: 0xffffa80e447711c0 | \Windows\ImmersiveControlPanel\SystemSettings.exe | SystemSettings
pool: 0xffffa80e44773050 | eprocess: 0xffffa80e447730c0 | \Windows\System32\Speech_OneCore\common\SpeechRuntime.exe | SpeechRuntime.
pool: 0xffffa80e448f5000 | eprocess: 0xffffa80e448f5080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e449eb000 | eprocess: 0xffffa80e449eb080 | \Program Files\WindowsApps\FACEBOOK.317180B0BB486_520.3.60.0_x64__8xx8rvfyw5nnt\app\Messenger.exe | Messenger.exe
pool: 0xffffa80e44cec000 | eprocess: 0xffffa80e44cec080 | \Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL\jhi_service.exe | jhi_service.ex
pool: 0xffffa80e44cee000 | eprocess: 0xffffa80e44cee080 | \Program Files\Intel\Intel(R) Rapid Storage Technology\IAStorDataMgrSvc.exe | IAStorDataMgrS
pool: 0xffffa80e44eb3000 | eprocess: 0xffffa80e44eb3080 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e45154040 | eprocess: 0xffffa80e451540c0 | \Windows\System32\msdtc.exe | msdtc.exe
pool: 0xffffa80e451c8040 | eprocess: 0xffffa80e451c80c0 | \Program Files\Dell\DellDataVault\DDVDataCollector.exe | DDVDataCollect
pool: 0xffffa80e451f0000 | eprocess: 0xffffa80e451f0080 | \Program Files (x86)\Intel\Intel(R) Management Engine Components\LMS\LMS.exe | LMS.exe
pool: 0xffffa80e451f4000 | eprocess: 0xffffa80e451f4080 | \Windows\System32\vmwp.exe | vmwp.exe
pool: 0xffffa80e45208000 | eprocess: 0xffffa80e45208080 | \Program Files\Dell\DellDataVault\DDVCollectorSvcApi.exe | DDVCollectorSv
pool: 0xffffa80e45235040 | eprocess: 0xffffa80e452350c0 | \ProgramData\Microsoft\Windows Defender\Scans\MsMpEngCP.exe | MsMpEngCP.exe
pool: 0xffffa80e452f7050 | eprocess: 0xffffa80e452f70c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e453c9040 | eprocess: 0xffffa80e453c90c0 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e453eb040 | eprocess: 0xffffa80e453eb0c0 | \Windows\System32\dllhost.exe | dllhost.exe
pool: 0xffffa80e4549e000 | eprocess: 0xffffa80e4549e080 | \Program Files\Docker\Docker\Docker Desktop.exe | Docker Desktop
pool: 0xffffa80e45502040 | eprocess: 0xffffa80e455020c0 | | sacpl.exe
pool: 0xffffa80e45554000 | eprocess: 0xffffa80e45554080 | \Program Files\CONEXANT\SA3\Dell-Notebook\SmartAudio3.exe | SmartAudio3.ex
pool: 0xffffa80e455d9040 | eprocess: 0xffffa80e455d90c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e455eb000 | eprocess: 0xffffa80e455eb080 | \Program Files\WindowsApps\FACEBOOK.317180B0BB486_520.3.60.0_x64__8xx8rvfyw5nnt\app\Messenger.exe | Messenger.exe
pool: 0xffffa80e45690020 | eprocess: 0xffffa80e45690080 | \Program Files\Intel\Intel(R) Online Connect\ioc.exe | ioc.exe
pool: 0xffffa80e45859000 | eprocess: 0xffffa80e45859080 | \Program Files\Dolby\Dolby DAX2\DAX2_API\DolbyDAX2API.exe | DolbyDAX2API.e
pool: 0xffffa80e45ae3000 | eprocess: 0xffffa80e45ae3080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e45b22000 | eprocess: 0xffffa80e45b22080 | | vmmem
pool: 0xffffa80e45b35040 | eprocess: 0xffffa80e45b350c0 | \ProgramData\Docker\cli-plugins\docker-mutagen.exe | docker-mutagen
pool: 0xffffa80e45b46040 | eprocess: 0xffffa80e45b460c0 | \Program Files\Docker\Docker\resources\com.docker.backend.exe | com.docker.bac
pool: 0xffffa80e45b79040 | eprocess: 0xffffa80e45b790c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e45b88090 | eprocess: 0xffffa80e45b88100 | | nvapiw.exe
pool: 0xffffa80e45dcc000 | eprocess: 0xffffa80e45dcc080 | \Windows\System32\SgrmBroker.exe | SgrmBroker.exe
pool: 0xffffa80e45dd7000 | eprocess: 0xffffa80e45dd7080 | \Program Files\Dell\SupportAssistAgent\bin\SupportAssistAgent.exe | SupportAssistA
pool: 0xffffa80e47872000 | eprocess: 0xffffa80e47872080 | \Program Files\WindowsApps\AcrobatNotificationClient_1.0.4.0_x86__e1rzdqpraam7r\AcrobatNotificationClient.exe | AcrobatNotific
pool: 0xffffa80e479c5040 | eprocess: 0xffffa80e479c50c0 | \Program Files\Dell\DellDataVault\nvapiw.exe | nvapiw.exe
pool: 0xffffa80e479c6000 | eprocess: 0xffffa80e479c6080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e47b090f0 | eprocess: 0xffffa80e47b09180 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e47b100f0 | eprocess: 0xffffa80e47b10180 | \Windows\System32\lxss\wslhost.exe | wslhost.exe
pool: 0xffffa80e47b3a0f0 | eprocess: 0xffffa80e47b3a180 | \Windows\System32\wsl.exe | wsl.exe
pool: 0xffffa80e47df0000 | eprocess: 0xffffa80e47df0080 | \Program Files\Docker\Docker\resources\vpnkit-bridge.exe | vpnkit-bridge.
pool: 0xffffa80e47ea0000 | eprocess: 0xffffa80e47ea0080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e47ead000 | eprocess: 0xffffa80e47ead080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e47ec2000 | eprocess: 0xffffa80e47ec2080 | \Windows\System32\wsl.exe | wsl.exe
pool: 0xffffa80e47ec5000 | eprocess: 0xffffa80e47ec5080 | \Windows\System32\lxss\wslhost.exe | wslhost.exe
pool: 0xffffa80e47ee8000 | eprocess: 0xffffa80e47ee8080 | \Windows\System32\lxss\wslhost.exe | wslhost.exe
pool: 0xffffa80e47ee9000 | eprocess: 0xffffa80e47ee9080 | \Program Files\Docker\Docker\resources\vpnkit.exe | vpnkit.exe
pool: 0xffffa80e47eeb040 | eprocess: 0xffffa80e47eeb0c0 | \Windows\System32\wsl.exe | wsl.exe
pool: 0xffffa80e47f18000 | eprocess: 0xffffa80e47f18080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e47f19000 | eprocess: 0xffffa80e47f19080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e47f42000 | eprocess: 0xffffa80e47f42080 | \Program Files\Docker\Docker\resources\com.docker.proxy.exe | com.docker.pro
pool: 0xffffa80e47fa9000 | eprocess: 0xffffa80e47fa9080 | \Windows\System32\lxss\wslhost.exe | wslhost.exe
pool: 0xffffa80e47fd8000 | eprocess: 0xffffa80e47fd8080 | \Windows\System32\lxss\wslhost.exe | wslhost.exe
pool: 0xffffa80e47fda000 | eprocess: 0xffffa80e47fda080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e48002040 | eprocess: 0xffffa80e480020c0 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e4800b000 | eprocess: 0xffffa80e4800b080 | \Program Files\Rivet Networks\SmartByte\SmartByteTelemetry.exe | SmartByteTelem
pool: 0xffffa80e48024040 | eprocess: 0xffffa80e480240c0 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e48029000 | eprocess: 0xffffa80e48029080 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffffa80e48077040 | eprocess: 0xffffa80e480770c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e48102040 | eprocess: 0xffffa80e481020c0 | \Windows\System32\wsl.exe | wsl.exe
pool: 0xffffa80e48171040 | eprocess: 0xffffa80e481710c0 | \Program Files\Docker\Docker\resources\com.docker.wsl-distro-proxy.exe | com.docker.wsl
pool: 0xffffa80e48189000 | eprocess: 0xffffa80e48189080 | \Windows\System32\dllhost.exe | dllhost.exe
pool: 0xffffa80e4846c1d0 | eprocess: 0xffffa80e4846c240 | | HxTsr.exe
pool: 0xffffa80e48470000 | eprocess: 0xffffa80e48470080 | \Program Files\WindowsApps\AdobeNotificationClient_1.0.1.22_x86__enpm4xejd91yc\AdobeNotificationClient.exe | AdobeNotificat
pool: 0xffffa80e48480040 | eprocess: 0xffffa80e484800c0 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e4854d040 | eprocess: 0xffffa80e4854d0c0 | \Windows\System32\MicrosoftEdgeSH.exe | MicrosoftEdgeS
pool: 0xffffa80e485541d0 | eprocess: 0xffffa80e48554240 | \Windows\System32\rundll32.exe | rundll32.exe
pool: 0xffffa80e4858a040 | eprocess: 0xffffa80e4858a0c0 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffffa80e485c0040 | eprocess: 0xffffa80e485c00c0 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffffa80e4879c040 | eprocess: 0xffffa80e4879c0c0 | | AcroRd32.exe
pool: 0xffffa80e499c5040 | eprocess: 0xffffa80e499c50c0 | \Windows\System32\browser_broker.exe | browser_broker
pool: 0xffffa80e4a2d6040 | eprocess: 0xffffa80e4a2d60c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e4a2f0050 | eprocess: 0xffffa80e4a2f00c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4a85a0c0 | eprocess: 0xffffa80e4a85a140 | \Windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe | MicrosoftEdge.
pool: 0xffffa80e4a8a5000 | eprocess: 0xffffa80e4a8a5080 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffffa80e4ac35040 | eprocess: 0xffffa80e4ac350c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4ac6c000 | eprocess: 0xffffa80e4ac6c080 | | chrome.exe
pool: 0xffffa80e4acdc040 | eprocess: 0xffffa80e4acdc0c0 | \Program Files\WindowsApps\FACEBOOK.317180B0BB486_520.3.60.0_x64__8xx8rvfyw5nnt\app\Messenger.exe | Messenger.exe
pool: 0xffffa80e4b03d050 | eprocess: 0xffffa80e4b03d0c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4b335040 | eprocess: 0xffffa80e4b3350c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4b4840c0 | eprocess: 0xffffa80e4b484140 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4b8d5040 | eprocess: 0xffffa80e4b8d50c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4ba1b040 | eprocess: 0xffffa80e4ba1b0c0 | | VirtualBoxVM.e
pool: 0xffffa80e4bbdb040 | eprocess: 0xffffa80e4bbdb0c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bbec040 | eprocess: 0xffffa80e4bbec0c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bc24040 | eprocess: 0xffffa80e4bc240c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bc46040 | eprocess: 0xffffa80e4bc460c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bc68040 | eprocess: 0xffffa80e4bc680c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bc8a040 | eprocess: 0xffffa80e4bc8a0c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bcce040 | eprocess: 0xffffa80e4bcce0c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bcdf040 | eprocess: 0xffffa80e4bcdf0c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bd02040 | eprocess: 0xffffa80e4bd020c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bd24040 | eprocess: 0xffffa80e4bd240c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bd67040 | eprocess: 0xffffa80e4bd670c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bd9a040 | eprocess: 0xffffa80e4bd9a0c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bdcd040 | eprocess: 0xffffa80e4bdcd0c0 | \My Programs\fvim-win-x64\FVim.exe | FVim.exe
pool: 0xffffa80e4be02040 | eprocess: 0xffffa80e4be020c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4be03000 | eprocess: 0xffffa80e4be03080 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bedd000 | eprocess: 0xffffa80e4bedd080 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4bf961d0 | eprocess: 0xffffa80e4bf96240 | \tools\neovim\Neovim\bin\nvim.exe | nvim.exe
pool: 0xffffa80e4c024040 | eprocess: 0xffffa80e4c0240c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4c04f000 | eprocess: 0xffffa80e4c04f080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e4c387020 | eprocess: 0xffffa80e4c387080 | \Windows\System32\dllhost.exe | dllhost.exe
pool: 0xffffa80e4c74c090 | eprocess: 0xffffa80e4c74c100 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffffa80e4c7b9040 | eprocess: 0xffffa80e4c7b90c0 | \Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe | windbg.exe
pool: 0xffffa80e4cec0040 | eprocess: 0xffffa80e4cec00c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4d5f2000 | eprocess: 0xffffa80e4d5f2080 | | chrome.exe
pool: 0xffffa80e4d6061d0 | eprocess: 0xffffa80e4d606240 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e4d985040 | eprocess: 0xffffa80e4d9850c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4da281c0 | eprocess: 0xffffa80e4da28240 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e4dc3a000 | eprocess: 0xffffa80e4dc3a080 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4dc79040 | eprocess: 0xffffa80e4dc790c0 | \Windows\explorer.exe | explorer.exe
pool: 0xffffa80e4df44000 | eprocess: 0xffffa80e4df44080 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4dfc41c0 | eprocess: 0xffffa80e4dfc4240 | \Users\nganhkhoa\AppData\Local\nvim\plugged\LanguageClient-neovim\bin\languageclient.exe | languageclient
pool: 0xffffa80e4e00b000 | eprocess: 0xffffa80e4e00b080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e4e026000 | eprocess: 0xffffa80e4e026080 | \Users\nganhkhoa\Desktop\findDbgBlock\parsePDBforOffsets\target\debug\eprocess_scan.exe | eprocess_scan.
pool: 0xffffa80e4e08f000 | eprocess: 0xffffa80e4e08f080 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4e131000 | eprocess: 0xffffa80e4e131080 | \Program Files\WindowsApps\FACEBOOK.317180B0BB486_520.3.60.0_x64__8xx8rvfyw5nnt\app\Messenger.exe | Messenger.exe
pool: 0xffffa80e4e16f0a0 | eprocess: 0xffffa80e4e16f100 | \Windows\System32\SearchProtocolHost.exe | SearchProtocol
pool: 0xffffa80e4e4ac040 | eprocess: 0xffffa80e4e4ac0c0 | \Program Files\WindowsApps\Microsoft.YourPhone_1.20051.90.0_x64__8wekyb3d8bbwe\YourPhone.exe | YourPhone.exe
pool: 0xffffa80e4e779040 | eprocess: 0xffffa80e4e7790c0 | \Windows\System32\cmd.exe | cmd.exe
pool: 0xffffa80e4e9b2040 | eprocess: 0xffffa80e4e9b20c0 | \Program Files\WindowsApps\FACEBOOK.317180B0BB486_520.3.60.0_x64__8xx8rvfyw5nnt\app\Messenger.exe | Messenger.exe
pool: 0xffffa80e4e9e5040 | eprocess: 0xffffa80e4e9e50c0 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffffa80e4ea05000 | eprocess: 0xffffa80e4ea05080 | \Windows\System32\cmd.exe | cmd.exe
pool: 0xffffa80e4ea9b040 | eprocess: 0xffffa80e4ea9b0c0 | | nvapiw.exe
pool: 0xffffa80e4ee02040 | eprocess: 0xffffa80e4ee020c0 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffffa80e4ee3f1d0 | eprocess: 0xffffa80e4ee3f240 | \Program Files\WindowsApps\Microsoft.Windows.Photos_2020.20050.19001.0_x64__8wekyb3d8bbwe\Microsoft.Photos.exe | Microsoft.Phot
pool: 0xffffa80e4efb5040 | eprocess: 0xffffa80e4efb50c0 | \Windows\System32\SearchProtocolHost.exe | SearchProtocol
pool: 0xffffa80e4f3ea040 | eprocess: 0xffffa80e4f3ea0c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4f3ee1d0 | eprocess: 0xffffa80e4f3ee240 | \tools\neovim\Neovim\bin\winpty-agent.exe | winpty-agent.e
pool: 0xffffa80e4f4e1040 | eprocess: 0xffffa80e4f4e10c0 | \Program Files\Notepad++\notepad++.exe | notepad++.exe
pool: 0xffffa80e4f55e040 | eprocess: 0xffffa80e4f55e0c0 | \Program Files (x86)\Google\Chrome\Application\chrome.exe | chrome.exe
pool: 0xffffa80e4f5610c0 | eprocess: 0xffffa80e4f561140 | \Windows\System32\SearchFilterHost.exe | SearchFilterHo
pool: 0xffffa80e4f5621d0 | eprocess: 0xffffa80e4f562240 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
NtUnloadDriver() -> 0x0

File diff suppressed because it is too large Load Diff

80
nonpaged-pool-range.md Normal file
View File

@ -0,0 +1,80 @@
> If you came here for `MmNonPagedPoolStart`, `MmNonPagedPoolEnd`, you ended up at the right place.
`NonPagedPool` in Windows has two variables that defined the start and end of the section in kernel memory. Online blog posts and tutorials show an outdated version of these two variables.
Take a look at [this old post](https://web.archive.org/web/20061110120809/http://www.rootkit.com/newsread.php?newsid=153). `_DBGKD_GET_VERSION64 KdVersionBlock` was a very important structure into the debugger block of Windows. However, if you try to find this structure in Windows 10, you will hit `KdVersionBlock == 0` (Ouch!!!). But this structure provides offset into `MmNonPagedPool{Start,End}`, how can we get those?
Luckily, both `MmNonPagedPoolStart` and `MmNonPagedPoolEnd` in Windows XP, can be found by offseting from `ntoskrnl.exe`. Rekall team are very positive that their tools doesn't rely on profiles file like Volatility but use PDB provided by Windows to find these values.
In [Rekall source code](https://github.com/google/rekall/blob/c5d68e31705f4b5bd2581c1d951b7f6983f7089c/rekall-core/rekall/plugins/windows/pool.py#L87), the values of those variables are:
- Windows XP: `MmNonPagedPool{Start,End}`
- Windows 7 and maybe 8: `MiNonPagedPoolStartAligned`, `MiNonPagedPoolEnd`, and `MiNonPagedPoolBitMap`
In Windows 7, 8, another field was added to controll the allocation of `NonPagedPool`, which is also mentioned in [this paper about pool tag quick scanning](https://www.sciencedirect.com/science/article/pii/S1742287616000062).
However, from Windows 10, the whole game changed around when the global offset to those (similar) variables are gone. Instead Windows 10 introduced a new variable `MiState`. `MiState` offset is available and we can get those start/end variables by either:
- Windows 2015: `(_MI_SYSTEM_INFORMATION*)(MiState)->SystemNodeInformation.NonPagedPool{First,Last}Va`
- Windows 2016: `(_MI_SYSTEM_INFORMATION*)(MiState)->Hardware.SystemNodeInformation.NonPagedPool{First,Last}Va`
The `NonPagedBitMap` was still visible untill the May 2019 Update, here, take a look at these 2 consecutive update [`1809 Redstone 5 (October Update)`](https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/1809%20Redstone%205%20(October%20Update)/\_MI\_SYSTEM\_NODE\_INFORMATION) and [`1903 19H1 (May 2019 Update)`](https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/1903%2019H1%20(May%202019%20Update)/\_MI\_SYSTEM\_NODE\_INFORMATION).
Windows OS changes quite frequently right? Tell you more, I am using the Insider version of Windows in 2020, and guess what, I found out that they put another struct to point to those value. So now we need to go like this:
- Windows 2020 Insider preview: `*(_MI_SYSTEM_INFORMATION*)(MiState)->Hardware.SystemNodeNonPagedPool.NonPagedPool{First,Last}Va`
> If you go with low-level, then you only care about the offset and formula to get those variables but knowing the structure is well benefit.
Anyway, I create this project to help me with my thesis, following outdated structs online yields no result. Oh, yeah, a guy seems to be asking on [how to get `MmNonPagedPoolStart`](https://reverseengineering.stackexchange.com/q/6483) on `stackexchange`, too bad [the answer](https://reverseengineering.stackexchange.com/a/6487) is not so much helpful.
----
Global variables offset are parsed from the PDB file and can be queried by `nt!` in Windbg. In a kernel driver, we need to get the kernel base address (which is `nt!`). Kernel base address is the loaded address of `ntoskrnl.exe`. There is a shellcode to get the address [here](https://gist.github.com/Barakat/34e9924217ed81fd78c9c92d746ec9c6), using IDT table. But when I use the shellcode with the Windows Insider preview 2020, the address is wrong (it still a loaded PE though). Other ways to get the address are listed [here](https://m0uk4.gitbook.io/notebooks/mouka/windowsinternal/find-kernel-module-address-todo). And hereby I present another way to get the kernel base address.
A device driver can get a pointer to an `_EPROCESS` through the use of `PEPROCESS IoGetCurrentProcess`. And as we know, `_EPROCESS` has pointer to other `_EPROCESS` as a circular doubly linked list. If we dump them all out, we can notice a few things:
- The image name returned by calling `IoGetCurrentProcess` in `DriverEntry` is `System`
- The `_EPROCESS` before `System` is somehow empty
```cpp
// in DriverEntry
PVOID eprocess = (PVOID)IoGetCurrentProcess();
// somewhere after offsets are setup
DbgPrint("eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + ImageBaseNameOffset));
for (int i = 0; i < 100; i++) {
eprocess = (PVOID)(*(ULONG64*)((ULONG64)eprocess + ActiveProcessLinksOffset) - ActiveProcessLinksOffset);
DbgPrint("eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + ImageBaseOffset));
}
// sample output
eprocess : 0xFFFFF8037401F528, [ ]
eprocess : 0xFFFF840F5A0D9080, [ System]
eprocess : 0xFFFF840F5A28C040, [ Secure System]
eprocess : 0xFFFF840F5A2EF040, [ Registry]
eprocess : 0xFFFF840F622BF040, [ smss.exe]
eprocess : 0xFFFF840F6187D080, [ smss.exe]
eprocess : 0xFFFF840F6263D140, [ csrss.exe]
eprocess : 0xFFFF840F6277F0C0, [ smss.exe]
eprocess : 0xFFFF840F627C2080, [ wininit.exe]
eprocess : 0xFFFF840F64187140, [ csrss.exe]
eprocess : 0xFFFF840F641CD080, [ services.exe]
```
And if we debug and compare the address of that `Empty _EPROCESS+ActiveProcessLinksOffset` with `nt!PsActiveProcessHead`, it is just the same. And with the given offset parsed from the PDB file, we can get kernel base address.
```cpp
// In DriverEntry
PVOID eprocess = (PVOID)IoGetCurrentProcess();
// somwhere after offsets are setup
DbgPrint("eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + ImageBaseNameOffset));
PVOID processHead = (PVOID)(*(ULONG64*)((ULONG64)eprocess + ActiveProcessLinksOffset + BLinkOffset));
DbgPrint("PsActiveProcessHead : 0x%p\n", processHead);
PVOID ntosbase = (PVOID)((ULONG64)processHead - ActiveHeadOffset);
DbgPrint("ntoskrnl.exe : 0x%p\n", ntosbase);
```
From now we have successfully get the kernel base address to index into other global variables.

View File

@ -0,0 +1,20 @@
import sys
import re
s = list(filter(lambda x: "unicode" in x, open(sys.argv[1], 'r').read().split('\n')))
m = re.compile(r"unicode str: (0x[0-9a-f]+) size: (0x[0-9a-f]+) capacity: (0x[0-9a-f]+)")
ss = list(filter(lambda x: int(x[0], 16) != 0 and int(x[1], 16) <= int(x[2], 16) and int(x[1], 16) != 0 and int(x[1], 16) % 2 == 0,
map(lambda x: m.match(x).group(1,2,3), s)))
aa = set()
bb = set()
for (a, s, c) in ss:
if a in aa or a in bb:
continue
aa.add(a)
# print("du", a, "|", s, c)
print("du", a)

91
src/bin/eprocess_scan.rs Normal file
View File

@ -0,0 +1,91 @@
use std::error::Error;
use std::str::{from_utf8};
use chrono::Utc;
use chrono::{DateTime};
use std::time::{UNIX_EPOCH, Duration};
use lpus::{
driver_state::{DriverState /* , EprocessPoolChunk */}
};
#[allow(dead_code)]
fn to_str_time(time_ms: u64) -> String {
if time_ms == 0 {
return "".to_string();
}
let d = UNIX_EPOCH + Duration::from_millis(time_ms);
let datetime = DateTime::<Utc>::from(d);
let timestamp_str = datetime.format("%Y-%m-%d %H:%M:%S.%f").to_string();
timestamp_str
}
fn main() -> Result<(), Box<dyn Error>> {
// for windows admin require
// https://github.com/nabijaczleweli/rust-embed-resource
let mut driver = DriverState::new();
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
// let eprocess_scan_head = driver.scan_active_head(ntosbase)?;
// let mut eprocess_list: Vec<EprocessPoolChunk> = Vec::new();
driver.scan_pool(b"Proc", |pool_addr, header, data_addr| {
let chunk_size = (header[2] as u64) * 16u64;
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 fob_filename_offset = driver.pdb_store.get_offset_r("_FILE_OBJECT.FileName")?;
let eprocess_image_file_ptr_offset = driver.pdb_store.get_offset_r("_EPROCESS.ImageFilePointer")?;
// 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;
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);
// using heuristics to eliminate false positive
if driver.windows_ffi.valid_process_time(create_time) {
break;
}
try_eprocess_ptr += 0x4; // search exhaustively
}
if try_eprocess_ptr > eprocess_valid_end {
return Ok(false);
}
let mut image_name = [0u8; 15];
let mut file_object_ptr = 0u64;
driver.deref_addr(try_eprocess_ptr + eprocess_name_offset, &mut image_name);
driver.deref_addr(try_eprocess_ptr + eprocess_image_file_ptr_offset, &mut file_object_ptr);
let filename = if file_object_ptr != 0 { driver.get_unicode_string(file_object_ptr + fob_filename_offset, true)? }
else { "".to_string() };
if let Ok(name) = from_utf8(&image_name) {
let eprocess_name = name
.to_string()
.trim_end_matches(char::from(0))
.to_string();
println!("pool: 0x{:x} | eprocess: 0x{:x} | {} | {}", pool_addr, try_eprocess_ptr, filename, eprocess_name);
}
else {
println!("pool: 0x{:x} | eprocess: 0x{:x} | {} | {:?}", pool_addr, try_eprocess_ptr, filename, image_name);
}
Ok(true)
// eprocess_list.push(EprocessPoolChunk {
// pool_addr,
// eprocess_addr: try_eprocess_ptr,
// eprocess_name: eprocess_name,
// create_time: to_epoch(create_time),
// exit_time: to_epoch(exit_time)
// });
})?;
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

View File

@ -0,0 +1,57 @@
use std::error::Error;
use lpus::{
driver_state::{DriverState}
};
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
driver.scan_pool(b"File", |pool_addr, header, data_addr| {
let chunk_size = (header[2] as u64) * 16u64;
let fob_size = driver.pdb_store.get_offset_r("_FILE_OBJECT.struct_size")?;
let fob_size_offset = driver.pdb_store.get_offset_r("_FILE_OBJECT.Size")?;
let fob_read_access_offset = driver.pdb_store.get_offset_r("_FILE_OBJECT.ReadAccess")?;
let fob_filename_offset = driver.pdb_store.get_offset_r("_FILE_OBJECT.FileName")?;
let valid_end = (pool_addr + chunk_size) - fob_size;
let mut try_ptr = data_addr;
let mut ftype = 0u16;
let mut size = 0u16;
while try_ptr <= valid_end {
driver.deref_addr(try_ptr, &mut ftype);
driver.deref_addr(try_ptr + fob_size_offset, &mut size);
if (size as u64) == fob_size && ftype == 5u16 {
break;
}
try_ptr += 0x4; // search exhaustively
}
if try_ptr > valid_end {
println!("pool: 0x{:x} cannot detect file object", pool_addr);
return Ok(false);
}
let fob_addr = try_ptr;
let mut read_ok = 0u8;
driver.deref_addr(fob_addr + fob_read_access_offset, &mut read_ok);
println!("pool: 0x{:x} | file object: 0x{:x} | offsetby: 0x{:x}", pool_addr, fob_addr, fob_addr - pool_addr);
if read_ok == 0 {
println!(" [NOT READABLE]");
}
else if let Ok(filename) = driver.get_unicode_string(fob_addr + fob_filename_offset, true) {
println!(" {}", filename);
}
else {
println!(" [NOT A VALID _UNICODE_STRING]");
}
Ok(true)
})?;
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

12
src/bin/print_pdb.rs Normal file
View File

@ -0,0 +1,12 @@
use std::error::Error;
use lpus::{
driver_state::{DriverState}
};
fn main() -> Result<(), Box<dyn Error>> {
let driver = DriverState::new();
driver.windows_ffi.print_version();
driver.pdb_store.print_default_information();
Ok(())
}

320
src/driver_state.rs Normal file
View File

@ -0,0 +1,320 @@
use std::error::Error;
// use std::io::{Error, ErrorKind};
use std::ffi::c_void;
use std::mem::{size_of_val};
use winapi::shared::ntdef::{NTSTATUS};
use winapi::shared::minwindef::{DWORD};
use winapi::um::winioctl::{
CTL_CODE, FILE_ANY_ACCESS,
METHOD_IN_DIRECT, METHOD_OUT_DIRECT, /* METHOD_BUFFERED, */ METHOD_NEITHER
};
use crate::pdb_store::{PdbStore, parse_pdb};
use crate::windows::{WindowsFFI, WindowsVersion};
use crate::ioctl_protocol::{
InputData, OffsetData, DerefAddr, ScanPoolData, /* HideProcess, */
/* OutputData, */ Nothing
};
type BoxResult<T> = Result<T, Box<dyn Error>>;
const SIOCTL_TYPE: DWORD = 40000;
pub fn to_epoch(filetime: u64) -> u64 {
let windows_epoch_diff: u64 = 11644473600000 * 10000;
if filetime < windows_epoch_diff {
return 0;
}
let process_time_epoch: u64 = (filetime - windows_epoch_diff) / 10000;
process_time_epoch
}
#[allow(dead_code)]
#[derive(Debug)]
pub enum DriverAction {
SetupOffset,
GetKernelBase,
ScanPsActiveHead,
ScanPool,
ScanPoolRemote,
DereferenceAddress,
HideProcess
}
impl DriverAction {
pub fn get_code(&self) -> DWORD {
match self {
DriverAction::SetupOffset => CTL_CODE(SIOCTL_TYPE, 0x900, METHOD_IN_DIRECT, FILE_ANY_ACCESS),
DriverAction::GetKernelBase => CTL_CODE(SIOCTL_TYPE, 0x901, METHOD_OUT_DIRECT, FILE_ANY_ACCESS),
DriverAction::ScanPsActiveHead => CTL_CODE(SIOCTL_TYPE, 0x902, METHOD_NEITHER, FILE_ANY_ACCESS),
DriverAction::ScanPool => CTL_CODE(SIOCTL_TYPE, 0x903, METHOD_IN_DIRECT, FILE_ANY_ACCESS),
DriverAction::ScanPoolRemote => CTL_CODE(SIOCTL_TYPE, 0x904, METHOD_IN_DIRECT, FILE_ANY_ACCESS),
DriverAction::DereferenceAddress => CTL_CODE(SIOCTL_TYPE, 0xA00, METHOD_OUT_DIRECT, FILE_ANY_ACCESS),
DriverAction::HideProcess => CTL_CODE(SIOCTL_TYPE, 0xA01, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
}
}
}
#[derive(Debug)]
pub struct EprocessPoolChunk {
pub pool_addr: u64,
pub eprocess_addr: u64,
pub eprocess_name: String,
pub create_time: u64,
pub exit_time: u64
}
impl PartialEq for EprocessPoolChunk {
fn eq(&self, other: &Self) -> bool {
self.eprocess_addr == other.eprocess_addr
}
}
#[allow(dead_code)]
pub struct DriverState {
// TODO: Make private, only call methods of DriverState
pub pdb_store: PdbStore,
pub windows_ffi: WindowsFFI,
}
impl DriverState {
pub fn new() -> Self {
Self {
pdb_store: parse_pdb().expect("Cannot get PDB file"),
windows_ffi: WindowsFFI::new()
}
}
pub fn startup(&mut self) -> NTSTATUS {
let s = self.windows_ffi.load_driver();
let mut input = InputData {
offset_value: OffsetData::new(&self.pdb_store, self.windows_ffi.short_version)
};
self.windows_ffi.device_io(DriverAction::SetupOffset.get_code(),
&mut input, &mut Nothing);
s
}
pub fn shutdown(&self) -> NTSTATUS {
self.windows_ffi.unload_driver()
}
pub fn get_kernel_base(&self) -> u64 {
let mut ntosbase = 0u64;
self.windows_ffi.device_io(DriverAction::GetKernelBase.get_code(),
&mut Nothing, &mut ntosbase);
// println!("ntosbase: 0x{:x}", self.ntosbase);
ntosbase
}
pub fn scan_active_head(&self) -> BoxResult<Vec<EprocessPoolChunk>> {
let ntosbase = self.get_kernel_base();
let ps_active_head = ntosbase + self.pdb_store.get_offset_r("PsActiveProcessHead")?;
let flink_offset = self.pdb_store.get_offset_r("_LIST_ENTRY.Flink")?;
let eprocess_link_offset = self.pdb_store.get_offset_r("_EPROCESS.ActiveProcessLinks")?;
let eprocess_name_offset = self.pdb_store.get_offset_r("_EPROCESS.ImageFileName")?;
let mut ptr = ps_active_head;
self.deref_addr(ptr + flink_offset, &mut ptr);
let mut result: Vec<EprocessPoolChunk> = Vec::new();
while ptr != ps_active_head {
let mut image_name = [0u8; 15];
let eprocess = ptr - eprocess_link_offset;
self.deref_addr(eprocess + eprocess_name_offset, &mut image_name);
match std::str::from_utf8(&image_name) {
Ok(n) => {
result.push(EprocessPoolChunk {
pool_addr: 0,
eprocess_addr: eprocess,
eprocess_name: n.to_string()
.trim_end_matches(char::from(0))
.to_string(),
create_time: 0,
exit_time: 0
});
},
_ => {}
};
self.deref_addr(ptr + flink_offset, &mut ptr);
}
Ok(result)
}
pub fn scan_pool<F>(&self, tag: &[u8; 4], mut handler: F) -> BoxResult<bool>
where F: FnMut(u64, &[u8], u64) -> BoxResult<bool>
// F(Pool Address, Pool Header Data, Pool Data Address)
// TODO: Pool Header as a real struct
{
let ntosbase = self.get_kernel_base();
let pool_header_size = self.pdb_store.get_offset_r("_POOL_HEADER.struct_size")?;
let minimum_block_size = self.get_minimum_block_size(tag)?;
let code = DriverAction::ScanPoolRemote.get_code();
let range = self.get_nonpaged_range(ntosbase)?;
let start_address = range[0];
let end_address = range[1];
let mut ptr = start_address;
while ptr < end_address {
let mut input = InputData {
scan_range: ScanPoolData::new(&[ptr, end_address], tag)
};
self.windows_ffi.device_io(code, &mut input, &mut ptr);
// println!("found: 0x{:x}", ptr);
if ptr >= end_address {
break;
}
let pool_addr = ptr;
let mut header = vec![0u8; pool_header_size as usize];
self.deref_addr_ptr(pool_addr, header.as_mut_ptr(), pool_header_size);
let chunk_size = (header[2] as u64) * 16u64;
if pool_addr + chunk_size > end_address {
// the chunk found is not a valid chunk for sure
break;
}
// automatically reject bad chunk
if chunk_size < minimum_block_size {
ptr += 0x4;
continue;
}
let success = handler(pool_addr, &header, pool_addr + pool_header_size)?;
if success {
ptr += chunk_size; /* pass this chunk */
// ptr += 0x4;
}
else {
ptr += 0x4; /* search next */
}
}
Ok(true)
}
fn get_minimum_block_size(&self, tag: &[u8; 4]) -> BoxResult<u64> {
// Proc -> _EPROCESS
// Thre -> _KTHREAD
let pool_header_size = self.pdb_store.get_offset_r("_POOL_HEADER.struct_size")?;
if tag == b"Proc" {
let eprocess_size = self.pdb_store.get_offset_r("_EPROCESS.struct_size")?;
let minimum_data_size = eprocess_size + pool_header_size;
Ok(minimum_data_size)
}
else if tag == b"File" {
let file_object_size = self.pdb_store.get_offset_r("_FILE_OBJECT.struct_size")?;
let minimum_data_size = file_object_size + pool_header_size;
Ok(minimum_data_size)
}
else {
Err("Tag unknown".into())
}
}
pub fn deref_addr<T>(&self, addr: u64, outbuf: &mut T) {
// println!("deref addr: 0x{:x}", addr);
let code = DriverAction::DereferenceAddress.get_code();
let size: usize = size_of_val(outbuf);
let mut input = InputData {
deref_addr: DerefAddr {
addr,
size: size as u64
}
};
// unsafe { println!("Dereference {} bytes at 0x{:x}", input.deref_addr.size, input.deref_addr.addr) };
self.windows_ffi.device_io(code, &mut input, outbuf);
}
pub fn deref_addr_ptr<T>(&self, addr: u64, outptr: *mut T, output_len: u64) {
let code = DriverAction::DereferenceAddress.get_code();
let mut input = InputData {
deref_addr: DerefAddr {
addr,
size: output_len
}
};
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);
}
pub fn get_unicode_string(&self, unicode_str_addr: u64, deref: bool) -> BoxResult<String> {
let mut strlen = 0u16;
let mut capacity = 0u16;
let mut bufaddr = 0u64;
let buffer_ptr = unicode_str_addr + self.pdb_store.get_offset_r("_UNICODE_STRING.Buffer")?;
let capacity_addr = unicode_str_addr + self.pdb_store.get_offset_r("_UNICODE_STRING.MaximumLength")?;
self.deref_addr(unicode_str_addr, &mut strlen);
self.deref_addr(capacity_addr, &mut capacity);
self.deref_addr(buffer_ptr, &mut bufaddr);
// println!("unicode str: 0x{:x} size: 0x{:x} capacity: 0x{:x}", bufaddr, strlen, capacity);
if bufaddr == 0 || strlen > capacity || strlen == 0 || strlen % 2 != 0 {
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);
Ok(String::from_utf16(&buf)?)
}
pub fn get_nonpaged_range(&self, ntosbase: u64) -> BoxResult<[u64; 2]> {
// TODO: Add support for other Windows version here
match self.windows_ffi.short_version {
WindowsVersion::Windows10FastRing => {
let mistate = ntosbase + self.pdb_store.get_offset_r("MiState")?;
let system_node_ptr = self.pdb_store.addr_decompose(
mistate, "_MI_SYSTEM_INFORMATION.Hardware.SystemNodeNonPagedPool")?;
let mut system_node_addr = 0u64;
self.deref_addr(system_node_ptr, &mut system_node_addr);
let mut first_va = 0u64;
let mut last_va = 0u64;
self.deref_addr(
system_node_addr
+ self.pdb_store.get_offset_r("_MI_SYSTEM_NODE_NONPAGED_POOL.NonPagedPoolFirstVa")?,
&mut first_va);
self.deref_addr(
system_node_addr
+ self.pdb_store.get_offset_r("_MI_SYSTEM_NODE_NONPAGED_POOL.NonPagedPoolLastVa")?,
&mut last_va);
Ok([first_va, last_va])
},
WindowsVersion::Windows10_2019 => {
let mistate = ntosbase + self.pdb_store.get_offset_r("MiState")?;
let system_node_ptr = self.pdb_store.addr_decompose(
mistate, "_MI_SYSTEM_INFORMATION.Hardware.SystemNodeInformation")?;
let mut system_node_addr = 0u64;
self.deref_addr(system_node_ptr, &mut system_node_addr);
let mut first_va = 0u64;
let mut last_va = 0u64;
self.deref_addr(
system_node_addr
+ self.pdb_store.get_offset_r("_MI_SYSTEM_NODE_INFORMATION.NonPagedPoolFirstVa")?,
&mut first_va);
self.deref_addr(
system_node_addr
+ self.pdb_store.get_offset_r("_MI_SYSTEM_NODE_INFORMATION.NonPagedPoolLastVa")?,
&mut last_va);
Ok([first_va, last_va])
},
_ => {
Err("Windows version for nonpaged pool algorithm is not implemented".into())
}
}
}
}

121
src/ioctl_protocol.rs Normal file
View File

@ -0,0 +1,121 @@
use crate::pdb_store::PdbStore;
use crate::windows::WindowsVersion;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct OffsetData {
eprocess_name_offset: u64,
eprocess_link_offset: u64,
list_blink_offset: u64,
process_head_offset: u64,
mistate_offset: u64,
hardware_offset: u64,
system_node_offset: u64,
first_va_offset: u64,
last_va_offset: u64,
large_page_table_offset: u64,
large_page_size_offset: u64,
pool_chunk_size: u64,
}
// TODO: Move to WindowsScanStrategy and return the corresponding struct base on Windows version
impl OffsetData {
pub fn new(pdb_store: &PdbStore, windows_version: WindowsVersion) -> Self {
match windows_version {
WindowsVersion::Windows10FastRing => Self {
eprocess_name_offset: pdb_store.get_offset("_EPROCESS.ImageFileName").unwrap_or(0u64),
eprocess_link_offset: pdb_store.get_offset("_EPROCESS.ActiveProcessLinks").unwrap_or(0u64),
list_blink_offset: pdb_store.get_offset("_LIST_ENTRY.Blink").unwrap_or(0u64),
process_head_offset: pdb_store.get_offset("PsActiveProcessHead").unwrap_or(0u64),
mistate_offset: pdb_store.get_offset("MiState").unwrap_or(0u64),
hardware_offset: pdb_store.get_offset("_MI_SYSTEM_INFORMATION.Hardware").unwrap_or(0u64),
system_node_offset: pdb_store.get_offset("_MI_HARDWARE_STATE.SystemNodeNonPagedPool").unwrap_or(0u64),
first_va_offset: pdb_store.get_offset("_MI_SYSTEM_NODE_NONPAGED_POOL.NonPagedPoolFirstVa").unwrap_or(0u64),
last_va_offset: pdb_store.get_offset("_MI_SYSTEM_NODE_NONPAGED_POOL.NonPagedPoolLastVa").unwrap_or(0u64),
large_page_table_offset: pdb_store.get_offset("PoolBigPageTable").unwrap_or(0u64),
large_page_size_offset: pdb_store.get_offset("PoolBigPageTableSize").unwrap_or(0u64),
pool_chunk_size: pdb_store.get_offset("_POOL_HEADER.struct_size").unwrap_or(0u64),
},
WindowsVersion::Windows10_2019 |
WindowsVersion::Windows10_2018 => Self {
eprocess_name_offset: pdb_store.get_offset("_EPROCESS.ImageFileName").unwrap_or(0u64),
eprocess_link_offset: pdb_store.get_offset("_EPROCESS.ActiveProcessLinks").unwrap_or(0u64),
list_blink_offset: pdb_store.get_offset("_LIST_ENTRY.Blink").unwrap_or(0u64),
process_head_offset: pdb_store.get_offset("PsActiveProcessHead").unwrap_or(0u64),
mistate_offset: pdb_store.get_offset("MiState").unwrap_or(0u64),
hardware_offset: pdb_store.get_offset("_MI_SYSTEM_INFORMATION.Hardware").unwrap_or(0u64),
system_node_offset: pdb_store.get_offset("_MI_HARDWARE_STATE.SystemNodeInformation").unwrap_or(0u64),
first_va_offset: pdb_store.get_offset("_MI_SYSTEM_NODE_INFORMATION.NonPagedPoolFirstVa").unwrap_or(0u64),
last_va_offset: pdb_store.get_offset("_MI_SYSTEM_NODE_INFORMATION.NonPagedPoolLastVa").unwrap_or(0u64),
large_page_table_offset: pdb_store.get_offset("PoolBigPageTable").unwrap_or(0u64),
large_page_size_offset: pdb_store.get_offset("PoolBigPageTableSize").unwrap_or(0u64),
pool_chunk_size: pdb_store.get_offset("_POOL_HEADER.struct_size").unwrap_or(0u64),
},
// TODO: Add other version of Windows here
// TODO: Warn user of unknown windows version, because BSOD will occur
_ => Self {
eprocess_name_offset: 0u64,
eprocess_link_offset: 0u64,
list_blink_offset: 0u64,
process_head_offset: 0u64,
mistate_offset: 0u64,
hardware_offset: 0u64,
system_node_offset: 0u64,
first_va_offset: 0u64,
last_va_offset: 0u64,
large_page_table_offset: 0u64,
large_page_size_offset: 0u64,
pool_chunk_size: 0u64,
}
}
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct DerefAddr {
pub addr: u64,
pub size: u64
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ScanPoolData {
pub start: u64,
pub end: u64,
pub tag: u32
}
impl ScanPoolData{
pub fn new(arr: &[u64; 2], tag: &[u8; 4]) -> Self {
Self {
start: arr[0],
end: arr[1],
tag: u32::from_le_bytes(*tag)
}
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct HideProcess {
pub name: [u8; 15],
pub size: u64
}
#[repr(C)]
pub union InputData {
pub offset_value: OffsetData,
pub deref_addr: DerefAddr,
pub scan_range: ScanPoolData,
pub hide_process: HideProcess,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Nothing; // for empty data
#[repr(C)]
pub union OutputData {
pub nothing: Nothing,
}

8
src/lib.rs Normal file
View File

@ -0,0 +1,8 @@
extern crate chrono;
extern crate app_dirs;
pub mod pdb_store;
pub mod windows;
pub mod ioctl_protocol;
pub mod driver_state;

View File

@ -1,183 +0,0 @@
extern crate reqwest;
use std::io;
use std::io::Read;
use std::fs::File;
use std::path::Path;
use std::collections::HashMap;
use pdb::PDB;
use pdb::SymbolData;
use pdb::TypeData;
use pdb::ClassType;
use pdb::FallibleIterator;
use pdb::TypeFinder;
use pdb::TypeIndex;
const PDBNAME: &str = "ntkrnlmp.pdb";
const NTOSKRNL_PATH: &str = "C:\\Windows\\System32\\ntoskrnl.exe";
const PDB_SERVER_PATH: &str = "http://msdl.microsoft.com/download/symbols";
fn get_type_as_str(type_finder: &TypeFinder, typ: &TypeIndex) -> String {
match type_finder.find(*typ).unwrap().parse().unwrap() {
TypeData::Class(ct) => {
format!("{}", ct.name.to_string())
},
TypeData::Primitive(pt) => {
format!("{:?}", pt.kind)
},
TypeData::Pointer(pt) => {
format!("{}*", get_type_as_str(type_finder, &pt.underlying_type))
},
unk => {
match unk.name() {
Some(s) => format!("{}", s.to_string()),
_ => "UNNOWN".to_string()
}
}
}
}
fn parse_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 info = pdb.pdb_information().expect("Cannot get pdb information");
let dbi = pdb.debug_information().expect("cannot get debug information");
println!("PDB for {}, guid: {}, age: {},", dbi.machine_type().unwrap(), info.guid, dbi.age().unwrap_or(0));
println!("");
// find global symbols offset
let addr_map = pdb.address_map().expect("Cannot get address map");
let glosym = pdb.global_symbols().expect("Cannot get global symbols");
let mut symbols = glosym.iter();
let need_symbols = [
"KdDebuggerDataBlock", "MmNonPagedPoolStart", "MmNonPagedPoolEnd", // Windows XP
"MiNonPagedPoolStartAligned", "MiNonPagedPoolEnd", "MiNonPagedPoolBitMap", // Windows 7, 8
"MiState" // Windows 10
];
while let Some(symbol) = symbols.next().unwrap() {
match symbol.parse() {
Ok(SymbolData::PublicSymbol(data)) => {
let name = symbol.name().unwrap().to_string();
for sym in need_symbols.iter() {
if &name == sym {
let rva = data.offset.to_rva(&addr_map).unwrap_or_default();
println!("{} {} {}:{}", name, rva, data.offset.section, data.offset.offset);
}
}
},
_ => {
// println!("Something else");
}
}
}
println!("");
let mut need_structs = HashMap::new();
need_structs.insert("_KDDEBUGGER_DATA64", vec![
"MmNonPagedPoolStart", "MmNonPagedPoolEnd", // Windows XP
"MiNonPagedPoolStartAligned", "MiNonPagedPoolEnd", "MiNonPagedPoolBitMap", // Windows 7, 8 -- not sure, global symbols
"MiState" // Windows 10 -- not sure, global symbols
]);
// these struct supports finding NonPagedPool{First,Last}Va in windows 10
need_structs.insert("_MI_SYSTEM_INFORMATION", vec![
"Hardware", // windows 10 2016+
"SystemNodeInformation" // windows 10 2015
]);
need_structs.insert("_MI_HARDWARE_STATE", vec![
"SystemNodeInformation", // till windows 10 1900
"SystemNodeNonPagedPool" // windows insider, 2020
]);
need_structs.insert("_MI_SYSTEM_NODE_INFORMATION", vec![ // till windows 10 1900
"NonPagedPoolFirstVa", "NonPagedPoolLastVa",
"NonPagedBitMap" // missing on windows 10 1900+
]);
need_structs.insert("_MI_SYSTEM_NODE_NONPAGED_POOL", vec![ // windows insider, 2020
"NonPagedPoolFirstVa", "NonPagedPoolLastVa"
]);
let type_information = pdb.type_information().expect("Cannot get type information");
let mut type_finder = type_information.type_finder();
let mut iter = type_information.iter();
while let Some(typ) = iter.next().unwrap() {
type_finder.update(&iter);
match typ.parse() {
Ok(TypeData::Class(ClassType {name, fields: Some(fields), ..})) => {
let n = name.to_string();
// println!("{}", name);
if !need_structs.contains_key(&*n) {
continue;
}
println!("struct {}", name);
match type_finder.find(fields).unwrap().parse().unwrap() {
TypeData::FieldList(list) => {
// `fields` is a Vec<TypeData>
for field in list.fields {
if let TypeData::Member(member) = field {
let mem_typ = get_type_as_str(&type_finder, &member.field_type);
println!(" - field {} {} at offset {:x}", mem_typ, member.name, member.offset);
} else {
// handle member functions, nested types, etc.
}
}
}
_ => {}
}
println!("");
},
_ => {}
}
}
}
fn download_pdb() {
let mut ntoskrnl = File::open(NTOSKRNL_PATH).expect("Cannot open ntoskrnl.exe");
let mut buffer = Vec::new();
ntoskrnl.read_to_end(&mut buffer).expect("Cannot read file ntoskrnl.exe");
let mut buffiter = buffer.chunks(4);
while buffiter.next().unwrap() != [0x52, 0x53, 0x44, 0x53] {
// signature == RSDS
}
// next 16 bytes is guid in raw bytes
let raw_guid: Vec<u8> = vec![
buffiter.next().unwrap(),
buffiter.next().unwrap(),
buffiter.next().unwrap(),
buffiter.next().unwrap(),
].concat();
// guid to hex string
let guid = (vec![
raw_guid[3], raw_guid[2], raw_guid[1], raw_guid[0],
raw_guid[5], raw_guid[4],
raw_guid[7], raw_guid[6],
raw_guid[8], raw_guid[9], raw_guid[10], raw_guid[11],
raw_guid[12], raw_guid[13], raw_guid[14], raw_guid[15],
].iter().map(|b| format!("{:02X}", b)).collect::<Vec<String>>()).join("");
// next 4 bytes is age, in little endian
let raw_age = buffiter.next().unwrap();
let age = u32::from_le_bytes([
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");
}
fn main() {
if !Path::new(PDBNAME).exists() {
download_pdb();
}
parse_pdb();
}

394
src/pdb_store.rs Normal file
View File

@ -0,0 +1,394 @@
use std::error::Error;
use std::io;
use std::io::{Read};
use std::path::{PathBuf};
use std::fs::File;
use std::collections::HashMap;
use pdb::{
PDB, SymbolData, TypeData, ClassType, ModifierType, Rva,
FallibleIterator, TypeFinder, TypeIndex
};
use app_dirs::{AppInfo, AppDataType, app_dir};
const APP_INFO: AppInfo = AppInfo { name: "lpus", author: "nganhkhoa" };
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)>>;
pub struct PdbStore {
pub symbols: SymbolStore,
pub structs: StructStore
}
impl PdbStore {
pub fn get_offset_r(&self, name: &str) -> BoxResult<u64> {
self.get_offset(name)
.ok_or(format!("{} is not found in PDB", name).into())
}
#[allow(dead_code)]
pub fn get_offset(&self, name: &str) -> Option<u64> {
if name.contains(".") {
let v: Vec<&str> = name.split_terminator('.').collect();
match self.structs.get(v[0]) {
Some(member_info) => {
match member_info.get(v[1]) {
Some((_memtype, offset)) => Some(*offset),
None => None
}
},
None => None
}
}
else {
match self.symbols.get(name) {
Some(offset) => Some(*offset),
None => None
}
}
}
#[allow(dead_code)]
pub fn addr_decompose(&self, addr: u64, full_name: &str) -> BoxResult<u64>{
if !full_name.contains(".") {
return Err("Not decomposable".into());
}
let mut name_part: Vec<&str> = full_name.split_terminator('.').collect();
let mut next: Vec<_> = name_part.drain(2..).collect();
match self.structs.get(name_part[0]) {
Some(member_info) => {
match member_info.get(name_part[1]) {
Some((memtype, offset)) => {
if next.len() != 0 {
if memtype.contains("*") {
return Err(format!("Cannot dereference pointer at {} {}", memtype, name_part[1]).into());
}
next.insert(0, memtype);
self.addr_decompose(addr + *offset, &next.join("."))
}
else {
Ok(addr + *offset)
}
},
None => Err(format!("Not found member {}", name_part[1]).into())
}
},
None => Err(format!("Struct {} not found", name_part[0]).into())
}
}
#[allow(dead_code)]
pub fn print_default_information(&self) {
let need_symbols = [
"PsLoadedModuleList", "PsActiveProcessHead", "KeNumberNodes",
"PoolBigPageTable", "PoolBigPageTableSize",
// "PoolVector", "ExpNumberOfNonPagedPools",
"KdDebuggerDataBlock", "MmNonPagedPoolStart", "MmNonPagedPoolEnd", // Windows XP
"MiNonPagedPoolStartAligned", "MiNonPagedPoolEnd", "MiNonPagedPoolBitMap", // Windows 7, 8
"MiNonPagedPoolBitMap", "MiNonPagedPoolVaBitMap",
"MiState" // Windows 10
];
let mut need_structs = HashMap::new();
need_structs.insert("_POOL_HEADER", vec![
"struct_size",
"PoolType", "BlockSize", "PoolTag"
]);
need_structs.insert("_PEB", vec![]);
need_structs.insert("_LIST_ENTRY", vec![
"Flink", "Blink"
]);
need_structs.insert("_FILE_OBJECT", vec![
"FileName"
]);
need_structs.insert("_EPROCESS", vec![
"struct_size",
"UniqueProcessId", "ActiveProcessLinks", "CreateTime",
"Peb", "ImageFilePointer", "ImageFileName", "ThreadListHead"
]);
need_structs.insert("_KDDEBUGGER_DATA64", vec![
"MmNonPagedPoolStart", "MmNonPagedPoolEnd", // Windows XP
]);
need_structs.insert("_POOL_TRACKER_BIG_PAGES", vec![]);
// these struct supports finding NonPagedPool{First,Last}Va in windows 10
need_structs.insert("_MI_SYSTEM_INFORMATION", vec![
"Hardware", // windows 10 2016+
"SystemNodeInformation" // windows 10 2015
]);
need_structs.insert("_MI_HARDWARE_STATE", vec![
"SystemNodeInformation", // till windows 10 1900
"SystemNodeNonPagedPool" // windows insider, 2020
]);
need_structs.insert("_MI_SYSTEM_NODE_INFORMATION", vec![ // till windows 10 1900
"NonPagedPoolFirstVa", "NonPagedPoolLastVa",
"NonPagedBitMap", // missing on windows 10 1900+
"DynamicBitMapNonPagedPool" // some weird field
]);
need_structs.insert("_MI_SYSTEM_NODE_NONPAGED_POOL", vec![ // windows insider, 2020
"NonPagedPoolFirstVa", "NonPagedPoolLastVa",
"DynamicBitMapNonPagedPool" // some weird field
]);
need_structs.insert("_MI_DYNAMIC_BITMAP", vec![]);
need_structs.insert("_RTL_BITMAP", vec![]); // windows 10 until 2020
need_structs.insert("_RTL_BITMAP_EX", vec![]); // windows insider, 2020
for &symbol in &need_symbols {
match self.symbols.get(symbol) {
Some(offset) => println!("0x{:x} {}", offset, symbol),
None => {}
}
}
for (&struct_name, members) in &need_structs {
match self.structs.get(struct_name) {
Some(member_info) => {
for &member in members {
match member_info.get(member) {
Some((memtype, offset)) =>
println!("0x{:x} {} {}.{}", offset, memtype, struct_name, member),
None => {}
}
}
},
None => {}
}
}
}
}
fn get_type_as_str(type_finder: &TypeFinder, typ: &TypeIndex) -> String {
match type_finder.find(*typ).unwrap().parse().unwrap() {
TypeData::Class(ct) => {
format!("{}", ct.name.to_string())
},
TypeData::Primitive(pt) => {
format!("{:?}", pt.kind)
},
TypeData::Pointer(pt) => {
format!("{}*", get_type_as_str(type_finder, &pt.underlying_type))
},
TypeData::StaticMember(st) => {
format!("static {}", get_type_as_str(type_finder, &st.field_type))
},
TypeData::Array(at) => {
format!("{}{:?}",
get_type_as_str(type_finder, &at.element_type), /* get_type_as_str(type_finder, &at.indexing_type), */ at.dimensions)
},
// TypeData::Enumeration(et) => {
// format!("enumeration")
// },
// TypeData::Enumerate(et) => {
// format!("enumerate")
// },
// TypeData::MemberFunction(mft) => {
// format!("member function")
// },
// TypeData::OverloadedMethod(ovmt) => {
// format!("overloaded method")
// },
// TypeData::Nested(nt) => {
// format!("nested")
// },
// TypeData::BaseClass(bct) => {
// format!("base class")
// },
// TypeData::VirtualBaseClass(vbct) => {
// format!("virtual base class")
// },
// TypeData::VirtualFunctionTablePointer(vftpt) => {
// format!("virtual function table pointer")
// },
TypeData::Procedure(pt) => {
let rettype = match pt.return_type {
Some(rt) => get_type_as_str(type_finder, &rt),
_ => "UNKNOWN".to_string()
};
format!("{}({})", rettype, get_type_as_str(type_finder, &pt.argument_list))
},
TypeData::Modifier(mt) => {
match mt {
ModifierType { constant: true, volatile: true, unaligned: true, .. } =>
format!("const volatile unaligned {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: true, volatile: true, unaligned: false, .. } =>
format!("const volatile {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: true, volatile: false, unaligned: true, .. } =>
format!("const unaligned {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: false, volatile: true, unaligned: true, .. } =>
format!("volatile unaligned {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: true, volatile: false, unaligned: false, .. } =>
format!("const {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: false, volatile: true, unaligned: false, .. } =>
format!("volatile {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: false, volatile: false, unaligned: true, .. } =>
format!("unaligned {}", get_type_as_str(type_finder, &mt.underlying_type)),
_ => format!("modifier {}", get_type_as_str(type_finder, &mt.underlying_type))
}
},
// TypeData::Union(ut) => {
// format!("union")
// },
// TypeData::Bitfield(bft) => {
// format!("bitfield")
// },
TypeData::FieldList(_flt) => {
format!("fieldlist")
},
// TypeData::ArgumentList(alt) => {
// format!("arglist")
// },
// TypeData::MethodList(mlt) => {
// format!("methodlist")
// },
unk => {
match unk.name() {
Some(s) => format!("{}", s.to_string()),
_ => "UNNOWN".to_string()
}
}
}
}
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();
file.read_to_end(&mut buffer)?;
let mut buffiter = buffer.chunks(4);
while buffiter.next().unwrap() != [0x52, 0x53, 0x44, 0x53] {
// signature == RSDS
}
// next 16 bytes is guid in raw bytes
let raw_guid: Vec<u8> = vec![
buffiter.next().unwrap(),
buffiter.next().unwrap(),
buffiter.next().unwrap(),
buffiter.next().unwrap(),
].concat();
// guid to hex string
let guid = (vec![
raw_guid[3], raw_guid[2], raw_guid[1], raw_guid[0],
raw_guid[5], raw_guid[4],
raw_guid[7], raw_guid[6],
raw_guid[8], raw_guid[9], raw_guid[10], raw_guid[11],
raw_guid[12], raw_guid[13], raw_guid[14], raw_guid[15],
].iter().map(|b| format!("{:02X}", b)).collect::<Vec<String>>()).join("");
// next 4 bytes is age, in little endian
let raw_age = buffiter.next().unwrap();
let age = u32::from_le_bytes([
raw_age[0], raw_age[1], raw_age[2], raw_age[3]
]);
Ok((guid, age))
}
fn pdb_exists(pdbname: &str, guid: &str, age: u32) -> BoxResult<(bool, PathBuf)> {
// Use a folder at %APPDATA% to save pdb files
// %APPDATA%\nganhkhoaa\lpus
// |--ntkrnlmp.pdb
// |--|--GUID
// |--|--|--ntkrnlmp.pdb
// |--file.pdb
// |--|--GUID
// |--|--|--file.pdb
let mut pdb_location = app_dir(AppDataType::UserData, &APP_INFO,
&format!("{}/{}/{}", pdbname, guid, age))?;
pdb_location.push(pdbname);
Ok((pdb_location.exists(), pdb_location))
}
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()?;
let mut type_finder = type_information.type_finder();
let mut iter = type_information.iter();
while let Some(_typ) = iter.next().unwrap() {
type_finder.update(&iter);
}
let mut symbol_extracted: SymbolStore = HashMap::new();
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() {
Ok(SymbolData::PublicSymbol(data)) => {
let name = symbol.name().unwrap().to_string();
let Rva(rva) = data.offset.to_rva(&addr_map).unwrap_or_default();
symbol_extracted.insert(format!("{}", name), rva as u64);
},
_ => {
}
}
}
let mut struct_extracted: StructStore = HashMap::new();
iter = type_information.iter();
while let Some(typ) = iter.next().unwrap() {
match typ.parse() {
Ok(TypeData::Class(ClassType {name, fields: Some(fields), size, ..})) => {
let mut struct_fields = HashMap::new();
struct_fields.insert("struct_size".to_string(), ("u32".to_string(), size as u64));
match type_finder.find(fields).unwrap().parse().unwrap() {
TypeData::FieldList(list) => {
for field in list.fields {
if let TypeData::Member(member) = field {
let mem_typ = get_type_as_str(&type_finder, &member.field_type);
struct_fields.insert(
format!("{}", member.name), (mem_typ, member.offset as u64));
}
}
}
_ => {}
}
struct_extracted.insert(format!("{}", name), struct_fields);
},
_ => {}
}
}
Ok(PdbStore {
symbols: symbol_extracted,
structs: struct_extracted
})
}

257
src/windows.rs Normal file
View File

@ -0,0 +1,257 @@
use std::ffi::{c_void, CString};
use std::mem::{transmute, size_of_val};
use std::ptr::null_mut;
use std::time::{SystemTime, UNIX_EPOCH};
use widestring::U16CString;
use winapi::shared::ntdef::*;
use winapi::shared::minwindef::{DWORD, HKEY, HMODULE};
use winapi::um::winnt::{
SE_PRIVILEGE_ENABLED, TOKEN_PRIVILEGES, TOKEN_ADJUST_PRIVILEGES, LUID_AND_ATTRIBUTES,
REG_DWORD, REG_SZ, REG_OPTION_NON_VOLATILE, KEY_WRITE,
PRTL_OSVERSIONINFOW, OSVERSIONINFOW,
FILE_ATTRIBUTE_NORMAL, GENERIC_READ, GENERIC_WRITE
};
use winapi::um::ioapiset::{DeviceIoControl};
use winapi::um::errhandlingapi::{GetLastError};
use winapi::um::fileapi::{CreateFileA, CREATE_ALWAYS};
use winapi::um::handleapi::{INVALID_HANDLE_VALUE, CloseHandle};
use winapi::um::libloaderapi::{LoadLibraryA, GetProcAddress};
use winapi::um::processthreadsapi::{GetCurrentProcess, OpenProcessToken};
use winapi::um::sysinfoapi::{GetTickCount64};
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\\lpus";
#[allow(dead_code)]
#[derive(Debug, Copy, Clone)]
pub enum WindowsVersion {
Windows10_2015,
Windows10_2016,
Windows10_2017,
Windows10_2018,
Windows10_2019,
Windows10_2020,
Windows10FastRing,
Windows10VersionUnknown
}
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub struct WindowsFFI {
pub version_info: OSVERSIONINFOW,
pub short_version: WindowsVersion,
driver_handle: HANDLE,
ntdll: HMODULE,
nt_load_driver: extern "system" fn(PUNICODE_STRING) -> NTSTATUS,
nt_unload_driver: extern "system" fn(PUNICODE_STRING) -> NTSTATUS,
rtl_init_unicode_str: extern "system" fn(PUNICODE_STRING, PCWSTR),
rtl_get_version: extern "system" fn(PRTL_OSVERSIONINFOW) -> NTSTATUS,
}
impl WindowsFFI {
pub fn new() -> Self {
let str_ntdll = CString::new("ntdll").unwrap();
let str_nt_load_driver = CString::new("NtLoadDriver").unwrap();
let str_nt_unload_driver = CString::new("NtUnloadDriver").unwrap();
let str_rtl_init_unicode_str = CString::new("RtlInitUnicodeString").unwrap();
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\\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();
let str_image_path = CString::new("ImagePath").unwrap();
let mut version_info = OSVERSIONINFOW {
dwOSVersionInfoSize: 0u32,
dwMajorVersion: 0u32,
dwMinorVersion: 0u32,
dwBuildNumber: 0u32,
dwPlatformId: 0u32,
szCSDVersion: [0u16; 128],
};
let ntdll: HMODULE;
let nt_load_driver: extern "system" fn(PUNICODE_STRING) -> NTSTATUS;
let nt_unload_driver: extern "system" fn(PUNICODE_STRING) -> NTSTATUS;
let rtl_init_unicode_str: extern "system" fn(PUNICODE_STRING, PCWSTR);
let rtl_get_version: extern "system" fn(PRTL_OSVERSIONINFOW) -> NTSTATUS;
// some pointer unsafe C code
unsafe {
ntdll = LoadLibraryA(str_ntdll.as_ptr());
let nt_load_driver_ = GetProcAddress(ntdll, str_nt_load_driver.as_ptr());
let nt_unload_driver_ = GetProcAddress(ntdll, str_nt_unload_driver.as_ptr());
let rtl_init_unicode_str_ = GetProcAddress(ntdll, str_rtl_init_unicode_str.as_ptr());
let rtl_get_version_ = GetProcAddress(ntdll, str_rtl_get_version.as_ptr());
nt_load_driver = transmute(nt_load_driver_);
nt_unload_driver = transmute(nt_unload_driver_);
rtl_init_unicode_str = transmute(rtl_init_unicode_str_);
rtl_get_version = transmute(rtl_get_version_);
// setup registry
let mut registry_key: HKEY = null_mut();
RegCreateKeyExA(
HKEY_LOCAL_MACHINE, str_registry_path.as_ptr(),
0, null_mut(),
REG_OPTION_NON_VOLATILE, KEY_WRITE,
null_mut(), &mut registry_key, null_mut()
);
let type_value: [u8; 4] = 1u32.to_le_bytes();
let error_control_value: [u8; 4] = 1u32.to_le_bytes();
let start_value: [u8; 4] = 3u32.to_le_bytes();
let registry_values = [
(str_type.as_ptr(), REG_DWORD, type_value.as_ptr(), 4),
(str_error_control.as_ptr(), REG_DWORD, error_control_value.as_ptr(), 4),
(str_start.as_ptr(), REG_DWORD, start_value.as_ptr(), 4),
(str_image_path.as_ptr(), REG_SZ,
str_driver_path.as_ptr() as *const u8, str_driver_path.to_bytes().len() + 1)
];
for &(key, keytype, value_ptr, size_in_bytes) in &registry_values {
RegSetValueExA(
registry_key, key, 0,
keytype, value_ptr, size_in_bytes as u32
);
}
RegCloseKey(registry_key);
// Setup privilege SeLoadDriverPrivilege
let mut token_handle: HANDLE = null_mut();
let mut luid = LUID::default();
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &mut token_handle);
LookupPrivilegeValueA(null_mut(), str_se_load_driver_privilege.as_ptr(), &mut luid);
let mut new_token_state = TOKEN_PRIVILEGES {
PrivilegeCount: 1,
Privileges: [LUID_AND_ATTRIBUTES {
Luid: luid,
Attributes: SE_PRIVILEGE_ENABLED
}]
};
AdjustTokenPrivileges(
token_handle, 0, &mut new_token_state, 16, null_mut(), null_mut());
CloseHandle(token_handle);
}
rtl_get_version(&mut version_info);
let short_version = match version_info.dwBuildNumber {
17134 | 17763 => WindowsVersion::Windows10_2018,
18362 | 18363 => WindowsVersion::Windows10_2019,
19041 => WindowsVersion::Windows10_2020,
_ if version_info.dwBuildNumber >= 19536 => WindowsVersion::Windows10FastRing,
_ => WindowsVersion::Windows10VersionUnknown
};
Self {
version_info,
short_version,
driver_handle: INVALID_HANDLE_VALUE,
ntdll,
nt_load_driver,
nt_unload_driver,
rtl_init_unicode_str,
rtl_get_version
}
}
pub fn driver_loaded(self) -> bool {
self.driver_handle != INVALID_HANDLE_VALUE
}
pub fn load_driver(&mut self) -> NTSTATUS {
// TODO: Move this to new()
// If we move this function to new(), self.driver_handle will be init, and thus no mut here
let str_driver_reg = U16CString::from_str(STR_DRIVER_REGISTRY_PATH).unwrap();
let mut str_driver_reg_unicode = UNICODE_STRING::default();
(self.rtl_init_unicode_str)(&mut str_driver_reg_unicode, str_driver_reg.as_ptr() as *const u16);
let status = (self.nt_load_driver)(&mut str_driver_reg_unicode);
let filename = CString::new("\\\\.\\poolscanner").unwrap();
let driver_file_handle: HANDLE = unsafe {
CreateFileA(filename.as_ptr(),
GENERIC_READ | GENERIC_WRITE,
0, null_mut(), CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, null_mut())
};
if driver_file_handle == INVALID_HANDLE_VALUE {
println!("Driver CreateFileA failed");
}
else {
self.driver_handle = driver_file_handle;
}
status
}
pub fn unload_driver(&self) -> NTSTATUS {
let str_driver_reg = U16CString::from_str(STR_DRIVER_REGISTRY_PATH).unwrap();
let mut str_driver_reg_unicode = UNICODE_STRING::default();
(self.rtl_init_unicode_str)(&mut str_driver_reg_unicode, str_driver_reg.as_ptr());
(self.nt_unload_driver)(&mut str_driver_reg_unicode)
}
#[allow(dead_code)]
pub fn get_build_number(&self) -> DWORD {
self.version_info.dwBuildNumber
}
#[allow(dead_code)]
pub fn print_version(&self) {
println!("Windows version: {}.{}.{} {:?}",
self.version_info.dwMajorVersion,
self.version_info.dwMinorVersion,
self.version_info.dwBuildNumber,
self.short_version
);
}
pub fn valid_process_time(&self, filetime: u64) -> bool {
// https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/
let windows_epoch_diff = 11644473600000 * 10000;
if filetime < windows_epoch_diff {
return false;
}
let system_up_time_ms = unsafe { GetTickCount64() };
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;
let system_start_up_time_ms = now_ms - system_up_time_ms;
if process_time_epoch < system_start_up_time_ms {
false
} else if process_time_epoch > now_ms {
false
} else {
true
}
}
pub fn device_io<T, E>(&self, code: DWORD, inbuf: &mut T, outbuf: &mut E) -> DWORD {
self.device_io_raw(code,
inbuf as *mut _ as *mut c_void, size_of_val(inbuf) as DWORD,
outbuf as *mut _ as *mut c_void, size_of_val(outbuf) as DWORD)
}
pub fn device_io_raw(&self, code: DWORD,
input_ptr: *mut c_void, input_len: DWORD,
output_ptr: *mut c_void, output_len: DWORD) -> DWORD {
// println!("driver loaded: {}; device_io_code: {}", self.driver_loaded(), code);
let mut bytes_returned: DWORD = 0;
unsafe {
let status = DeviceIoControl(self.driver_handle, code,
input_ptr, input_len,
output_ptr, output_len,
&mut bytes_returned, null_mut());
if status == 0 {
println!("device io failed: last error {}", GetLastError());
}
};
bytes_returned
}
}