Compare commits
24 Commits
0.1.0
...
v0.2-alpha
Author | SHA1 | Date | |
---|---|---|---|
4bf2bb71ff | |||
ecc476c604 | |||
ee13c6be58 | |||
7be3b2fc05 | |||
5842ed216c | |||
ff53a1a31c | |||
dd16a31984 | |||
5bddf90501 | |||
dae10a5312 | |||
3214e79d63 | |||
cbc3cb7e15 | |||
862a5c0788 | |||
d0c0161b06 | |||
d08852af55 | |||
0ca87a871c | |||
2ee77d16c7 | |||
8928e4e4cb | |||
c036f3645a | |||
ebeea02962 | |||
f872b8e14a | |||
71b59861c5 | |||
30da3fe60a | |||
fc61c5e605 | |||
0bb4ecd0e3 |
101
Cargo.lock
generated
101
Cargo.lock
generated
@ -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"
|
||||
|
14
Cargo.toml
14
Cargo.toml
@ -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
|
||||
# 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
138
README.md
@ -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
|
||||
```
|
||||
|
325
logs/eprocess_scan_log_2.txt
Normal file
325
logs/eprocess_scan_log_2.txt
Normal 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
|
50749
logs/file_object_scan_log_2.txt
Normal file
50749
logs/file_object_scan_log_2.txt
Normal file
File diff suppressed because it is too large
Load Diff
80
nonpaged-pool-range.md
Normal file
80
nonpaged-pool-range.md
Normal 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.
|
||||
|
20
other/parse_file_scan_result.py
Normal file
20
other/parse_file_scan_result.py
Normal 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
91
src/bin/eprocess_scan.rs
Normal 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(())
|
||||
}
|
||||
|
56
src/bin/file_object_scan.rs
Normal file
56
src/bin/file_object_scan.rs
Normal file
@ -0,0 +1,56 @@
|
||||
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]");
|
||||
return Ok(true);
|
||||
}
|
||||
if let Ok(filename) = driver.get_unicode_string(fob_addr + fob_filename_offset, true) {
|
||||
println!(" {}", filename);
|
||||
return Ok(true);
|
||||
}
|
||||
Ok(false)
|
||||
})?;
|
||||
|
||||
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
12
src/bin/print_pdb.rs
Normal file
12
src/bin/print_pdb.rs
Normal 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
320
src/driver_state.rs
Normal 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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
105
src/ioctl_protocol.rs
Normal file
105
src/ioctl_protocol.rs
Normal file
@ -0,0 +1,105 @@
|
||||
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),
|
||||
},
|
||||
// TODO: Add other version of Windows here
|
||||
_ => 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
8
src/lib.rs
Normal 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;
|
||||
|
183
src/main.rs
183
src/main.rs
@ -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
394
src/pdb_store.rs
Normal 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
257
src/windows.rs
Normal 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 ®istry_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
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user