Compare commits

..

20 Commits

Author SHA1 Message Date
ae679b62be Format code 2020-08-01 04:47:59 +07:00
e2eac767e0 One binary setup 2020-08-01 04:47:38 +07:00
967684f140 Fix SSDT entry
SSDT entries can be negative, so signed int is used
2020-07-24 21:44:29 +07:00
2d7576b1e2 update 2020-07-21 17:07:52 +07:00
60513ee142 Add driver_irp and test_load 2020-07-07 23:43:29 +07:00
09114848fc Update eprocess and ethread scan 2020-07-03 02:08:27 +07:00
a154c71f9b Run rustfmt 2020-07-02 02:47:15 +07:00
b1c3107c74 Create object in object.rs 2020-07-02 02:44:01 +07:00
4e67e10aee Update working status for Windows 7 2020-07-01 00:01:12 +07:00
8cb553eb11 Update base code for windows 7, 8, 8.1
Because the tag is different in lower version of Windows, need to
change the tag in scan algorithm

4b29cf1986/volatility/framework/plugins/windows/poolscanner.py (L229)
2020-06-30 04:09:13 +07:00
abb7a70b72 Update
- Driver scan device tree and output more data
- Print ssdt scanning base on kernel modules traversing
2020-06-23 18:27:24 +07:00
199c3ca10b Update cargo dependencies
And ready for a lisp repl
2020-06-22 22:31:55 +07:00
0350ec46d9 Scan unloaded module/driver
By reversing MmLocateUnloadedDriver, we can know the algorithm
to extract name/start/end of unloaded drivers
2020-06-22 22:30:35 +07:00
5619048a4a Update lpus feature
Traverse scan
- PsActiveProcessHead
- PsLoadedModuleList
- KiProcessListHead
- HandleTableList

pdb_store has dt(struct) to display struct
2020-06-22 17:45:06 +07:00
8cf91aef79 Update scan for kernel modules and driver
Scan kernel modules
Driver scan major functions' address
2020-06-22 14:52:15 +07:00
1707b301ff Generalize the API for common scan and return json 2020-06-17 01:47:20 +07:00
060f222c0a Introducing Address type
Use address type to represent address
Decompose address with ease using DriverState.decompose
2020-06-11 01:27:26 +07:00
72a947ccd7 Update scan algorithm
- Scan _ETHREAD with PoolTag='Thre'
- Parse pid/ppid from _EPROCESS
- Build process tree from output log
- Static link for machine missing Windows C++ dev environment
2020-06-09 04:13:15 +07:00
8c642f6ba0 add dump test 1 2020-06-05 19:37:13 +07:00
c8ce82e8a7 Update lpus
File scan printing update
Update values sent to driver in ioctl for Windows 10 2019/2018
2020-06-02 16:27:29 +07:00
40 changed files with 69994 additions and 1259 deletions

5
.cargo/config Normal file
View File

@ -0,0 +1,5 @@
[target.x86_64-pc-windows-msvc]
# CRT static to make run on machine without VC++
# https://github.com/rust-lang/rust/pull/66801#issuecomment-558947376
# >> "-Clink-args=/subsystem:console,5.02"
rustflags = ["-Ctarget-feature=+crt-static"]

525
Cargo.lock generated
View File

@ -1,5 +1,13 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "anyhow"
version = "1.0.26"
@ -16,6 +24,26 @@ dependencies = [
"xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "arrayvec"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "1.0.0"
@ -31,11 +59,61 @@ name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2b_simd"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "block-buffer"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "block-padding"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bstr"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bumpalo"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
version = "0.5.4"
@ -69,6 +147,25 @@ dependencies = [
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clap"
version = "2.33.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "core-foundation"
version = "0.6.4"
@ -83,11 +180,83 @@ name = "core-foundation-sys"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "csv"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bstr 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "csv-core"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "digest"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dirs"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dirs-next"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs-sys-next 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dtoa"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "encoding_rs"
version = "0.8.22"
@ -96,6 +265,11 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fallible-iterator"
version = "0.1.6"
@ -174,6 +348,14 @@ dependencies = [
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "generic-array"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "getrandom"
version = "0.1.14"
@ -218,11 +400,6 @@ 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"
@ -354,13 +531,26 @@ 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)",
"clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parse_int 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"prettytable-rs 0.8.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)",
"rust-embed 5.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustyline 6.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
"vergen 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"widestring 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "matches"
version = "0.1.8"
@ -441,6 +631,18 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nix"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nom"
version = "4.2.3"
@ -485,6 +687,11 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "openssl"
version = "0.10.28"
@ -515,6 +722,14 @@ dependencies = [
"vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parse_int"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pdb"
version = "0.5.0"
@ -530,6 +745,45 @@ name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ucd-trie 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pest_derive"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_generator 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pest_generator"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_meta 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pest_meta"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pin-project"
version = "0.4.8"
@ -568,6 +822,19 @@ name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "prettytable-rs"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.4.30"
@ -642,6 +909,24 @@ name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_users"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-automata"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "remove_dir_all"
version = "0.5.2"
@ -684,6 +969,46 @@ dependencies = [
"winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rust-argon2"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rust-embed"
version = "5.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rust-embed-impl 5.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-embed-utils 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rust-embed-impl"
version = "5.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-embed-utils 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rust-embed-utils"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
@ -692,11 +1017,37 @@ dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustyline"
version = "6.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs-next 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8parse 0.2.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 = "ryu"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "schannel"
version = "0.1.17"
@ -706,6 +1057,11 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scroll"
version = "0.9.2"
@ -764,7 +1120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_json"
version = "1.0.48"
version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -783,6 +1139,17 @@ dependencies = [
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sha-1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "shell32-sys"
version = "0.1.2"
@ -807,6 +1174,11 @@ name = "sourcefile"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.15.44"
@ -840,6 +1212,24 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "term"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"
version = "0.1.42"
@ -898,6 +1288,16 @@ name = "try-lock"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "typenum"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ucd-trie"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicase"
version = "2.6.0"
@ -927,6 +1327,11 @@ name = "unicode-segmentation"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-width"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.1.0"
@ -947,6 +1352,11 @@ dependencies = [
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "utf8parse"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "uuid"
version = "0.7.4"
@ -957,6 +1367,20 @@ name = "vcpkg"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vergen"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 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)",
]
[[package]]
name = "version_check"
version = "0.1.5"
@ -967,6 +1391,21 @@ name = "version_check"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "walkdir"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "want"
version = "0.3.0"
@ -988,7 +1427,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1080,7 +1519,7 @@ dependencies = [
[[package]]
name = "widestring"
version = "0.4.0"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -1107,6 +1546,14 @@ name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
@ -1135,21 +1582,42 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"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 arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"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"
"checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
"checksum bstr 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931"
"checksum bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
"checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1"
"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 clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
"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 crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
"checksum csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279"
"checksum csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
"checksum dirs-next 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1cbcf9241d9e8d106295bd496bbe2e9cffd5fa098f2a8c9e2bbcbf09773c11a8"
"checksum dirs-sys-next 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c60f7b8a8953926148223260454befb50c751d3c50e1c178c4fd1ace4083c9a"
"checksum dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3"
"checksum encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
"checksum encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fallible-iterator 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eb7217124812dc5672b7476d0c2d20cfe9f7c0f1ba0904b674a9762a0212f72e"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
@ -1162,11 +1630,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6"
"checksum futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27"
"checksum futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"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"
@ -1181,6 +1649,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53445de381a1f436797497c61d851644d0e8e88e6140f22872ad33a704933978"
"checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
@ -1189,22 +1658,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"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 nix 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
"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 opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"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"
"checksum parse_int 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82db48cac18f0963b10ddad303fa88447b95bbe0e6dbe3385f98402b63d0cc48"
"checksum pdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6b57b7067dc9dbd04b1305bb51a8ae7d0fc645956a73b6cb2807dd956ab6929"
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
"checksum pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
"checksum pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
"checksum pest_generator 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
"checksum pest_meta 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
"checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c"
"checksum pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f"
"checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae"
"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
@ -1214,11 +1691,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
"checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
"checksum reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0e798e19e258bf6c30a304622e3e9ac820e483b06a1857a026e1f109b113fe4"
"checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
"checksum rust-embed 5.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "213acf1bc5a6dfcd70b62db1e9a7d06325c0e73439c312fcb8599d456d9686ee"
"checksum rust-embed-impl 5.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7903c2cf599db8f310b392332f38367ca4acc84420fa1aee3536299f433c10d5"
"checksum rust-embed-utils 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97655158074ccb2d2cfb1ccb4c956ef0f4054e43a2c1e71146d4991e6961e105"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum rustyline 6.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3358c21cbbc1a751892528db4e1de4b7a2b6a73f001e215aaba97d712cfa9777"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
"checksum schannel 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "507a9e6e8ffe0a4e0ebb9a10293e62fdf7657c06f1b8bb07a8fcf697d2abf295"
"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
"checksum scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f84d114ef17fd144153d608fba7c446b0145d038985e7a8cc5d08bb0ce20383"
"checksum scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb"
"checksum security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df"
@ -1226,32 +1712,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"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_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226"
"checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
"checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
"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"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b"
"checksum tokio-tls 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7bde02a3a5291395f59b06ec6945a3077602fac2b07eeeaf0dee2122f3619828"
"checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930"
"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
"checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
"checksum ucd-trie 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
"checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
"checksum utf8parse 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
"checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168"
"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
"checksum vergen 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ce50d8996df1f85af15f2cd8d33daae6e479575123ef4314a51a70a230739cb"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
"checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c"
@ -1263,11 +1761,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"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 widestring 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a763e303c0e0f23b0da40888724762e802a8ffefbc22de4127ef42493c2ea68c"
"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"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
"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"

View File

@ -12,9 +12,21 @@ 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"] }
serde_json = "1.0.55"
parse_int = "0.4.0"
# repl dependencies
rustyline = "6.2.0"
pest = "2.1.3"
pest_derive = "2.1.0"
# others
prettytable-rs = "^0.8"
rust-embed="5.6.0"
clap="2.33.1"
[build-dependencies]
vergen="3.1.0"

View File

@ -1,6 +1,16 @@
# LPUS (A live pool-tag scanning solution)
This is the frontend to the live pool tag scanning solution, the backend is a driver (which is now closed source).
This is the frontend to the live pool tag scanning solution, the backend is a
driver (which is now closed source).
Works on Windows 7 and above (Vista not tested, but 7 ok and 10 ok), and on x64
systems only. (I hardcoded the address as u64 so only 64 systems should run this).
> The binary is runable, without crashing. But I still need to add some
manual instructions on referencing the structs and offset on some places.
> Windows 10, versions 2018, 2019 and 2020 is tested and works.
Windows XP is not supported: Windows XP Win32Api is missing here and there.
## How this works
@ -21,7 +31,7 @@ use lpus::{
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| {
driver.scan_pool(b"Tag ", "_STRUCT_NAME", |pool_addr, header, data_addr| {
})?;
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
}
@ -33,3 +43,67 @@ 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.
We also have a set of functions for scanning a specific tag/object.
- `pub fn scan_eprocess(driver: &DriverState) -> BoxResult<Vec<Value>>`
- `pub fn scan_file(driver: &DriverState) -> BoxResult<Vec<Value>>`
- `pub fn scan_ethread(driver: &DriverState) -> BoxResult<Vec<Value>>`
- `pub fn scan_mutant(driver: &DriverState) -> BoxResult<Vec<Value>>`
- `pub fn scan_driver(driver: &DriverState) -> BoxResult<Vec<Value>>`
- `pub fn scan_kernel_module(driver: &DriverState) -> BoxResult<Vec<Value>>`
And a list traversing the kernel object:
- `pub fn traverse_loadedmodulelist(driver: &DriverState) -> BoxResult<Vec<Value>>`
- `pub fn traverse_activehead(driver: &DriverState) -> BoxResult<Vec<Value>>`
- missing symbols `pub fn traverse_afdendpoint(driver: &DriverState) -> BoxResult<Vec<Value>>`
- `pub fn traverse_kiprocesslist(driver: &DriverState) -> BoxResult<Vec<Value>>`
- `pub fn traverse_handletable(driver: &DriverState) -> BoxResult<Vec<Value>>`
- `pub fn traverse_unloadeddrivers(driver: &DriverState) -> BoxResult<Vec<Value>>`
## Things to note
Right now, we only have one symbol file of ntoskrnl.exe. While we may need more
symbols, kernel32.sys, win32k.sys, tcpis.sys... This will be a future update
where symbols are combined into one big `HashMap` but still retain the module. I
haven't tested the debug symbols of others binary, I wonder if the PDB file even
exists.
The pdb file is not restricted in ntoskrnl.exe, I might need to split to a
smaller module or such.
Also the symbols list is parsed directly from the PDB file, but some structs
(like the callback routine members or network structs) are missing. Right now a
simple hardcoded to add in a struct member is used, but it would break if the
OS running have a different layout.
The HashMap of symbols/struct is now using string and u32 to store member
offset and types, this should be changed into something that would be type-safe
and more functional.
I also follow a few Volatility implementation on Rootkit, The art of Memory
forensics Chapter 13. Scanning in Windows 10 yields promising result, though I
haven't tested on any malware to see if we can have the "same" result.
At the pace of development, I seperate the binary to functionalities for
testing, I would add a CLI and a REPL.
One last thing, the backend doesn't have any check on address referencing, so
one may get a blue screen, eventhough I tried to avoid it, I'm not 100% sure it
would not crash the system.
## Future works
- [ ] An interactive repl (1)
- [ ] More kernel modules symbols (2)
- [ ] Implementation of more technique (reference Volatility here)
- [ ] Quick and easy way to add manual struct, symbols (3)
(1) This is quite hard to work out, because we have to make the *types* works.
The currently chosen repl is based on Lisp, because lisp is cool. If the repl
is online, we can combine everything into one binary.
(2) We may need to download it all and combine to one `HashMap`, with their
types as a specific struct. (Try to avoid string).
(3) Have no idea on this.

8
build.rs Normal file
View File

@ -0,0 +1,8 @@
extern crate vergen;
use vergen::{generate_cargo_keys, ConstantsFlags};
fn main() {
let flags = ConstantsFlags::all();
generate_cargo_keys(flags).expect("Unable to generate the cargo keys!");
}

View File

@ -0,0 +1,74 @@
import sys
import re
import collections
class Process:
def __init__(self, e, pid, ppid, name, path):
self.e = e
self.pid = pid
self.ppid = ppid
self.name = name
self.path = path
def __str__(self):
return f'{self.e} {self.pid} {self.ppid} {self.name} {self.path}'
def __repr__(self):
return f'{self.e} {self.pid} {self.ppid} {self.name} {self.path}'
process_map = {}
# shamelessly steal from https://github.com/giampaolo/psutil/blob/master/scripts/pstree.py
# not work if a detached node presents
def print_tree(parent, tree, indent='', traversed=[]):
try:
p = process_map[parent]
name = f"{p.pid} [{p.name}] {p.path}"
except:
name = f"{parent} [UNNOWN]"
# input(name)
if parent in traversed:
print(name, "[LOOP]")
return
else:
print(name)
traversed += [parent]
if parent not in tree:
return
children = tree[parent][:-1]
for child in children:
print(indent + "|- ", end='')
print_tree(child.pid, tree, indent + "| ", traversed)
child = tree[parent][-1]
print(indent + "`_ ", end='')
print_tree(child.pid, tree, indent + " ", traversed)
lpus = re.finditer(r'^pool: 0x[0-9a-f]+ \| eprocess: (0x[0-9a-f]+) \| pid: (\d+) \| ppid: (\d+) \| name: ([^|]*) \| (.*)$',
open(sys.argv[1], 'r', encoding='utf-8').read(), re.MULTILINE)
process_tree = {}
for v in lpus:
e, pid, ppid, name, path = list(v.groups())
proc = Process(e, int(pid), int(ppid), name, path)
process_map[int(pid)] = proc
if int(ppid) in process_tree:
process_tree[int(ppid)] += [proc]
else:
process_tree[int(ppid)] = [proc]
if 0 in process_tree:
process_tree.pop(0)
remove = []
for k, child in process_tree.items():
for c in child:
if c.pid in process_tree and c.ppid in process_tree:
# print('remove', c)
remove += [c.pid]
break
# print(remove)
for k in process_tree.keys():
if k not in remove:
print_tree(k, process_tree)
# input()

View File

@ -0,0 +1,118 @@
address,process,fullpath
0xffff948957c6c080,svchost.exe,
0xffff948957caa080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895ad15080,powershell.exe,
0xffff94895ad1a080,CodeHelper.exe,\Users\User\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\platform\files\node\watcher\win32\CodeHelper.exe
0xffff94895b394080,Code.exe,\Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
0xffff94895ba28080,MicrosoftEdgeC,\Windows\System32\MicrosoftEdgeCP.exe
0xffff94895ba2b080,sppsvc.exe,\Windows\System32\sppsvc.exe
0xffff94895ba433c0,audiodg.exe,\Windows\System32\audiodg.exe
0xffff94895bb21380,powershell.exe,\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
0xffff94895bb25080,MicrosoftEdgeC,\Windows\System32\MicrosoftEdgeCP.exe
0xffff94895bb28080,conhost.exe,\Windows\System32\conhost.exe
0xffff94895bb8a080,conhost.exe,\Windows\System32\conhost.exe
0xffff94895cbc9080,Code.exe,\Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
0xffff94895ce98400,svchost.exe,\Windows\System32\svchost.exe
0xffff94895cea7080,MemCompression,
0xffff94895ceb5380,svchost.exe,\Windows\System32\svchost.exe
0xffff94895cec9080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895cf2e3c0,svchost.exe,\Windows\System32\svchost.exe
0xffff94895cf5c400,svchost.exe,\Windows\System32\svchost.exe
0xffff94895cf90400,svchost.exe,\Windows\System32\svchost.exe
0xffff94895cf98400,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e017440,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e02b380,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e072400,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e077400,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e0ce400,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e0d8400,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e1670c0,sqlwriter.exe,\Program Files\Microsoft SQL Server\90\Shared\sqlwriter.exe
0xffff94895e169380,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e16a080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e16b080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e16c080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e16d080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e170080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e171080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e172080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e174080,spoolsv.exe,\Windows\System32\spoolsv.exe
0xffff94895e1780c0,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e38b080,WindowsInterna,\Windows\SystemApps\InputApp_cw5n1h2txyewy\WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.exe
0xffff94895e390080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e391080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e392080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e394080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e395080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e396080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895e3990c0,wlms.exe,\Windows\System32\wlms\wlms.exe
0xffff94895e54e4c0,NisSrv.exe,\ProgramData\Microsoft\Windows Defender\Platform\4.18.2005.5-0\NisSrv.exe
0xffff94895e929480,smartscreen.ex,\Windows\System32\smartscreen.exe
0xffff94895e92a080,Code.exe,\Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
0xffff94895e9412c0,Windows.WARP.J,\Windows\System32\Windows.WARP.JITService.exe
0xffff94895e9512c0,MsMpEng.exe,\ProgramData\Microsoft\Windows Defender\Platform\4.18.2005.5-0\MsMpEng.exe
0xffff94895e970080,SearchUI.exe,\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe
0xffff94895eaaf440,sihost.exe,\Windows\System32\sihost.exe
0xffff94895eaee480,svchost.exe,\Windows\System32\svchost.exe
0xffff94895eaf54c0,svchost.exe,\Windows\System32\svchost.exe
0xffff94895eaf84c0,svchost.exe,\Windows\System32\svchost.exe
0xffff94895eb4f080,svchost.exe,
0xffff94895eb57380,svchost.exe,\Windows\System32\svchost.exe
0xffff94895eb5b4c0,taskhostw.exe,\Windows\System32\taskhostw.exe
0xffff94895ebbd3c0,svchost.exe,\Windows\System32\svchost.exe
0xffff94895ebc2440,ctfmon.exe,\Windows\System32\ctfmon.exe
0xffff94895ec48400,svchost.exe,\Windows\System32\svchost.exe
0xffff94895ec5e080,userinit.exe,
0xffff94895ec62080,explorer.exe,\Windows\explorer.exe
0xffff94895ec70080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895ec77080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895ec934c0,svchost.exe,\Windows\System32\svchost.exe
0xffff94895eccc4c0,Code.exe,\Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
0xffff94895ece5080,dllhost.exe,\Windows\System32\dllhost.exe
0xffff94895edca080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895edda080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895edf6080,StartMenuExper,\Windows\SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\StartMenuExperienceHost.exe
0xffff94895ef1b480,RuntimeBroker.,\Windows\System32\RuntimeBroker.exe
0xffff94895efb9080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895f089480,RuntimeBroker.,\Windows\System32\RuntimeBroker.exe
0xffff94895f118480,RuntimeBroker.,\Windows\System32\RuntimeBroker.exe
0xffff94895f119080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895f122380,SearchIndexer.,\Windows\System32\SearchIndexer.exe
0xffff94895f19e080,Windows.WARP.J,\Windows\System32\Windows.WARP.JITService.exe
0xffff94895f2020c0,MicrosoftEdge.,\Windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe
0xffff94895f2074c0,ApplicationFra,\Windows\System32\ApplicationFrameHost.exe
0xffff94895f267440,cmd.exe,\Windows\System32\cmd.exe
0xffff94895f2c8080,SgrmBroker.exe,\Windows\System32\SgrmBroker.exe
0xffff94895f2db080,SkypeBackgroun,\Program Files\WindowsApps\Microsoft.SkypeApp_14.56.102.0_x64__kzf8qxf38zg5c\SkypeBackgroundHost.exe
0xffff94895f2dd080,SkypeApp.exe,\Program Files\WindowsApps\Microsoft.SkypeApp_14.56.102.0_x64__kzf8qxf38zg5c\SkypeApp.exe
0xffff94895f3be480,browser_broker,\Windows\System32\browser_broker.exe
0xffff94895f3c5080,YourPhone.exe,\Program Files\WindowsApps\Microsoft.YourPhone_1.20041.91.0_x64__8wekyb3d8bbwe\YourPhone.exe
0xffff94895f3ce400,svchost.exe,\Windows\System32\svchost.exe
0xffff94895f419080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895f449080,WinStore.App.e,\Program Files\WindowsApps\Microsoft.WindowsStore_12005.1001.1.0_x64__8wekyb3d8bbwe\WinStore.App.exe
0xffff94895f44b480,RuntimeBroker.,\Windows\System32\RuntimeBroker.exe
0xffff94895f4b1080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895f4e5080,RuntimeBroker.,\Windows\System32\RuntimeBroker.exe
0xffff94895f4e9240,MicrosoftEdgeC,\Windows\System32\MicrosoftEdgeCP.exe
0xffff94895f571480,RuntimeBroker.,\Windows\System32\RuntimeBroker.exe
0xffff94895f5880c0,RuntimeBroker.,\Windows\System32\RuntimeBroker.exe
0xffff94895f58e080,VBoxTray.exe,\Windows\System32\VBoxTray.exe
0xffff94895f5c7080,svchost.exe,\Windows\System32\svchost.exe
0xffff94895f603080,MicrosoftEdgeS,\Windows\System32\MicrosoftEdgeSH.exe
0xffff94895f7c7080,OneDrive.exe,\Users\User\AppData\Local\Microsoft\OneDrive\OneDrive.exe
0xffff94895f7c8080,SecurityHealth,\Windows\System32\SecurityHealthSystray.exe
0xffff94895f7ca380,SecurityHealth,\Windows\System32\SecurityHealthService.exe
0xffff94895fce60c0,backgroundTask,\Windows\System32\backgroundTaskHost.exe
0xffff94895fdd2080,Code.exe,\Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
0xffff94895ffce080,MicrosoftEdgeC,
0xffff94895ffe2080,Code.exe,\Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
0xffff94895ffef080,backgroundTask,\Windows\System32\backgroundTaskHost.exe
0xffff94895fff2480,conhost.exe,\Windows\System32\conhost.exe
0xffff9489600c50c0,Code.exe,\Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
0xffff9489600cf340,eprocess_scan.,\Users\User\Desktop\lpus-0.3-alpha\target\release\eprocess_scan.exe
0xffff9489602ec080,dllhost.exe,\Windows\System32\dllhost.exe
0xffff9489602f0080,conhost.exe,
0xffff9489602f5080,svchost.exe,\Windows\System32\svchost.exe
0xffff9489603ca080,Windows.WARP.J,\Windows\System32\Windows.WARP.JITService.exe
0xffff948960acc080,svchost.exe,\Windows\System32\svchost.exe
0xffff948960ad3080,RuntimeBroker.,\Windows\System32\RuntimeBroker.exe
0xffff9489610de080,MicrosoftEdgeC,\Windows\System32\MicrosoftEdgeCP.exe
1 address process fullpath
2 0xffff948957c6c080 svchost.exe
3 0xffff948957caa080 svchost.exe \Windows\System32\svchost.exe
4 0xffff94895ad15080 powershell.exe
5 0xffff94895ad1a080 CodeHelper.exe \Users\User\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\platform\files\node\watcher\win32\CodeHelper.exe
6 0xffff94895b394080 Code.exe \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
7 0xffff94895ba28080 MicrosoftEdgeC \Windows\System32\MicrosoftEdgeCP.exe
8 0xffff94895ba2b080 sppsvc.exe \Windows\System32\sppsvc.exe
9 0xffff94895ba433c0 audiodg.exe \Windows\System32\audiodg.exe
10 0xffff94895bb21380 powershell.exe \Windows\System32\WindowsPowerShell\v1.0\powershell.exe
11 0xffff94895bb25080 MicrosoftEdgeC \Windows\System32\MicrosoftEdgeCP.exe
12 0xffff94895bb28080 conhost.exe \Windows\System32\conhost.exe
13 0xffff94895bb8a080 conhost.exe \Windows\System32\conhost.exe
14 0xffff94895cbc9080 Code.exe \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
15 0xffff94895ce98400 svchost.exe \Windows\System32\svchost.exe
16 0xffff94895cea7080 MemCompression
17 0xffff94895ceb5380 svchost.exe \Windows\System32\svchost.exe
18 0xffff94895cec9080 svchost.exe \Windows\System32\svchost.exe
19 0xffff94895cf2e3c0 svchost.exe \Windows\System32\svchost.exe
20 0xffff94895cf5c400 svchost.exe \Windows\System32\svchost.exe
21 0xffff94895cf90400 svchost.exe \Windows\System32\svchost.exe
22 0xffff94895cf98400 svchost.exe \Windows\System32\svchost.exe
23 0xffff94895e017440 svchost.exe \Windows\System32\svchost.exe
24 0xffff94895e02b380 svchost.exe \Windows\System32\svchost.exe
25 0xffff94895e072400 svchost.exe \Windows\System32\svchost.exe
26 0xffff94895e077400 svchost.exe \Windows\System32\svchost.exe
27 0xffff94895e0ce400 svchost.exe \Windows\System32\svchost.exe
28 0xffff94895e0d8400 svchost.exe \Windows\System32\svchost.exe
29 0xffff94895e1670c0 sqlwriter.exe \Program Files\Microsoft SQL Server\90\Shared\sqlwriter.exe
30 0xffff94895e169380 svchost.exe \Windows\System32\svchost.exe
31 0xffff94895e16a080 svchost.exe \Windows\System32\svchost.exe
32 0xffff94895e16b080 svchost.exe \Windows\System32\svchost.exe
33 0xffff94895e16c080 svchost.exe \Windows\System32\svchost.exe
34 0xffff94895e16d080 svchost.exe \Windows\System32\svchost.exe
35 0xffff94895e170080 svchost.exe \Windows\System32\svchost.exe
36 0xffff94895e171080 svchost.exe \Windows\System32\svchost.exe
37 0xffff94895e172080 svchost.exe \Windows\System32\svchost.exe
38 0xffff94895e174080 spoolsv.exe \Windows\System32\spoolsv.exe
39 0xffff94895e1780c0 svchost.exe \Windows\System32\svchost.exe
40 0xffff94895e38b080 WindowsInterna \Windows\SystemApps\InputApp_cw5n1h2txyewy\WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.exe
41 0xffff94895e390080 svchost.exe \Windows\System32\svchost.exe
42 0xffff94895e391080 svchost.exe \Windows\System32\svchost.exe
43 0xffff94895e392080 svchost.exe \Windows\System32\svchost.exe
44 0xffff94895e394080 svchost.exe \Windows\System32\svchost.exe
45 0xffff94895e395080 svchost.exe \Windows\System32\svchost.exe
46 0xffff94895e396080 svchost.exe \Windows\System32\svchost.exe
47 0xffff94895e3990c0 wlms.exe \Windows\System32\wlms\wlms.exe
48 0xffff94895e54e4c0 NisSrv.exe \ProgramData\Microsoft\Windows Defender\Platform\4.18.2005.5-0\NisSrv.exe
49 0xffff94895e929480 smartscreen.ex \Windows\System32\smartscreen.exe
50 0xffff94895e92a080 Code.exe \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
51 0xffff94895e9412c0 Windows.WARP.J \Windows\System32\Windows.WARP.JITService.exe
52 0xffff94895e9512c0 MsMpEng.exe \ProgramData\Microsoft\Windows Defender\Platform\4.18.2005.5-0\MsMpEng.exe
53 0xffff94895e970080 SearchUI.exe \Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe
54 0xffff94895eaaf440 sihost.exe \Windows\System32\sihost.exe
55 0xffff94895eaee480 svchost.exe \Windows\System32\svchost.exe
56 0xffff94895eaf54c0 svchost.exe \Windows\System32\svchost.exe
57 0xffff94895eaf84c0 svchost.exe \Windows\System32\svchost.exe
58 0xffff94895eb4f080 svchost.exe
59 0xffff94895eb57380 svchost.exe \Windows\System32\svchost.exe
60 0xffff94895eb5b4c0 taskhostw.exe \Windows\System32\taskhostw.exe
61 0xffff94895ebbd3c0 svchost.exe \Windows\System32\svchost.exe
62 0xffff94895ebc2440 ctfmon.exe \Windows\System32\ctfmon.exe
63 0xffff94895ec48400 svchost.exe \Windows\System32\svchost.exe
64 0xffff94895ec5e080 userinit.exe
65 0xffff94895ec62080 explorer.exe \Windows\explorer.exe
66 0xffff94895ec70080 svchost.exe \Windows\System32\svchost.exe
67 0xffff94895ec77080 svchost.exe \Windows\System32\svchost.exe
68 0xffff94895ec934c0 svchost.exe \Windows\System32\svchost.exe
69 0xffff94895eccc4c0 Code.exe \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
70 0xffff94895ece5080 dllhost.exe \Windows\System32\dllhost.exe
71 0xffff94895edca080 svchost.exe \Windows\System32\svchost.exe
72 0xffff94895edda080 svchost.exe \Windows\System32\svchost.exe
73 0xffff94895edf6080 StartMenuExper \Windows\SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\StartMenuExperienceHost.exe
74 0xffff94895ef1b480 RuntimeBroker. \Windows\System32\RuntimeBroker.exe
75 0xffff94895efb9080 svchost.exe \Windows\System32\svchost.exe
76 0xffff94895f089480 RuntimeBroker. \Windows\System32\RuntimeBroker.exe
77 0xffff94895f118480 RuntimeBroker. \Windows\System32\RuntimeBroker.exe
78 0xffff94895f119080 svchost.exe \Windows\System32\svchost.exe
79 0xffff94895f122380 SearchIndexer. \Windows\System32\SearchIndexer.exe
80 0xffff94895f19e080 Windows.WARP.J \Windows\System32\Windows.WARP.JITService.exe
81 0xffff94895f2020c0 MicrosoftEdge. \Windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe
82 0xffff94895f2074c0 ApplicationFra \Windows\System32\ApplicationFrameHost.exe
83 0xffff94895f267440 cmd.exe \Windows\System32\cmd.exe
84 0xffff94895f2c8080 SgrmBroker.exe \Windows\System32\SgrmBroker.exe
85 0xffff94895f2db080 SkypeBackgroun \Program Files\WindowsApps\Microsoft.SkypeApp_14.56.102.0_x64__kzf8qxf38zg5c\SkypeBackgroundHost.exe
86 0xffff94895f2dd080 SkypeApp.exe \Program Files\WindowsApps\Microsoft.SkypeApp_14.56.102.0_x64__kzf8qxf38zg5c\SkypeApp.exe
87 0xffff94895f3be480 browser_broker \Windows\System32\browser_broker.exe
88 0xffff94895f3c5080 YourPhone.exe \Program Files\WindowsApps\Microsoft.YourPhone_1.20041.91.0_x64__8wekyb3d8bbwe\YourPhone.exe
89 0xffff94895f3ce400 svchost.exe \Windows\System32\svchost.exe
90 0xffff94895f419080 svchost.exe \Windows\System32\svchost.exe
91 0xffff94895f449080 WinStore.App.e \Program Files\WindowsApps\Microsoft.WindowsStore_12005.1001.1.0_x64__8wekyb3d8bbwe\WinStore.App.exe
92 0xffff94895f44b480 RuntimeBroker. \Windows\System32\RuntimeBroker.exe
93 0xffff94895f4b1080 svchost.exe \Windows\System32\svchost.exe
94 0xffff94895f4e5080 RuntimeBroker. \Windows\System32\RuntimeBroker.exe
95 0xffff94895f4e9240 MicrosoftEdgeC \Windows\System32\MicrosoftEdgeCP.exe
96 0xffff94895f571480 RuntimeBroker. \Windows\System32\RuntimeBroker.exe
97 0xffff94895f5880c0 RuntimeBroker. \Windows\System32\RuntimeBroker.exe
98 0xffff94895f58e080 VBoxTray.exe \Windows\System32\VBoxTray.exe
99 0xffff94895f5c7080 svchost.exe \Windows\System32\svchost.exe
100 0xffff94895f603080 MicrosoftEdgeS \Windows\System32\MicrosoftEdgeSH.exe
101 0xffff94895f7c7080 OneDrive.exe \Users\User\AppData\Local\Microsoft\OneDrive\OneDrive.exe
102 0xffff94895f7c8080 SecurityHealth \Windows\System32\SecurityHealthSystray.exe
103 0xffff94895f7ca380 SecurityHealth \Windows\System32\SecurityHealthService.exe
104 0xffff94895fce60c0 backgroundTask \Windows\System32\backgroundTaskHost.exe
105 0xffff94895fdd2080 Code.exe \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
106 0xffff94895ffce080 MicrosoftEdgeC
107 0xffff94895ffe2080 Code.exe \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
108 0xffff94895ffef080 backgroundTask \Windows\System32\backgroundTaskHost.exe
109 0xffff94895fff2480 conhost.exe \Windows\System32\conhost.exe
110 0xffff9489600c50c0 Code.exe \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe
111 0xffff9489600cf340 eprocess_scan. \Users\User\Desktop\lpus-0.3-alpha\target\release\eprocess_scan.exe
112 0xffff9489602ec080 dllhost.exe \Windows\System32\dllhost.exe
113 0xffff9489602f0080 conhost.exe
114 0xffff9489602f5080 svchost.exe \Windows\System32\svchost.exe
115 0xffff9489603ca080 Windows.WARP.J \Windows\System32\Windows.WARP.JITService.exe
116 0xffff948960acc080 svchost.exe \Windows\System32\svchost.exe
117 0xffff948960ad3080 RuntimeBroker. \Windows\System32\RuntimeBroker.exe
118 0xffff9489610de080 MicrosoftEdgeC \Windows\System32\MicrosoftEdgeCP.exe

View File

@ -0,0 +1,121 @@
PDB for Amd64, guid: e7477a03-a707-8050-cb79-36455ce346b5, age: 1
NtLoadDriver() -> 0x0
pool: 0xffff948957c6c000 | eprocess: 0xffff948957c6c080 | | svchost.exe
pool: 0xffff948957caa000 | eprocess: 0xffff948957caa080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895ad15000 | eprocess: 0xffff94895ad15080 | | powershell.exe
pool: 0xffff94895ad1a000 | eprocess: 0xffff94895ad1a080 | \Users\User\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\platform\files\node\watcher\win32\CodeHelper.exe | CodeHelper.exe
pool: 0xffff94895b394000 | eprocess: 0xffff94895b394080 | \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe | Code.exe
pool: 0xffff94895ba28000 | eprocess: 0xffff94895ba28080 | \Windows\System32\MicrosoftEdgeCP.exe | MicrosoftEdgeC
pool: 0xffff94895ba2b000 | eprocess: 0xffff94895ba2b080 | \Windows\System32\sppsvc.exe | sppsvc.exe
pool: 0xffff94895ba43360 | eprocess: 0xffff94895ba433c0 | \Windows\System32\audiodg.exe | audiodg.exe
pool: 0xffff94895bb21310 | eprocess: 0xffff94895bb21380 | \Windows\System32\WindowsPowerShell\v1.0\powershell.exe | powershell.exe
pool: 0xffff94895bb25000 | eprocess: 0xffff94895bb25080 | \Windows\System32\MicrosoftEdgeCP.exe | MicrosoftEdgeC
pool: 0xffff94895bb28000 | eprocess: 0xffff94895bb28080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffff94895bb8a000 | eprocess: 0xffff94895bb8a080 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffff94895cbc9000 | eprocess: 0xffff94895cbc9080 | \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe | Code.exe
pool: 0xffff94895ce98390 | eprocess: 0xffff94895ce98400 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895cea7040 | eprocess: 0xffff94895cea7080 | | MemCompression
pool: 0xffff94895ceb5310 | eprocess: 0xffff94895ceb5380 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895cec9000 | eprocess: 0xffff94895cec9080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895cf2e350 | eprocess: 0xffff94895cf2e3c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895cf5c390 | eprocess: 0xffff94895cf5c400 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895cf90390 | eprocess: 0xffff94895cf90400 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895cf98390 | eprocess: 0xffff94895cf98400 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e0173c0 | eprocess: 0xffff94895e017440 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e02b310 | eprocess: 0xffff94895e02b380 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e072390 | eprocess: 0xffff94895e072400 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e077390 | eprocess: 0xffff94895e077400 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e0ce390 | eprocess: 0xffff94895e0ce400 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e0d8390 | eprocess: 0xffff94895e0d8400 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e167040 | eprocess: 0xffff94895e1670c0 | \Program Files\Microsoft SQL Server\90\Shared\sqlwriter.exe | sqlwriter.exe
pool: 0xffff94895e169310 | eprocess: 0xffff94895e169380 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e16a000 | eprocess: 0xffff94895e16a080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e16b000 | eprocess: 0xffff94895e16b080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e16c000 | eprocess: 0xffff94895e16c080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e16d000 | eprocess: 0xffff94895e16d080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e170000 | eprocess: 0xffff94895e170080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e171000 | eprocess: 0xffff94895e171080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e172000 | eprocess: 0xffff94895e172080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e174000 | eprocess: 0xffff94895e174080 | \Windows\System32\spoolsv.exe | spoolsv.exe
pool: 0xffff94895e178040 | eprocess: 0xffff94895e1780c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e38b000 | eprocess: 0xffff94895e38b080 | \Windows\SystemApps\InputApp_cw5n1h2txyewy\WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.exe | WindowsInterna
pool: 0xffff94895e390000 | eprocess: 0xffff94895e390080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e391000 | eprocess: 0xffff94895e391080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e392000 | eprocess: 0xffff94895e392080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e394000 | eprocess: 0xffff94895e394080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e395000 | eprocess: 0xffff94895e395080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e396000 | eprocess: 0xffff94895e396080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895e399040 | eprocess: 0xffff94895e3990c0 | \Windows\System32\wlms\wlms.exe | wlms.exe
pool: 0xffff94895e54e450 | eprocess: 0xffff94895e54e4c0 | \ProgramData\Microsoft\Windows Defender\Platform\4.18.2005.5-0\NisSrv.exe | NisSrv.exe
pool: 0xffff94895e929410 | eprocess: 0xffff94895e929480 | \Windows\System32\smartscreen.exe | smartscreen.ex
pool: 0xffff94895e92a000 | eprocess: 0xffff94895e92a080 | \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe | Code.exe
pool: 0xffff94895e941250 | eprocess: 0xffff94895e9412c0 | \Windows\System32\Windows.WARP.JITService.exe | Windows.WARP.J
pool: 0xffff94895e951230 | eprocess: 0xffff94895e9512c0 | \ProgramData\Microsoft\Windows Defender\Platform\4.18.2005.5-0\MsMpEng.exe | MsMpEng.exe
pool: 0xffff94895e970000 | eprocess: 0xffff94895e970080 | \Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe | SearchUI.exe
pool: 0xffff94895eaaf3b0 | eprocess: 0xffff94895eaaf440 | \Windows\System32\sihost.exe | sihost.exe
pool: 0xffff94895eaee420 | eprocess: 0xffff94895eaee480 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895eaf5430 | eprocess: 0xffff94895eaf54c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895eaf8430 | eprocess: 0xffff94895eaf84c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895eb4f000 | eprocess: 0xffff94895eb4f080 | | svchost.exe
pool: 0xffff94895eb57310 | eprocess: 0xffff94895eb57380 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895eb5b430 | eprocess: 0xffff94895eb5b4c0 | \Windows\System32\taskhostw.exe | taskhostw.exe
pool: 0xffff94895ebbd340 | eprocess: 0xffff94895ebbd3c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895ebc23b0 | eprocess: 0xffff94895ebc2440 | \Windows\System32\ctfmon.exe | ctfmon.exe
pool: 0xffff94895ec48380 | eprocess: 0xffff94895ec48400 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895ec5e000 | eprocess: 0xffff94895ec5e080 | | userinit.exe
pool: 0xffff94895ec62000 | eprocess: 0xffff94895ec62080 | \Windows\explorer.exe | explorer.exe
pool: 0xffff94895ec70000 | eprocess: 0xffff94895ec70080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895ec77000 | eprocess: 0xffff94895ec77080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895ec93430 | eprocess: 0xffff94895ec934c0 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895eccc450 | eprocess: 0xffff94895eccc4c0 | \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe | Code.exe
pool: 0xffff94895ece5000 | eprocess: 0xffff94895ece5080 | \Windows\System32\dllhost.exe | dllhost.exe
pool: 0xffff94895edca000 | eprocess: 0xffff94895edca080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895edda000 | eprocess: 0xffff94895edda080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895edf6000 | eprocess: 0xffff94895edf6080 | \Windows\SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\StartMenuExperienceHost.exe | StartMenuExper
pool: 0xffff94895ef1b420 | eprocess: 0xffff94895ef1b480 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffff94895efb9000 | eprocess: 0xffff94895efb9080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895f089420 | eprocess: 0xffff94895f089480 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffff94895f118420 | eprocess: 0xffff94895f118480 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffff94895f119000 | eprocess: 0xffff94895f119080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895f122310 | eprocess: 0xffff94895f122380 | \Windows\System32\SearchIndexer.exe | SearchIndexer.
pool: 0xffff94895f19e000 | eprocess: 0xffff94895f19e080 | \Windows\System32\Windows.WARP.JITService.exe | Windows.WARP.J
pool: 0xffff94895f202040 | eprocess: 0xffff94895f2020c0 | \Windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe | MicrosoftEdge.
pool: 0xffff94895f207440 | eprocess: 0xffff94895f2074c0 | \Windows\System32\ApplicationFrameHost.exe | ApplicationFra
pool: 0xffff94895f2673c0 | eprocess: 0xffff94895f267440 | \Windows\System32\cmd.exe | cmd.exe
pool: 0xffff94895f2c8000 | eprocess: 0xffff94895f2c8080 | \Windows\System32\SgrmBroker.exe | SgrmBroker.exe
pool: 0xffff94895f2db000 | eprocess: 0xffff94895f2db080 | \Program Files\WindowsApps\Microsoft.SkypeApp_14.56.102.0_x64__kzf8qxf38zg5c\SkypeBackgroundHost.exe | SkypeBackgroun
pool: 0xffff94895f2dd000 | eprocess: 0xffff94895f2dd080 | \Program Files\WindowsApps\Microsoft.SkypeApp_14.56.102.0_x64__kzf8qxf38zg5c\SkypeApp.exe | SkypeApp.exe
pool: 0xffff94895f3be420 | eprocess: 0xffff94895f3be480 | \Windows\System32\browser_broker.exe | browser_broker
pool: 0xffff94895f3c5000 | eprocess: 0xffff94895f3c5080 | \Program Files\WindowsApps\Microsoft.YourPhone_1.20041.91.0_x64__8wekyb3d8bbwe\YourPhone.exe | YourPhone.exe
pool: 0xffff94895f3ce390 | eprocess: 0xffff94895f3ce400 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895f419000 | eprocess: 0xffff94895f419080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895f449000 | eprocess: 0xffff94895f449080 | \Program Files\WindowsApps\Microsoft.WindowsStore_12005.1001.1.0_x64__8wekyb3d8bbwe\WinStore.App.exe | WinStore.App.e
pool: 0xffff94895f44b420 | eprocess: 0xffff94895f44b480 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffff94895f4b1000 | eprocess: 0xffff94895f4b1080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895f4e5000 | eprocess: 0xffff94895f4e5080 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffff94895f4e91d0 | eprocess: 0xffff94895f4e9240 | \Windows\System32\MicrosoftEdgeCP.exe | MicrosoftEdgeC
pool: 0xffff94895f571420 | eprocess: 0xffff94895f571480 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffff94895f588040 | eprocess: 0xffff94895f5880c0 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffff94895f58e000 | eprocess: 0xffff94895f58e080 | \Windows\System32\VBoxTray.exe | VBoxTray.exe
pool: 0xffff94895f5c7000 | eprocess: 0xffff94895f5c7080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff94895f603000 | eprocess: 0xffff94895f603080 | \Windows\System32\MicrosoftEdgeSH.exe | MicrosoftEdgeS
pool: 0xffff94895f7c7000 | eprocess: 0xffff94895f7c7080 | \Users\User\AppData\Local\Microsoft\OneDrive\OneDrive.exe | OneDrive.exe
pool: 0xffff94895f7c8000 | eprocess: 0xffff94895f7c8080 | \Windows\System32\SecurityHealthSystray.exe | SecurityHealth
pool: 0xffff94895f7ca320 | eprocess: 0xffff94895f7ca380 | \Windows\System32\SecurityHealthService.exe | SecurityHealth
pool: 0xffff94895fce6040 | eprocess: 0xffff94895fce60c0 | \Windows\System32\backgroundTaskHost.exe | backgroundTask
pool: 0xffff94895fdd2000 | eprocess: 0xffff94895fdd2080 | \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe | Code.exe
pool: 0xffff94895ffce000 | eprocess: 0xffff94895ffce080 | | MicrosoftEdgeC
pool: 0xffff94895ffe2000 | eprocess: 0xffff94895ffe2080 | \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe | Code.exe
pool: 0xffff94895ffef000 | eprocess: 0xffff94895ffef080 | \Windows\System32\backgroundTaskHost.exe | backgroundTask
pool: 0xffff94895fff2400 | eprocess: 0xffff94895fff2480 | \Windows\System32\conhost.exe | conhost.exe
pool: 0xffff9489600c5040 | eprocess: 0xffff9489600c50c0 | \Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe | Code.exe
pool: 0xffff9489600cf2b0 | eprocess: 0xffff9489600cf340 | \Users\User\Desktop\lpus-0.3-alpha\target\release\eprocess_scan.exe | eprocess_scan.
pool: 0xffff9489602ec000 | eprocess: 0xffff9489602ec080 | \Windows\System32\dllhost.exe | dllhost.exe
pool: 0xffff9489602f0000 | eprocess: 0xffff9489602f0080 | | conhost.exe
pool: 0xffff9489602f5000 | eprocess: 0xffff9489602f5080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff9489603ca000 | eprocess: 0xffff9489603ca080 | \Windows\System32\Windows.WARP.JITService.exe | Windows.WARP.J
pool: 0xffff948960acc000 | eprocess: 0xffff948960acc080 | \Windows\System32\svchost.exe | svchost.exe
pool: 0xffff948960ad3000 | eprocess: 0xffff948960ad3080 | \Windows\System32\RuntimeBroker.exe | RuntimeBroker.
pool: 0xffff9489610de000 | eprocess: 0xffff9489610de080 | \Windows\System32\MicrosoftEdgeCP.exe | MicrosoftEdgeC
NtUnloadDriver() -> 0x0

View File

@ -0,0 +1,29 @@
import re
import csv
vp = re.compile(r'^(0x[0-9a-f]+)\s+(.{15})\s+\d+\s+\d+.*$')
vol = map(lambda x: x.group(1, 2), filter(lambda x: x is not None, map(vp.match, open('eprocess_volscan.txt', 'r').read().split('\n'))))
with open('eprocess_volscan.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['address', 'process'])
for v in vol:
a, b = list(v)
a = hex(int(a, 16) + 0xffff000000000000)
b = b.rstrip(' ')
writer.writerow([a, b])
# lp = re.compile(r'pool: 0x[0-9a-f]+ \| file object: (0x[0-9a-f]+) \| offsetby: 0x[0-9a-f]+\s+(.*)$', re.MULTILINE)
lpus = re.finditer(r'pool: 0x[0-9a-f]+ \| eprocess: (0x[0-9a-f]+) \| ([^|]*) \| (.*)$',
open('eprocess_scan_log.txt', 'r', encoding='utf-8').read(), re.MULTILINE)
with open('eprocess_lpusscan.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['address', 'process', 'fullpath'])
for v in lpus:
a, b, c = list(v.groups())
writer.writerow([a, c, b])

View File

@ -0,0 +1,75 @@
address,process
0xffff948957c67080,VBoxService.ex
0xffff948957c6c080,svchost.exe
0xffff948957caa080,svchost.exe
0xffff948957ce3080,svchost.exe
0xffff948957d1b080,svchost.exe
0xffff948957ddf040,Registry
0xffff94895ac79400,smss.exe
0xffff94895ad15080,powershell.exe
0xffff94895b0452c0,csrss.exe
0xffff94895ba28080,MicrosoftEdgeC
0xffff94895bb25080,MicrosoftEdgeC
0xffff94895bdb0080,winlogon.exe
0xffff94895bdf51c0,services.exe
0xffff94895ca5f280,fontdrvhost.ex
0xffff94895ca6a280,fontdrvhost.ex
0xffff94895ca70380,svchost.exe
0xffff94895caf6400,svchost.exe
0xffff94895cb3a380,svchost.exe
0xffff94895cbd8400,svchost.exe
0xffff94895cc15440,svchost.exe
0xffff94895cc223c0,svchost.exe
0xffff94895cc5b380,svchost.exe
0xffff94895ccae400,svchost.exe
0xffff94895cdac400,svchost.exe
0xffff94895cdae400,svchost.exe
0xffff94895ce19400,svchost.exe
0xffff94895ce1b080,svchost.exe
0xffff94895ce98400,svchost.exe
0xffff94895cea7080,MemCompression
0xffff94895ceb5380,svchost.exe
0xffff94895cf2e3c0,svchost.exe
0xffff94895cf90400,svchost.exe
0xffff94895cf98400,svchost.exe
0xffff94895e017440,svchost.exe
0xffff94895e02b380,svchost.exe
0xffff94895e077400,svchost.exe
0xffff94895e0ce400,svchost.exe
0xffff94895e0d8400,svchost.exe
0xffff94895e169380,svchost.exe
0xffff94895e171080,svchost.exe
0xffff94895e391080,SearchProtocol
0xffff94895e54e4c0,NisSrv.exe
0xffff94895e929480,smartscreen.ex
0xffff94895e9412c0,Windows.WARP.J
0xffff94895e9512c0,MsMpEng.exe
0xffff94895e970080,SearchUI.exe
0xffff94895eaaf440,sihost.exe
0xffff94895eaee480,svchost.exe
0xffff94895eaf54c0,svchost.exe
0xffff94895eaf84c0,svchost.exe
0xffff94895eb5b4c0,taskhostw.exe
0xffff94895ebbd3c0,svchost.exe
0xffff94895ebc2440,ctfmon.exe
0xffff94895ec5e080,userinit.exe
0xffff94895eccc4c0,Code.exe
0xffff94895ece5080,dllhost.exe
0xffff94895edf6080,StartMenuExper
0xffff94895ef1b480,RuntimeBroker.
0xffff94895f2074c0,ApplicationFra
0xffff94895f2dd080,SkypeApp.exe
0xffff94895f3be480,browser_broker
0xffff94895f3c5080,YourPhone.exe
0xffff94895f3ce400,svchost.exe
0xffff94895f449080,WinStore.App.e
0xffff94895f44b480,RuntimeBroker.
0xffff94895f4e9240,MicrosoftEdgeC
0xffff94895f571480,RuntimeBroker.
0xffff94895f7ca380,SecurityHealth
0xffff94895ffce080,MicrosoftEdgeC
0xffff94895fff2480,conhost.exe
0xffff9489600c50c0,Code.exe
0xffff9489602ec080,dllhost.exe
0xffff9489603ca080,Windows.WARP.J
0xffff948960acc080,svchost.exe
1 address process
2 0xffff948957c67080 VBoxService.ex
3 0xffff948957c6c080 svchost.exe
4 0xffff948957caa080 svchost.exe
5 0xffff948957ce3080 svchost.exe
6 0xffff948957d1b080 svchost.exe
7 0xffff948957ddf040 Registry
8 0xffff94895ac79400 smss.exe
9 0xffff94895ad15080 powershell.exe
10 0xffff94895b0452c0 csrss.exe
11 0xffff94895ba28080 MicrosoftEdgeC
12 0xffff94895bb25080 MicrosoftEdgeC
13 0xffff94895bdb0080 winlogon.exe
14 0xffff94895bdf51c0 services.exe
15 0xffff94895ca5f280 fontdrvhost.ex
16 0xffff94895ca6a280 fontdrvhost.ex
17 0xffff94895ca70380 svchost.exe
18 0xffff94895caf6400 svchost.exe
19 0xffff94895cb3a380 svchost.exe
20 0xffff94895cbd8400 svchost.exe
21 0xffff94895cc15440 svchost.exe
22 0xffff94895cc223c0 svchost.exe
23 0xffff94895cc5b380 svchost.exe
24 0xffff94895ccae400 svchost.exe
25 0xffff94895cdac400 svchost.exe
26 0xffff94895cdae400 svchost.exe
27 0xffff94895ce19400 svchost.exe
28 0xffff94895ce1b080 svchost.exe
29 0xffff94895ce98400 svchost.exe
30 0xffff94895cea7080 MemCompression
31 0xffff94895ceb5380 svchost.exe
32 0xffff94895cf2e3c0 svchost.exe
33 0xffff94895cf90400 svchost.exe
34 0xffff94895cf98400 svchost.exe
35 0xffff94895e017440 svchost.exe
36 0xffff94895e02b380 svchost.exe
37 0xffff94895e077400 svchost.exe
38 0xffff94895e0ce400 svchost.exe
39 0xffff94895e0d8400 svchost.exe
40 0xffff94895e169380 svchost.exe
41 0xffff94895e171080 svchost.exe
42 0xffff94895e391080 SearchProtocol
43 0xffff94895e54e4c0 NisSrv.exe
44 0xffff94895e929480 smartscreen.ex
45 0xffff94895e9412c0 Windows.WARP.J
46 0xffff94895e9512c0 MsMpEng.exe
47 0xffff94895e970080 SearchUI.exe
48 0xffff94895eaaf440 sihost.exe
49 0xffff94895eaee480 svchost.exe
50 0xffff94895eaf54c0 svchost.exe
51 0xffff94895eaf84c0 svchost.exe
52 0xffff94895eb5b4c0 taskhostw.exe
53 0xffff94895ebbd3c0 svchost.exe
54 0xffff94895ebc2440 ctfmon.exe
55 0xffff94895ec5e080 userinit.exe
56 0xffff94895eccc4c0 Code.exe
57 0xffff94895ece5080 dllhost.exe
58 0xffff94895edf6080 StartMenuExper
59 0xffff94895ef1b480 RuntimeBroker.
60 0xffff94895f2074c0 ApplicationFra
61 0xffff94895f2dd080 SkypeApp.exe
62 0xffff94895f3be480 browser_broker
63 0xffff94895f3c5080 YourPhone.exe
64 0xffff94895f3ce400 svchost.exe
65 0xffff94895f449080 WinStore.App.e
66 0xffff94895f44b480 RuntimeBroker.
67 0xffff94895f4e9240 MicrosoftEdgeC
68 0xffff94895f571480 RuntimeBroker.
69 0xffff94895f7ca380 SecurityHealth
70 0xffff94895ffce080 MicrosoftEdgeC
71 0xffff94895fff2480 conhost.exe
72 0xffff9489600c50c0 Code.exe
73 0xffff9489602ec080 dllhost.exe
74 0xffff9489603ca080 Windows.WARP.J
75 0xffff948960acc080 svchost.exe

View File

@ -0,0 +1,77 @@
Volatility Foundation Volatility Framework 2.6.1
Offset(P) Name PID PPID PDB Time created Time exited
------------------ ---------------- ------ ------ ------------------ ------------------------------ ------------------------------
0x0000948957c67080 VBoxService.ex 1604 596 0x00000000205e9002 2020-06-04 20:20:35 UTC+0000
0x0000948957c6c080 svchost.exe 6904 596 0x0000000009506002 2020-06-04 06:25:45 UTC+0000 2020-06-04 06:27:55 UTC+0000
0x0000948957caa080 svchost.exe 6448 596 0x000000006a7bc002 2020-06-04 06:21:12 UTC+0000
0x0000948957ce3080 svchost.exe 1508 596 0x000000001ff45002 2020-06-04 20:20:35 UTC+0000
0x0000948957d1b080 svchost.exe 1444 596 0x000000001e3b9002 2020-06-04 20:20:35 UTC+0000
0x0000948957ddf040 Registry 68 4 0x0000000000341002 2020-06-04 20:20:13 UTC+0000
0x000094895ac79400 smss.exe 324 4 0x0000000101742002 2020-06-04 20:20:19 UTC+0000
0x000094895ad15080 powershell.exe 408 1060 0x00000000b5241002 2020-06-04 07:19:20 UTC+0000 2020-06-04 07:20:22 UTC+0000
0x000094895b0452c0 csrss.exe 416 408 0x0000000002e84002 2020-06-04 20:20:33 UTC+0000
0x000094895ba28080 MicrosoftEdgeC 1436 772 0x000000011866b002 2020-06-04 07:16:47 UTC+0000
0x000094895bb25080 MicrosoftEdgeC 2776 772 0x00000000d2641002 2020-06-04 07:16:57 UTC+0000
0x000094895bdb0080 winlogon.exe 544 480 0x0000000001add002 2020-06-04 20:20:33 UTC+0000
0x000094895bdf51c0 services.exe 596 488 0x0000000016c16002 2020-06-04 20:20:33 UTC+0000
0x000094895ca5f280 fontdrvhost.ex 680 544 0x0000000019366002 2020-06-04 20:20:33 UTC+0000
0x000094895ca6a280 fontdrvhost.ex 688 488 0x0000000015d1b002 2020-06-04 20:20:33 UTC+0000
0x000094895ca70380 svchost.exe 708 596 0x0000000017338002 2020-06-04 20:20:33 UTC+0000
0x000094895caf6400 svchost.exe 824 596 0x0000000019ad0002 2020-06-04 20:20:34 UTC+0000
0x000094895cb3a380 svchost.exe 876 596 0x000000001a2b4002 2020-06-04 20:20:34 UTC+0000
0x000094895cbd8400 svchost.exe 384 596 0x000000001950d002 2020-06-04 20:20:34 UTC+0000
0x000094895cc15440 svchost.exe 420 596 0x000000001c315002 2020-06-04 20:20:34 UTC+0000
0x000094895cc223c0 svchost.exe 592 596 0x000000001c549002 2020-06-04 20:20:34 UTC+0000
0x000094895cc5b380 svchost.exe 1064 596 0x000000001d1a4002 2020-06-04 20:20:34 UTC+0000
0x000094895ccae400 svchost.exe 1148 596 0x000000001ddbf002 2020-06-04 20:20:34 UTC+0000
0x000094895cdac400 svchost.exe 1372 596 0x000000001ca24002 2020-06-04 20:20:35 UTC+0000
0x000094895cdae400 svchost.exe 1452 596 0x00000000206dd002 2020-06-04 20:20:35 UTC+0000
0x000094895ce19400 svchost.exe 1632 596 0x0000000023c4f002 2020-06-04 20:20:35 UTC+0000
0x000094895ce1b080 svchost.exe 1640 596 0x0000000022b39002 2020-06-04 20:20:35 UTC+0000
0x000094895ce98400 svchost.exe 1772 596 0x0000000020e71002 2020-06-04 06:20:37 UTC+0000
0x000094895cea7080 MemCompression 1812 4 0x00000000236f8002 2020-06-04 06:20:37 UTC+0000
0x000094895ceb5380 svchost.exe 1868 596 0x0000000025c34002 2020-06-04 06:20:37 UTC+0000
0x000094895cf2e3c0 svchost.exe 1936 596 0x0000000024179002 2020-06-04 06:20:37 UTC+0000
0x000094895cf90400 svchost.exe 1660 596 0x0000000022790002 2020-06-04 06:20:37 UTC+0000
0x000094895cf98400 svchost.exe 1352 596 0x0000000025171002 2020-06-04 06:20:37 UTC+0000
0x000094895e017440 svchost.exe 2088 596 0x0000000021120002 2020-06-04 06:20:38 UTC+0000
0x000094895e02b380 svchost.exe 2128 596 0x0000000027d28002 2020-06-04 06:20:38 UTC+0000
0x000094895e077400 svchost.exe 2160 596 0x0000000025ec9002 2020-06-04 06:20:38 UTC+0000
0x000094895e0ce400 svchost.exe 2208 596 0x00000000260c0002 2020-06-04 06:20:38 UTC+0000
0x000094895e0d8400 svchost.exe 2232 596 0x000000002652a002 2020-06-04 06:20:38 UTC+0000
0x000094895e169380 svchost.exe 2928 596 0x000000002e054002 2020-06-04 06:20:39 UTC+0000
0x000094895e171080 svchost.exe 2684 596 0x000000002ad7c002 2020-06-04 06:20:39 UTC+0000
0x000094895e391080 SearchProtocol 1648 5160 0x000000009b248002 2020-06-04 07:26:11 UTC+0000
0x000094895e54e4c0 NisSrv.exe 2016 596 0x00000000b4eff002 2020-06-04 06:28:41 UTC+0000
0x000094895e929480 smartscreen.ex 3256 772 0x00000000c11d6002 2020-06-04 07:16:27 UTC+0000
0x000094895e9412c0 Windows.WARP.J 5712 5580 0x00000000c0f76002 2020-06-04 07:16:26 UTC+0000
0x000094895e9512c0 MsMpEng.exe 4676 596 0x0000000044f09002 2020-06-04 06:28:33 UTC+0000
0x000094895e970080 SearchUI.exe 4692 772 0x0000000057496002 2020-06-04 06:21:01 UTC+0000
0x000094895eaaf440 sihost.exe 432 1292 0x0000000043c29002 2020-06-04 06:20:50 UTC+0000
0x000094895eaee480 svchost.exe 1588 596 0x0000000043ecd002 2020-06-04 06:20:50 UTC+0000
0x000094895eaf54c0 svchost.exe 3152 596 0x0000000045d46002 2020-06-04 06:20:50 UTC+0000
0x000094895eaf84c0 svchost.exe 3672 596 0x00000000465a3002 2020-06-04 06:20:50 UTC+0000
0x000094895eb5b4c0 taskhostw.exe 4124 1064 0x0000000046bc4002 2020-06-04 06:20:50 UTC+0000
0x000094895ebbd3c0 svchost.exe 4232 596 0x000000004306e002 2020-06-04 06:20:50 UTC+0000
0x000094895ebc2440 ctfmon.exe 4300 4232 0x0000000041c8c002 2020-06-04 06:20:50 UTC+0000
0x000094895ec5e080 userinit.exe 4400 544 0x0000000046ed7002 2020-06-04 06:20:51 UTC+0000 2020-06-04 06:21:20 UTC+0000
0x000094895eccc4c0 Code.exe 6968 3736 0x00000000bb0c4002 2020-06-04 07:19:16 UTC+0000
0x000094895ece5080 dllhost.exe 4648 772 0x00000000502b5002 2020-06-04 06:20:53 UTC+0000
0x000094895edf6080 StartMenuExper 4972 772 0x0000000053638002 2020-06-04 06:21:00 UTC+0000
0x000094895ef1b480 RuntimeBroker. 5092 772 0x0000000056e70002 2020-06-04 06:21:00 UTC+0000
0x000094895f2074c0 ApplicationFra 5336 772 0x000000005c223002 2020-06-04 06:21:04 UTC+0000
0x000094895f2dd080 SkypeApp.exe 5412 772 0x000000005fea5002 2020-06-04 06:21:05 UTC+0000
0x000094895f3be480 browser_broker 5544 772 0x0000000060a28002 2020-06-04 06:21:05 UTC+0000
0x000094895f3c5080 YourPhone.exe 5588 772 0x000000006315e002 2020-06-04 06:21:05 UTC+0000
0x000094895f3ce400 svchost.exe 5580 596 0x0000000063376002 2020-06-04 06:21:05 UTC+0000
0x000094895f449080 WinStore.App.e 5952 772 0x00000001142d1002 2020-06-04 06:22:36 UTC+0000
0x000094895f44b480 RuntimeBroker. 5860 772 0x0000000061748002 2020-06-04 06:21:06 UTC+0000
0x000094895f4e9240 MicrosoftEdgeC 6048 772 0x0000000063ba6002 2020-06-04 06:21:07 UTC+0000
0x000094895f571480 RuntimeBroker. 6908 772 0x000000006dcb1002 2020-06-04 06:21:16 UTC+0000
0x000094895f7ca380 SecurityHealth 2248 596 0x000000006f4ba002 2020-06-04 06:21:21 UTC+0000
0x000094895ffce080 MicrosoftEdgeC 3288 772 0x00000000bd993002 2020-06-04 07:16:41 UTC+0000 2020-06-04 07:19:52 UTC+0000
0x000094895fff2480 conhost.exe 5696 1892 0x0000000058bc3002 2020-06-04 07:19:49 UTC+0000
0x00009489600c50c0 Code.exe 1060 3736 0x000000003859d002 2020-06-04 07:19:17 UTC+0000
0x00009489602ec080 dllhost.exe 4156 772 0x000000009589c002 2020-06-04 07:16:29 UTC+0000
0x00009489603ca080 Windows.WARP.J 7068 5580 0x00000000bb4da002 2020-06-04 07:16:48 UTC+0000
0x0000948960acc080 svchost.exe 3204 596 0x00000000c4173002 2020-06-04 07:19:47 UTC+0000

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
import re
import csv
vp = re.compile(r'(0x[0-9a-f]+)\s+\d+\s+[01]\s+[RWDrwd-]+\s+(.*)')
vol = map(lambda x: x.group(1, 2), filter(lambda x: x is not None, map(vp.match, open('file_volscan.txt', 'r').read().split('\n'))))
with open('file_volscan.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['address', 'file'])
for v in vol:
a, b = list(v)
a = hex(int(a, 16) + 0xffff000000000000)
writer.writerow([a, b])
# lp = re.compile(r'pool: 0x[0-9a-f]+ \| file object: (0x[0-9a-f]+) \| offsetby: 0x[0-9a-f]+\s+(.*)$', re.MULTILINE)
lpus = map(lambda x: x.group(1, 2), filter(lambda x: x is not None, map(vp.match, open('file_volscan.txt', 'r').read().split('\n'))))
lpus = re.finditer(r'pool: 0x[0-9a-f]+ \| file object: (0x[0-9a-f]+) \| offsetby: 0x[0-9a-f]+\s+(.*)$',
open('file_scan_log.txt', 'r', encoding='utf-8').read(), re.MULTILINE)
with open('file_lpusscan.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['address', 'file'])
for v in lpus:
a, b = list(v.groups())
writer.writerow([a, b])

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

50
logs/dump_test/1/stat.py Normal file
View File

@ -0,0 +1,50 @@
import pandas as pd
elpus = pd.read_csv('eprocess_lpusscan.csv')
flpus = pd.read_csv('file_lpusscan.csv', encoding='utf-8')
evol = pd.read_csv('eprocess_volscan.csv')
fvol = pd.read_csv('file_volscan.csv')
print('''
A simple statistics for LPUS and Volatility
Environment: Windows 10 2019 (build number 18362) on VirtualBox
RAM: 4GB
> The VM is downloaded through Microsoft
LPUS scan _EPROCESS and _FILE_OBJECT.
The scan time: approximate 5 minutes.
After that, use VirtualBox command to generate the memory image
> "C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" debugvm "<name>" dumpvmcore --filename "/path/to/<name>.elf"
Volatility version is at 5f685e5
> The latest release of Volatility doesn't have support for Windows build no. 18362
Then compare the log from LPUS and the two volatility command with profile Win10x64_18362:
- psscan to scan _EPROCESS, approximate 30 minutes
- filescan to scan _EPROCESS, approximate 2-3 hours
(The log file is then converted to csv files, see 'eprocess_to_csv.py' and 'file_to_csv.py')
''')
print('==================================================')
print('_EPROCESS')
print('lpus scan: ', elpus['address'].shape, 'results')
print('volatility scan: ', evol['address'].shape, 'results')
print('volatility scan misses lpus: ', elpus['address'][~elpus['address'].isin(evol['address'])].shape, 'results')
print('lpus scan misses volatility: ', evol['address'][~evol['address'].isin(elpus['address'])].shape, 'results')
print('==================================================')
print('_FILE_OBJECT')
print('lpus scan: ', flpus['address'].shape, 'results')
print('volatility scan: ', fvol['address'].shape, 'results')
print('volatility scan misses lpus: ', flpus['address'][~flpus['address'].isin(fvol['address'])].shape, 'results')
print('lpus scan misses volatility: ', fvol['address'][~fvol['address'].isin(flpus['address'])].shape, 'results')

138
logs/eprocess_scan.log Normal file
View File

@ -0,0 +1,138 @@
PDB for Amd64, guid: 8b11040a-5928-757b-1139-0ac78f6b6925, age: 1
NtLoadDriver() -> 0x0
pool: 0xffffe282a0463000 | eprocess: 0xffffe282a0463080 | pid: 1088 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a0465010 | eprocess: 0xffffe282a0465080 | pid: 1032 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a046b160 | eprocess: 0xffffe282a046b1c0 | pid: 4 | ppid: 0 | name: System | path:
pool: 0xffffe282a047e000 | eprocess: 0xffffe282a047e080 | pid: 1080 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a0482260 | eprocess: 0xffffe282a04822c0 | pid: 1812 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a04b6000 | eprocess: 0xffffe282a04b6080 | pid: 1220 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a04ed000 | eprocess: 0xffffe282a04ed080 | pid: 1276 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a050d000 | eprocess: 0xffffe282a050d080 | pid: 1148 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a0511000 | eprocess: 0xffffe282a0511080 | pid: 1156 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a31d04d0 | eprocess: 0xffffe282a31d0540 | pid: 288 | ppid: 4 | name: smss.exe | path: \Windows\System32\smss.exe
pool: 0xffffe282a3cbe1f0 | eprocess: 0xffffe282a3cbe280 | pid: 6736 | ppid: 756 | name: smartscreen.ex | path: \Windows\System32\smartscreen.exe
pool: 0xffffe282a3cd94d0 | eprocess: 0xffffe282a3cd9540 | pid: 4976 | ppid: 4868 | name: Windows.WARP.J | path: \Windows\System32\Windows.WARP.JITService.exe
pool: 0xffffe282a3d45000 | eprocess: 0xffffe282a3d45080 | pid: 808 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a3d4b000 | eprocess: 0xffffe282a3d4b080 | pid: 452 | ppid: 376 | name: wininit.exe | path: \Windows\System32\wininit.exe
pool: 0xffffe282a3d500b0 | eprocess: 0xffffe282a3d50140 | pid: 460 | ppid: 444 | name: csrss.exe | path: \Windows\System32\csrss.exe
pool: 0xffffe282a3d65000 | eprocess: 0xffffe282a3d65080 | pid: 512 | ppid: 444 | name: winlogon.exe | path: \Windows\System32\winlogon.exe
pool: 0xffffe282a3dc90d0 | eprocess: 0xffffe282a3dc9140 | pid: 560 | ppid: 452 | name: services.exe | path: \Windows\System32\services.exe
pool: 0xffffe282a3dd50b0 | eprocess: 0xffffe282a3dd5140 | pid: 584 | ppid: 452 | name: lsass.exe | path: \Windows\System32\lsass.exe
pool: 0xffffe282a3e910b0 | eprocess: 0xffffe282a3e91140 | pid: 384 | ppid: 376 | name: csrss.exe | path: \Windows\System32\csrss.exe
pool: 0xffffe282a3f08260 | eprocess: 0xffffe282a3f082c0 | pid: 4964 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a4c2b2d0 | eprocess: 0xffffe282a4c2b340 | pid: 660 | ppid: 512 | name: fontdrvhost.ex | path: \Windows\System32\fontdrvhost.exe
pool: 0xffffe282a4c2f000 | eprocess: 0xffffe282a4c2f080 | pid: 668 | ppid: 452 | name: fontdrvhost.ex | path: \Windows\System32\fontdrvhost.exe
pool: 0xffffe282a4c76290 | eprocess: 0xffffe282a4c76300 | pid: 684 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a4cd1280 | eprocess: 0xffffe282a4cd1300 | pid: 756 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a4e06290 | eprocess: 0xffffe282a4e06300 | pid: 852 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a4e9a0e0 | eprocess: 0xffffe282a4e9a140 | pid: 928 | ppid: 512 | name: LogonUI.exe | path:
pool: 0xffffe282a4e9c240 | eprocess: 0xffffe282a4e9c2c0 | pid: 936 | ppid: 512 | name: dwm.exe | path: \Windows\System32\dwm.exe
pool: 0xffffe282a4f61290 | eprocess: 0xffffe282a4f61300 | pid: 1008 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a4f68310 | eprocess: 0xffffe282a4f68380 | pid: 1020 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a4f76340 | eprocess: 0xffffe282a4f763c0 | pid: 336 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a4fc62c0 | eprocess: 0xffffe282a4fc6340 | pid: 348 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a60c3340 | eprocess: 0xffffe282a60c33c0 | pid: 376 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a623c000 | eprocess: 0xffffe282a623c080 | pid: 1456 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a623f2b0 | eprocess: 0xffffe282a623f340 | pid: 1300 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a628f320 | eprocess: 0xffffe282a628f380 | pid: 1312 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a62c3270 | eprocess: 0xffffe282a62c3300 | pid: 1372 | ppid: 560 | name: VBoxService.ex | path: \Windows\System32\VBoxService.exe
pool: 0xffffe282a62c62b0 | eprocess: 0xffffe282a62c6340 | pid: 1464 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a62ca290 | eprocess: 0xffffe282a62ca300 | pid: 1484 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a64d6000 | eprocess: 0xffffe282a64d6040 | pid: 1548 | ppid: 4 | name: MemCompression | path:
pool: 0xffffe282a64d9280 | eprocess: 0xffffe282a64d9300 | pid: 1560 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a64dc320 | eprocess: 0xffffe282a64dc380 | pid: 1568 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a65242d0 | eprocess: 0xffffe282a6524340 | pid: 1608 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a653a320 | eprocess: 0xffffe282a653a380 | pid: 1628 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a653f000 | eprocess: 0xffffe282a653f080 | pid: 2108 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6546320 | eprocess: 0xffffe282a6546380 | pid: 1668 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a659c320 | eprocess: 0xffffe282a659c380 | pid: 1772 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a659e000 | eprocess: 0xffffe282a659e080 | pid: 1780 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6652350 | eprocess: 0xffffe282a66523c0 | pid: 1832 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a665d000 | eprocess: 0xffffe282a665d080 | pid: 1388 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a665e000 | eprocess: 0xffffe282a665e080 | pid: 1320 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a666b000 | eprocess: 0xffffe282a666b080 | pid: 2020 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a666c000 | eprocess: 0xffffe282a666c080 | pid: 2012 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a666e000 | eprocess: 0xffffe282a666e080 | pid: 1936 | ppid: 1032 | name: CompatTelRunne | path: \Windows\System32\CompatTelRunner.exe
pool: 0xffffe282a6670000 | eprocess: 0xffffe282a6670080 | pid: 1920 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6673000 | eprocess: 0xffffe282a6673080 | pid: 1900 | ppid: 560 | name: spoolsv.exe | path: \Windows\System32\spoolsv.exe
pool: 0xffffe282a67eb000 | eprocess: 0xffffe282a67eb080 | pid: 2384 | ppid: 560 | name: MsMpEng.exe | path: \ProgramData\Microsoft\Windows Defender\Platform\4.18.2005.5-0\MsMpEng.exe
pool: 0xffffe282a67ec000 | eprocess: 0xffffe282a67ec080 | pid: 2376 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a67ed000 | eprocess: 0xffffe282a67ed080 | pid: 2368 | ppid: 560 | name: ruby.exe | path: \Program Files\Puppet Labs\Puppet\sys\ruby\bin\ruby.exe
pool: 0xffffe282a67f0000 | eprocess: 0xffffe282a67f0080 | pid: 2296 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a67f2000 | eprocess: 0xffffe282a67f2080 | pid: 2272 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a67f4000 | eprocess: 0xffffe282a67f4080 | pid: 2252 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a67f6000 | eprocess: 0xffffe282a67f6080 | pid: 2240 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a67f7000 | eprocess: 0xffffe282a67f7080 | pid: 2220 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6802040 | eprocess: 0xffffe282a68020c0 | pid: 2200 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a694c260 | eprocess: 0xffffe282a694c2c0 | pid: 1896 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a694d000 | eprocess: 0xffffe282a694d080 | pid: 3016 | ppid: 2964 | name: dasHost.exe | path: \Windows\System32\dasHost.exe
pool: 0xffffe282a6950000 | eprocess: 0xffffe282a6950080 | pid: 2964 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6953000 | eprocess: 0xffffe282a6953080 | pid: 2728 | ppid: 560 | name: sppsvc.exe | path: \Windows\System32\sppsvc.exe
pool: 0xffffe282a6956040 | eprocess: 0xffffe282a69560c0 | pid: 2500 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6959000 | eprocess: 0xffffe282a6959080 | pid: 2444 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a695c000 | eprocess: 0xffffe282a695c080 | pid: 2400 | ppid: 560 | name: wlms.exe | path: \Windows\System32\wlms\wlms.exe
pool: 0xffffe282a6d1e450 | eprocess: 0xffffe282a6d1e4c0 | pid: 3316 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6d26000 | eprocess: 0xffffe282a6d26080 | pid: 3256 | ppid: 1032 | name: taskhostw.exe | path: \Windows\System32\taskhostw.exe
pool: 0xffffe282a6d29000 | eprocess: 0xffffe282a6d29080 | pid: 6516 | ppid: 756 | name: RuntimeBroker. | path: \Windows\System32\RuntimeBroker.exe
pool: 0xffffe282a6d2a000 | eprocess: 0xffffe282a6d2a080 | pid: 3172 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6d2b000 | eprocess: 0xffffe282a6d2b080 | pid: 6804 | ppid: 560 | name: SecurityHealth | path: \Windows\System32\SecurityHealthService.exe
pool: 0xffffe282a6d2d000 | eprocess: 0xffffe282a6d2d080 | pid: 3140 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6d2f000 | eprocess: 0xffffe282a6d2f080 | pid: 3108 | ppid: 1148 | name: sihost.exe | path: \Windows\System32\sihost.exe
pool: 0xffffe282a6d30000 | eprocess: 0xffffe282a6d30080 | pid: 4372 | ppid: 756 | name: SearchUI.exe | path: \Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe
pool: 0xffffe282a6d35040 | eprocess: 0xffffe282a6d350c0 | pid: 2192 | ppid: 560 | name: NisSrv.exe | path: \ProgramData\Microsoft\Windows Defender\Platform\4.18.2005.5-0\NisSrv.exe
pool: 0xffffe282a6ece000 | eprocess: 0xffffe282a6ece080 | pid: 4016 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6ed0000 | eprocess: 0xffffe282a6ed0080 | pid: 3892 | ppid: 3788 | name: explorer.exe | path: \Windows\explorer.exe
pool: 0xffffe282a6ed1000 | eprocess: 0xffffe282a6ed1080 | pid: 3224 | ppid: 3892 | name: OneDrive.exe | path: \Users\IEUser\AppData\Local\Microsoft\OneDrive\OneDrive.exe
pool: 0xffffe282a6ed3000 | eprocess: 0xffffe282a6ed3080 | pid: 3808 | ppid: 1936 | name: conhost.exe | path: \Windows\System32\conhost.exe
pool: 0xffffe282a6ed4000 | eprocess: 0xffffe282a6ed4080 | pid: 6296 | ppid: 5824 | name: SearchProtocol | path: \Windows\System32\SearchProtocolHost.exe
pool: 0xffffe282a6ed5000 | eprocess: 0xffffe282a6ed5080 | pid: 3788 | ppid: 512 | name: userinit.exe | path:
pool: 0xffffe282a6ed7000 | eprocess: 0xffffe282a6ed7080 | pid: 3752 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6ed9000 | eprocess: 0xffffe282a6ed9080 | pid: 3656 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6edc040 | eprocess: 0xffffe282a6edc0c0 | pid: 3548 | ppid: 3460 | name: ctfmon.exe | path: \Windows\System32\ctfmon.exe
pool: 0xffffe282a6edf000 | eprocess: 0xffffe282a6edf080 | pid: 3468 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a6ee0000 | eprocess: 0xffffe282a6ee0080 | pid: 3460 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a722d310 | eprocess: 0xffffe282a722d380 | pid: 5068 | ppid: 756 | name: backgroundTask | path: \Windows\System32\backgroundTaskHost.exe
pool: 0xffffe282a724f000 | eprocess: 0xffffe282a724f080 | pid: 4256 | ppid: 756 | name: ShellExperienc | path: \Windows\SystemApps\ShellExperienceHost_cw5n1h2txyewy\ShellExperienceHost.exe
pool: 0xffffe282a72f02d0 | eprocess: 0xffffe282a72f0340 | pid: 6612 | ppid: 756 | name: RuntimeBroker. | path: \Windows\System32\RuntimeBroker.exe
pool: 0xffffe282a7437370 | eprocess: 0xffffe282a7437400 | pid: 4548 | ppid: 756 | name: RuntimeBroker. | path: \Windows\System32\RuntimeBroker.exe
pool: 0xffffe282a74bc000 | eprocess: 0xffffe282a74bc080 | pid: 6012 | ppid: 756 | name: RuntimeBroker. | path: \Windows\System32\RuntimeBroker.exe
pool: 0xffffe282a74cf000 | eprocess: 0xffffe282a74cf080 | pid: 7592 | ppid: 7584 | name: conhost.exe | path: \Windows\System32\conhost.exe
pool: 0xffffe282a74f43a0 | eprocess: 0xffffe282a74f4400 | pid: 4632 | ppid: 756 | name: ApplicationFra | path: \Windows\System32\ApplicationFrameHost.exe
pool: 0xffffe282a75484d0 | eprocess: 0xffffe282a7548540 | pid: 6776 | ppid: 3892 | name: SecurityHealth | path: \Windows\System32\SecurityHealthSystray.exe
pool: 0xffffe282a7564040 | eprocess: 0xffffe282a75640c0 | pid: 4668 | ppid: 756 | name: MicrosoftEdge. | path: \Windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe
pool: 0xffffe282a75a2000 | eprocess: 0xffffe282a75a2080 | pid: 5636 | ppid: 756 | name: LockApp.exe | path: \Windows\SystemApps\Microsoft.LockApp_cw5n1h2txyewy\LockApp.exe
pool: 0xffffe282a768a320 | eprocess: 0xffffe282a768a380 | pid: 4868 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a768f380 | eprocess: 0xffffe282a768f400 | pid: 4876 | ppid: 756 | name: browser_broker | path: \Windows\System32\browser_broker.exe
pool: 0xffffe282a7724040 | eprocess: 0xffffe282a77240c0 | pid: 1604 | ppid: 756 | name: backgroundTask | path: \Windows\System32\backgroundTaskHost.exe
pool: 0xffffe282a7740290 | eprocess: 0xffffe282a7740300 | pid: 3364 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a778f040 | eprocess: 0xffffe282a778f0c0 | pid: 736 | ppid: 756 | name: YourPhone.exe | path: \Program Files\WindowsApps\Microsoft.YourPhone_1.20051.93.0_x64__8wekyb3d8bbwe\YourPhone.exe
pool: 0xffffe282a77e1370 | eprocess: 0xffffe282a77e1400 | pid: 4128 | ppid: 756 | name: RuntimeBroker. | path: \Windows\System32\RuntimeBroker.exe
pool: 0xffffe282a7813040 | eprocess: 0xffffe282a78130c0 | pid: 5204 | ppid: 756 | name: SkypeBackgroun | path: \Program Files\WindowsApps\Microsoft.SkypeApp_14.56.102.0_x64__kzf8qxf38zg5c\SkypeBackgroundHost.exe
pool: 0xffffe282a78171d0 | eprocess: 0xffffe282a7817240 | pid: 5260 | ppid: 756 | name: SkypeApp.exe | path: \Program Files\WindowsApps\Microsoft.SkypeApp_14.56.102.0_x64__kzf8qxf38zg5c\SkypeApp.exe
pool: 0xffffe282a781b1d0 | eprocess: 0xffffe282a781b240 | pid: 5284 | ppid: 756 | name: MicrosoftEdgeC | path: \Windows\System32\MicrosoftEdgeCP.exe
pool: 0xffffe282a78a4040 | eprocess: 0xffffe282a78a40c0 | pid: 5384 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a78b3000 | eprocess: 0xffffe282a78b3080 | pid: 5432 | ppid: 4128 | name: MicrosoftEdgeS | path: \Windows\System32\MicrosoftEdgeSH.exe
pool: 0xffffe282a78bb290 | eprocess: 0xffffe282a78bb300 | pid: 5504 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a79f1000 | eprocess: 0xffffe282a79f1080 | pid: 5756 | ppid: 756 | name: backgroundTask | path: \Windows\System32\backgroundTaskHost.exe
pool: 0xffffe282a7a1c370 | eprocess: 0xffffe282a7a1c400 | pid: 5704 | ppid: 756 | name: RuntimeBroker. | path: \Windows\System32\RuntimeBroker.exe
pool: 0xffffe282a7a44290 | eprocess: 0xffffe282a7a44300 | pid: 5824 | ppid: 560 | name: SearchIndexer. | path: \Windows\System32\SearchIndexer.exe
pool: 0xffffe282a7a90320 | eprocess: 0xffffe282a7a90380 | pid: 5904 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a7b02040 | eprocess: 0xffffe282a7b020c0 | pid: 7900 | ppid: 7584 | name: eprocess_scan. | path: \Users\IEUser\Downloads\eprocess_scan.exe
pool: 0xffffe282a7b03000 | eprocess: 0xffffe282a7b03080 | pid: 6820 | ppid: 2368 | name: cmd.exe | path:
pool: 0xffffe282a7b0e000 | eprocess: 0xffffe282a7b0e080 | pid: 6164 | ppid: 756 | name: RuntimeBroker. | path: \Windows\System32\RuntimeBroker.exe
pool: 0xffffe282a7b20430 | eprocess: 0xffffe282a7b204c0 | pid: 5936 | ppid: 756 | name: RuntimeBroker. | path: \Windows\System32\RuntimeBroker.exe
pool: 0xffffe282a7b4a000 | eprocess: 0xffffe282a7b4a080 | pid: 6860 | ppid: 756 | name: RuntimeBroker. | path: \Windows\System32\RuntimeBroker.exe
pool: 0xffffe282a7ba32c0 | eprocess: 0xffffe282a7ba3340 | pid: 6232 | ppid: 756 | name: WmiPrvSE.exe | path: \Windows\System32\wbem\WmiPrvSE.exe
pool: 0xffffe282a7cea000 | eprocess: 0xffffe282a7cea080 | pid: 6456 | ppid: 5824 | name: SearchFilterHo | path: \Windows\System32\SearchFilterHost.exe
pool: 0xffffe282a7e7f000 | eprocess: 0xffffe282a7e7f080 | pid: 7028 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a7e843a0 | eprocess: 0xffffe282a7e84400 | pid: 7000 | ppid: 3892 | name: VBoxTray.exe | path: \Windows\System32\VBoxTray.exe
pool: 0xffffe282a7ed23c0 | eprocess: 0xffffe282a7ed2440 | pid: 7104 | ppid: 756 | name: dllhost.exe | path: \Windows\System32\dllhost.exe
pool: 0xffffe282a7ed8000 | eprocess: 0xffffe282a7ed8080 | pid: 5672 | ppid: 6820 | name: ruby.exe | path:
pool: 0xffffe282a7f15000 | eprocess: 0xffffe282a7f15080 | pid: 7656 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a7f16000 | eprocess: 0xffffe282a7f16080 | pid: 6392 | ppid: 756 | name: WindowsInterna | path: \Windows\SystemApps\InputApp_cw5n1h2txyewy\WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.exe
pool: 0xffffe282a80f12b0 | eprocess: 0xffffe282a80f1340 | pid: 6904 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a811a340 | eprocess: 0xffffe282a811a3c0 | pid: 7184 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a81cd290 | eprocess: 0xffffe282a81cd300 | pid: 7288 | ppid: 560 | name: svchost.exe | path: \Windows\System32\svchost.exe
pool: 0xffffe282a81ce000 | eprocess: 0xffffe282a81ce080 | pid: 7584 | ppid: 3892 | name: cmd.exe | path: \Windows\System32\cmd.exe
NtUnloadDriver() -> 0x0

7
other/to_epoch.py Normal file
View File

@ -0,0 +1,7 @@
windows_epoch_diff = 11644473600000 * 10000
filetime = 132380977838542980
process_time_epoch = (filetime - windows_epoch_diff) // 10000
print(process_time_epoch)

177
src/address.rs Normal file
View File

@ -0,0 +1,177 @@
use std::cmp::Ordering;
use std::fmt;
use std::ops::{Add, AddAssign, Sub, SubAssign};
use std::rc::Rc;
// pub struct Object {
// name: String,
// address: Address
// }
//
// impl Object {
// pub fn get<F>(&self, resolver: &F) -> u64
// where F: Fn(u64) -> u64 {
// // this function returns address of Object
// self.address.get(resolver)
// }
// }
pub struct Address {
base: u64,
pointer: Option<Rc<Address>>,
offset: u64,
// TODO: resolver
// It would be nice to have an address resolver
// Then implement Deref trait to call get()
// resolver uses DriverState address decompose
// lifetime issue occur
}
impl Address {
pub fn from_base(base: u64) -> Self {
Address {
base: base,
pointer: None,
offset: 0,
}
}
pub fn from_ptr(pointer: Address) -> Self {
Address {
base: 0,
pointer: Some(Rc::new(pointer)),
offset: 0,
}
}
fn deref<F>(&self, resolver: &F) -> Address
where
F: Fn(u64) -> u64,
{
match &self.pointer {
Some(p) => {
let addr = p.deref(resolver);
// println!("deref: {} -> {}; resolve: 0x{:x}", self, addr, addr.base + addr.offset);
let base = if addr.base != 0 {
resolver(addr.base + addr.offset)
} else {
0
};
Address {
base: base,
pointer: None,
offset: self.offset,
}
}
None => Address {
base: self.base,
pointer: None,
offset: self.offset,
},
}
}
pub fn get<F>(&self, resolver: &F) -> u64
where
F: Fn(u64) -> u64,
{
if self.pointer.is_some() {
self.deref(resolver).get(resolver)
} else if self.base == 0 {
0
} else {
self.base + self.offset
}
}
pub fn address(&self) -> u64 {
self.base + self.offset
}
// pub fn to(&self, name: &str) -> Object {
// Object {
// name: name.to_string(),
// address: self.clone()
// }
// }
}
impl Add<u64> for Address {
type Output = Self;
fn add(self, other: u64) -> Self {
Self {
base: self.base,
pointer: self.pointer.map(|p| Rc::clone(&p)),
offset: self.offset + other,
}
}
}
impl AddAssign<u64> for Address {
fn add_assign(&mut self, other: u64) {
*self = Self {
base: self.base,
pointer: self.pointer.clone(),
offset: self.offset + other,
}
}
}
impl Sub<u64> for Address {
type Output = Self;
fn sub(self, other: u64) -> Self {
Self {
base: self.base,
pointer: self.pointer.map(|p| Rc::clone(&p)),
offset: self.offset - other,
}
}
}
impl SubAssign<u64> for Address {
fn sub_assign(&mut self, other: u64) {
*self = Self {
base: self.base,
pointer: self.pointer.clone(),
offset: self.offset - other,
}
}
}
impl PartialEq for Address {
fn eq(&self, other: &Self) -> bool {
self.pointer.is_none()
&& other.pointer.is_none()
&& self.base == other.base
&& self.offset == other.offset
}
}
impl PartialOrd for Address {
fn partial_cmp(&self, other: &Address) -> Option<Ordering> {
if self.pointer.is_some() || other.pointer.is_some() {
None
} else {
let this = self.base + self.offset;
let that = other.base + other.offset;
Some(this.cmp(&that))
}
}
}
impl fmt::Display for Address {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(p) = &self.pointer {
write!(f, "*({}) + 0x{:x}", *p, self.offset)
} else if self.offset != 0 {
write!(f, "0x{:x} + 0x{:x}", self.base, self.offset)
} else {
write!(f, "0x{:x}", self.base)
}
}
}
impl Clone for Address {
fn clone(&self) -> Self {
Address {
base: self.base,
pointer: self.pointer.clone(),
offset: self.offset,
}
}
}

82
src/bin/driver_irp.rs Normal file
View File

@ -0,0 +1,82 @@
use std::error::Error;
use parse_int::parse;
use rustyline::error::ReadlineError;
use rustyline::Editor;
use lpus::{driver_state::DriverState, get_irp_name, scan_driver, scan_kernel_module};
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
if !driver.is_supported() {
return Err(format!(
"Windows version {:?} is not supported",
driver.windows_ffi.short_version
)
.into());
}
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
let drivers = scan_driver(&driver).unwrap_or(Vec::new());
let kmods = scan_kernel_module(&driver).unwrap_or(Vec::new());
for d in drivers.iter() {
println!("{} {}", d["address"], d["device"]);
}
let mut rl = Editor::<()>::new();
loop {
let readline = rl.readline("irp> ");
match readline {
Ok(line) => {
rl.add_history_entry(line.as_str());
for d in drivers.iter() {
if d["address"].as_str().unwrap_or("") == line {
println!("{:#}", d);
for (idx, addr_) in d["major_function"]
.as_array()
.unwrap_or(&Vec::new())
.iter()
.enumerate()
{
let addr: u64 = addr_.as_str().and_then(|x| parse(x).ok()).unwrap_or(0);
let mut owner = "(??)";
println!("{} {}", addr, get_irp_name(idx));
for kmod in kmods.iter() {
let base: u64 = kmod["dllbase"]
.as_str()
.and_then(|x| parse(x).ok())
.unwrap_or(0);
let size: u64 = kmod["size"]
.as_str()
.and_then(|x| parse(x).ok())
.unwrap_or(0);
if addr > base && addr < base + size {
owner = kmod["BaseName"].as_str().unwrap_or("(??)");
break;
}
}
println!("\towned by {}", owner);
}
break;
}
}
}
Err(ReadlineError::Interrupted) => {
println!("CTRL-C");
break;
}
Err(ReadlineError::Eof) => {
println!("CTRL-D");
break;
}
Err(err) => {
println!("Error: {:?}", err);
break;
}
}
}
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

24
src/bin/driver_scan.rs Normal file
View File

@ -0,0 +1,24 @@
use std::error::Error;
use lpus::{driver_state::DriverState, scan_driver};
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
if !driver.is_supported() {
return Err(format!(
"Windows version {:?} is not supported",
driver.windows_ffi.short_version
)
.into());
}
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
let result = scan_driver(&driver).unwrap_or(Vec::new());
for r in result.iter() {
println!("{:#}", r.to_string());
}
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

View File

@ -1,91 +1,104 @@
use serde_json::Value;
use std::collections::HashSet;
use std::error::Error;
use std::str::{from_utf8};
use chrono::Utc;
use chrono::{DateTime};
use std::time::{UNIX_EPOCH, Duration};
#[macro_use]
extern crate prettytable;
use prettytable::Table;
use lpus::{
driver_state::{DriverState /* , EprocessPoolChunk */}
driver_state::DriverState, scan_eprocess, scan_ethread, traverse_activehead,
traverse_handletable, traverse_kiprocesslist,
};
#[allow(dead_code)]
fn to_str_time(time_ms: u64) -> String {
if time_ms == 0 {
return "".to_string();
fn process_in_list(addr: &str, list: &Vec<Value>) -> bool {
for r in list.iter() {
if r["address"].as_str().unwrap() == addr {
return true;
}
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
}
false
}
fn main() -> Result<(), Box<dyn Error>> {
// for windows admin require
// https://github.com/nabijaczleweli/rust-embed-resource
fn get_from_list(addr: &str, list: &Vec<Value>) -> Option<Value> {
for r in list.iter() {
if r["address"].as_str().unwrap() == addr {
return Some(r.clone());
}
}
None
}
fn process_in_list_thread(addr: &str, list: &Vec<Value>) -> bool {
for r in list.iter() {
if r["eprocess"].as_str().unwrap() == addr {
return true;
}
}
false
}
// fn get_process_from_list(addr: String, list: &Vec<Value>) -> String { }
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
if !driver.is_supported() {
return Err(format!(
"Windows version {:?} is not supported",
driver.windows_ffi.short_version
)
.into());
}
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 process_scan = scan_eprocess(&driver).unwrap_or(Vec::new());
let thread_scan = scan_ethread(&driver).unwrap_or(Vec::new());
let activehead = traverse_activehead(&driver).unwrap_or(Vec::new());
let kiprocesslist = traverse_kiprocesslist(&driver).unwrap_or(Vec::new());
let handletable = traverse_handletable(&driver).unwrap_or(Vec::new());
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;
let mut unique_process = HashSet::new();
for list in [&process_scan, &activehead, &kiprocesslist, &handletable].iter() {
for r in list.iter() {
let addr = r["address"].as_str().unwrap();
unique_process.insert(addr);
}
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);
let mut table = Table::new();
table.add_row(row![
"Address",
"Name",
"pid",
"ppid",
"PoolTagScan",
"ActiveProcessHead",
"KiProcessListHead",
"HandleTableList",
"ThreadScan"
]);
for p in &unique_process {
let addr = p.to_string();
let v = get_from_list(&addr, &activehead).unwrap_or_default();
table.add_row(row![
&addr,
v["name"].as_str().unwrap_or("(??)"),
v["pid"].as_i64().unwrap_or(-1),
v["ppid"].as_i64().unwrap_or(-1),
process_in_list(&addr, &process_scan),
process_in_list(&addr, &activehead),
process_in_list(&addr, &kiprocesslist),
process_in_list(&addr, &handletable),
process_in_list_thread(&addr, &thread_scan)
]);
}
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)
// });
})?;
table.printstd();
// for r in process_scan.iter() {
// println!("{:#}", r.to_string());
// }
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

View File

@ -0,0 +1,36 @@
use std::error::Error;
use lpus::{
driver_state::DriverState, traverse_activehead, traverse_handletable, traverse_kiprocesslist,
};
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
if !driver.is_supported() {
return Err(format!(
"Windows version {:?} is not supported",
driver.windows_ffi.short_version
)
.into());
}
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
let activehead = traverse_activehead(&driver).unwrap_or(Vec::new());
let kiprocesslist = traverse_kiprocesslist(&driver).unwrap_or(Vec::new());
let handletable = traverse_handletable(&driver).unwrap_or(Vec::new());
for r in activehead.iter() {
println!("{:#}", r.to_string());
}
println!("=========================================");
for r in kiprocesslist.iter() {
println!("{:#}", r.to_string());
}
println!("=========================================");
for r in handletable.iter() {
println!("{:#}", r.to_string());
}
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

28
src/bin/ethread_scan.rs Normal file
View File

@ -0,0 +1,28 @@
use std::error::Error;
use lpus::{driver_state::DriverState, scan_ethread /* scan_mutant */};
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
if !driver.is_supported() {
return Err(format!(
"Windows version {:?} is not supported",
driver.windows_ffi.short_version
)
.into());
}
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
let threads = scan_ethread(&driver).unwrap_or(Vec::new());
// let mutants = scan_mutant(&driver).unwrap_or(Vec::new());
for r in threads.iter() {
println!("{:#}", r.to_string());
}
// for r in mutants.iter() {
// println!("{:#}", r.to_string());
// }
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

View File

@ -1,56 +1,24 @@
use std::error::Error;
use lpus::{
driver_state::{DriverState}
};
use lpus::{driver_state::DriverState, scan_file};
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
if !driver.is_supported() {
return Err(format!(
"Windows version {:?} is not supported",
driver.windows_ffi.short_version
)
.into());
}
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 result = scan_file(&driver).unwrap_or(Vec::new());
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;
for r in result.iter() {
println!("{:#}", r.to_string());
}
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(())
}

View File

@ -0,0 +1,24 @@
use std::error::Error;
use lpus::{driver_state::DriverState, scan_kernel_module};
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
if !driver.is_supported() {
return Err(format!(
"Windows version {:?} is not supported",
driver.windows_ffi.short_version
)
.into());
}
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
let result = scan_kernel_module(&driver).unwrap_or(Vec::new());
for r in result.iter() {
println!("{:#}", r.to_string());
}
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

View File

@ -0,0 +1,78 @@
use std::error::Error;
use parse_int::parse;
use lpus::{
driver_state::DriverState, ssdt_table, traverse_loadedmodulelist, traverse_unloadeddrivers,
};
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
if !driver.is_supported() {
return Err(format!(
"Windows version {:?} is not supported",
driver.windows_ffi.short_version
)
.into());
}
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
let loaded = traverse_loadedmodulelist(&driver).unwrap_or(Vec::new());
let unloaded = traverse_unloadeddrivers(&driver).unwrap_or(Vec::new());
let ssdt = ssdt_table(&driver)?;
let ntosbase = driver.get_kernel_base();
// for r in loaded.iter() {
// println!("{:#}", r.to_string());
// }
println!("=============================================");
for r in unloaded.iter() {
println!("{:#}", r);
}
println!("=============================================");
for (idx, func) in ssdt.iter().enumerate() {
println!("SSDT [{}]\t0x{:x}", idx, func);
let owner = loaded.iter().find_map(|r| {
let base = r["dllbase"]
.as_str()
.and_then(|b| parse::<u64>(b).ok())
.unwrap_or(0);
let size = r["size"]
.as_str()
.and_then(|s| parse::<u64>(s).ok())
.unwrap_or(0);
if *func > base && *func < base + size {
let module = r["BaseName"].as_str().unwrap();
Some(module)
} else {
None
}
});
if owner == Some("ntoskrnl.exe") {
let offset = func - ntosbase.address();
let funcname: String = {
driver
.pdb_store
.symbols
.iter()
.find_map(|(name, o)| {
if o.clone() == offset {
Some(name.clone())
} else {
None
}
})
.unwrap_or("(??)".to_string())
};
println!("\towned by nt!{}", funcname);
} else if let Some(owner_) = owner {
println!("\\thooked by {}", owner_);
} else {
println!("\tmissing owner");
}
}
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

143
src/bin/lpus.rs Normal file
View File

@ -0,0 +1,143 @@
use serde_json::json;
use std::error::Error;
use std::fs;
use std::io::Write;
extern crate clap;
extern crate prettytable;
use app_dirs::{app_dir, AppDataType};
use clap::{App, Arg, SubCommand};
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "resource"]
struct Asset;
use lpus::{
commands::{driverscan, modscan, psxview, ssdt, unloadedmodules},
driver_state::DriverState,
APP_INFO,
};
fn extract_driver() {
let driver_bytes = Asset::get("lpus.sys").unwrap();
let mut driver_location =
app_dir(AppDataType::UserData, &APP_INFO, &format!("driver")).unwrap();
driver_location.push("lpus.sys");
println!("driver location: {:?}", driver_location);
if let Ok(mut f) = fs::File::create(driver_location) {
f.write_all(&driver_bytes).unwrap();
}
}
fn main() -> Result<(), Box<dyn Error>> {
let version = format!(
"{}-{} commit on {}",
env!("VERGEN_SEMVER"),
env!("VERGEN_SHA_SHORT"),
env!("VERGEN_COMMIT_DATE")
);
let matches = App::new("LPUS")
.version(&*version)
.author("Khoa Nguyen Anh <mail.nganhkhoa@gmail.com>")
.about("Live memory fornesics on Windows")
.arg(
Arg::with_name("load")
.short("l")
.help("Load the driver and exit"),
)
.arg(
Arg::with_name("unload")
.short("u")
.help("Unload the driver and exit"),
)
.subcommand(
SubCommand::with_name("repl").about("Run the Interactive REPL (in development)"),
)
.subcommand(SubCommand::with_name("pdb").about("Inspect the PDB file"))
.subcommand(
SubCommand::with_name("hide_notepad")
.about("Compare processes found from multiple commands"),
)
.subcommand(
SubCommand::with_name("psxview")
.about("Compare processes found from multiple commands"),
)
.subcommand(
SubCommand::with_name("unloadedmodules")
.about("Compare processes found from multiple commands"),
)
.subcommand(
SubCommand::with_name("modscan")
.about("Compare processes found from multiple commands"),
)
.subcommand(
SubCommand::with_name("driverscan")
.about("Compare processes found from multiple commands"),
)
.subcommand(
SubCommand::with_name("ssdt")
.about("Dump the SSDT table")
.arg(
Arg::with_name("hook")
.short("h")
.help("print only hooked function"),
),
)
.get_matches();
extract_driver();
let mut driver = DriverState::new();
if !driver.is_supported() {
return Err(format!(
"Windows version {:?} is not supported",
driver.windows_ffi.short_version
)
.into());
}
if matches.is_present("load") {
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
return Ok(());
}
if matches.is_present("unload") {
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
return Ok(());
}
driver.connect();
if let Some(_c) = matches.subcommand_matches("hide_notepad") {
driver.hide_notepad();
return Ok(());
}
if let Some(c) = matches.subcommand_matches("ssdt") {
ssdt(&driver, c.is_present("hook"));
return Ok(());
}
if let Some(_c) = matches.subcommand_matches("psxview") {
psxview(&driver);
return Ok(());
}
if let Some(_c) = matches.subcommand_matches("unloadedmodules") {
unloadedmodules(&driver);
return Ok(());
}
if let Some(_c) = matches.subcommand_matches("driverscan") {
driverscan(&driver);
return Ok(());
}
if let Some(_c) = matches.subcommand_matches("modscan") {
modscan(&driver);
return Ok(());
}
Ok(())
}

53
src/bin/lpus_all.rs Normal file
View File

@ -0,0 +1,53 @@
use serde_json::json;
use std::error::Error;
use std::fs;
use lpus::{
driver_state::DriverState, scan_driver, scan_eprocess, scan_ethread, scan_kernel_module,
ssdt_table, traverse_activehead, traverse_handletable, traverse_kiprocesslist,
traverse_loadedmodulelist, traverse_unloadeddrivers,
};
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
if !driver.is_supported() {
return Err(format!(
"Windows version {:?} is not supported",
driver.windows_ffi.short_version
)
.into());
}
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
let eprocess_1 = scan_eprocess(&driver)?;
let eprocess_2 = traverse_activehead(&driver)?;
let eprocess_3 = traverse_kiprocesslist(&driver)?;
let eprocess_4 = traverse_handletable(&driver)?;
let ethread = scan_ethread(&driver)?;
let drivers = scan_driver(&driver)?;
let kernel_module_1 = scan_kernel_module(&driver)?;
let kernel_module_2 = traverse_loadedmodulelist(&driver)?;
let unloaded_driver = traverse_unloadeddrivers(&driver)?;
let ssdt: Vec<String> = ssdt_table(&driver)?
.into_iter()
.map(|x| format!("0x{:x}", x))
.collect();
let result = json!({
"scan_eprocess": eprocess_1,
"traverse_activehead": eprocess_2,
"traverse_kiprocesslist": eprocess_3,
"traverse_handletable": eprocess_4,
"scan_ethread": ethread,
"scan_driver": drivers,
"scan_kernel_module": kernel_module_1,
"traverse_loadedmodulelist": kernel_module_2,
"traverse_unloadeddrivers": unloaded_driver,
"ssdt_table": ssdt
});
fs::write("./lpus.json", format!("{:#}", result)).ok();
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

View File

@ -1,12 +1,61 @@
use std::error::Error;
// use std::time::{SystemTime, UNIX_EPOCH};
use lpus::{
driver_state::{DriverState}
};
use rustyline::error::ReadlineError;
use rustyline::Editor;
use lpus::driver_state::DriverState;
pub fn to_epoch(filetime: u64) -> u64 {
// https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/
let windows_epoch_diff = 11644473600000 * 10000;
if filetime < windows_epoch_diff {
return 0;
}
let process_time_epoch = (filetime - windows_epoch_diff) / 10000;
// let now_ms = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_millis() as u64;
process_time_epoch
}
fn main() -> Result<(), Box<dyn Error>> {
let driver = DriverState::new();
driver.windows_ffi.print_version();
driver.pdb_store.print_default_information();
println!("{}", to_epoch(0xfffffa80018cb688));
println!("{}", to_epoch(0x01d64ecd8b295318));
let mut rl = Editor::<()>::new();
if rl.load_history("history.lpus").is_err() {
println!("No previous history.");
}
loop {
let readline = rl.readline(">> ");
match readline {
Ok(line) => {
rl.add_history_entry(line.as_str());
println!("Line: {}", line);
// TODO: add parser here
if let Err(e) = driver.pdb_store.dt(&line) {
println!("{}", e);
}
}
Err(ReadlineError::Interrupted) => {
println!("CTRL-C");
break;
}
Err(ReadlineError::Eof) => {
println!("CTRL-D");
break;
}
Err(err) => {
println!("Error: {:?}", err);
break;
}
}
}
rl.save_history("history.lpus").unwrap();
Ok(())
}

11
src/bin/test_load.rs Normal file
View File

@ -0,0 +1,11 @@
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());
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
Ok(())
}

190
src/commands.rs Normal file
View File

@ -0,0 +1,190 @@
use serde_json::Value;
use std::collections::HashSet;
use std::error::Error;
use prettytable::{cell, row, Table};
use parse_int::parse;
use crate::{
driver_state::DriverState, scan_driver, scan_eprocess, scan_ethread, scan_kernel_module,
ssdt_table, traverse_activehead, traverse_handletable, traverse_kiprocesslist,
traverse_loadedmodulelist, traverse_unloadeddrivers,
};
pub fn ssdt(driver: &DriverState, only_hooked: bool) {
let loaded = traverse_loadedmodulelist(&driver).unwrap_or(Vec::new());
let ssdt = ssdt_table(&driver).unwrap_or(Vec::new());
let ntosbase = driver.get_kernel_base();
for (idx, func) in ssdt.iter().enumerate() {
let owner = loaded.iter().find_map(|r| {
let base = r["dllbase"]
.as_str()
.and_then(|b| parse::<u64>(b).ok())
.unwrap_or(0);
let size = r["size"]
.as_str()
.and_then(|s| parse::<u64>(s).ok())
.unwrap_or(0);
if *func > base && *func < base + size {
let module = r["BaseName"].as_str().unwrap();
Some(module)
} else {
None
}
});
if owner == Some("ntoskrnl.exe") {
if !only_hooked {
let offset = func - ntosbase.address();
let funcname: String = {
driver
.pdb_store
.symbols
.iter()
.find_map(|(name, o)| {
if o.clone() == offset {
Some(name.clone())
} else {
None
}
})
.unwrap_or("(??)".to_string())
};
println!("SSDT [{}]\t0x{:x}", idx, func);
println!("\towned by nt!{}", funcname);
}
} else if let Some(owner_) = owner {
println!("SSDT [{}]\t0x{:x}", idx, func);
println!("\\thooked by {}", owner_);
} else {
println!("SSDT [{}]\t0x{:x}", idx, func);
println!("\tmissing owner");
}
}
}
pub fn psxview(driver: &DriverState) {
fn process_in_list(addr: &str, list: &Vec<Value>) -> bool {
for r in list.iter() {
if r["address"].as_str().unwrap() == addr {
return true;
}
}
false
}
fn get_from_list(addr: &str, list: &Vec<Value>) -> Option<Value> {
for r in list.iter() {
if r["address"].as_str().unwrap() == addr {
return Some(r.clone());
}
}
None
}
fn process_in_list_thread(addr: &str, list: &Vec<Value>) -> bool {
for r in list.iter() {
if r["eprocess"].as_str().unwrap() == addr {
return true;
}
}
false
}
let process_scan = scan_eprocess(&driver).unwrap_or(Vec::new());
let thread_scan = scan_ethread(&driver).unwrap_or(Vec::new());
let activehead = traverse_activehead(&driver).unwrap_or(Vec::new());
let kiprocesslist = traverse_kiprocesslist(&driver).unwrap_or(Vec::new());
let handletable = traverse_handletable(&driver).unwrap_or(Vec::new());
let mut unique_process = HashSet::new();
for list in [&process_scan, &activehead, &kiprocesslist, &handletable].iter() {
for r in list.iter() {
let addr = r["address"].as_str().unwrap();
unique_process.insert(addr);
}
}
let mut table = Table::new();
table.add_row(row![
"Address",
"Name",
"pid",
"ppid",
"PoolTagScan",
"ActiveProcessHead",
"KiProcessListHead",
"HandleTableList",
"ThreadScan"
]);
for p in &unique_process {
let addr = p.to_string();
let v = {
if let Some(vv) = get_from_list(&addr, &activehead) {
vv
} else {
get_from_list(&addr, &process_scan).unwrap_or_default()
}
};
table.add_row(row![
&addr,
v["name"].as_str().unwrap_or("(??)"),
v["pid"].as_i64().unwrap_or(-1),
v["ppid"].as_i64().unwrap_or(-1),
process_in_list(&addr, &process_scan),
process_in_list(&addr, &activehead),
process_in_list(&addr, &kiprocesslist),
process_in_list(&addr, &handletable),
process_in_list_thread(&addr, &thread_scan)
]);
}
table.printstd();
}
pub fn modscan(driver: &DriverState) {
let dd = scan_kernel_module(&driver).unwrap_or(Vec::new());
let mut table = Table::new();
table.add_row(row!["Address", "Base name", "Base", "Size", "File"]);
for d in &dd {
table.add_row(row![
d["address"].as_str().unwrap_or("(??)"),
d["BaseName"].as_str().unwrap_or("(??)"),
d["dllbase"].as_str().unwrap_or("(??)"),
d["size"].as_str().unwrap_or("(??)"),
d["FullName"].as_str().unwrap_or("(??)"),
]);
}
table.printstd();
}
pub fn driverscan(driver: &DriverState) {
let dd = scan_driver(&driver).unwrap_or(Vec::new());
let mut table = Table::new();
table.add_row(row!["Address", "Device", "Service key", "Start", "Size"]);
for d in &dd {
table.add_row(row![
d["address"].as_str().unwrap_or("(??)"),
d["device"].as_str().unwrap_or("(??)"),
d["servicekey"].as_str().unwrap_or("(??)"),
d["start"].as_str().unwrap_or("(??)"),
d["size"].as_str().unwrap_or("(??)"),
]);
}
table.printstd();
}
pub fn unloadedmodules(driver: &DriverState) {
let modules = traverse_unloadeddrivers(&driver).unwrap_or(Vec::new());
let mut table = Table::new();
table.add_row(row!["Address", "Driver", "Start", "End", "Time"]);
for m in &modules {
table.add_row(row![
m["address"].as_str().unwrap_or("(??)"),
m["name"].as_str().unwrap_or("(??)"),
m["start_addr"].as_str().unwrap_or("(??)"),
m["end_addr"].as_str().unwrap_or("(??)"),
m["time_rfc2822"].as_str().unwrap_or("(??)"),
]);
}
table.printstd();
}

53
src/downloader.rs Normal file
View File

@ -0,0 +1,53 @@
use std::error::Error;
use indicatif::{ProgressBar, ProgressStyle};
use reqwest::{header, Client};
use std::path::Path;
use structopt::StructOpt;
use tokio::{fs, io::AsyncWriteExt};
type BoxResult<T> = Result<T, Box<dyn Error>>;
async fn download(url: &str, path: &PathBuf) -> BoxResult<()> {
let client = Client::new();
let total_size = {
let resp = client.head(url).send().await?;
if resp.status().is_success() {
resp.headers()
.get(header::CONTENT_LENGTH)
.and_then(|ct_len| ct_len.to_str().ok())
.and_then(|ct_len| ct_len.parse().ok())
.unwrap_or(0)
} else {
return Err(format!("Couldn'n download URL: {}", url));
}
};
let mut request = client.get(url);
let pb = ProgressBar::new(total_size);
pb.set_style(
ProgressStyle::default_bar()
.template("{spinner:.green} [{elapsed_precise}] \
[{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})")
.progress_chars("#>-"));
let file = Path::new(path);
if file.exists() {
return Err(format!("File {:?} existed", file));
// let size = file.metadata()?.len().saturating_sub(1);
// request = request.header(header::RANGE, format!("bytes={}-", size));
// pb.inc(size);
}
let mut source = request.send().await?;
let mut dest = fs::OpenOptions::new().create(true).append(true).open(&file).await?;
while let Some(chunk) = source.chunk().await? {
dest.write_all(&chunk).await?;
pb.inc(chunk.len() as u64);
}
println!("Download of '{}' has been completed.", file.to_str().unwrap());
Ok(())
}

View File

@ -1,21 +1,23 @@
use std::clone::Clone;
use std::default::Default;
use std::error::Error;
// use std::io::{Error, ErrorKind};
use std::ffi::c_void;
use std::mem::{size_of_val};
use std::mem::{size_of, size_of_val};
use winapi::shared::ntdef::{NTSTATUS};
use winapi::shared::minwindef::{DWORD};
use winapi::shared::minwindef::DWORD;
use winapi::shared::ntdef::NTSTATUS;
use winapi::um::winioctl::{
CTL_CODE, FILE_ANY_ACCESS,
METHOD_IN_DIRECT, METHOD_OUT_DIRECT, /* METHOD_BUFFERED, */ METHOD_NEITHER
CTL_CODE, FILE_ANY_ACCESS, METHOD_IN_DIRECT, /* METHOD_BUFFERED, */ METHOD_NEITHER,
METHOD_OUT_DIRECT,
};
use crate::pdb_store::{PdbStore, parse_pdb};
use crate::windows::{WindowsFFI, WindowsVersion};
use crate::address::Address;
use crate::ioctl_protocol::{
InputData, OffsetData, DerefAddr, ScanPoolData, /* HideProcess, */
/* OutputData, */ Nothing
DerefAddr, HideProcess, InputData, /* OutputData, */ Nothing, OffsetData, ScanPoolData,
};
use crate::pdb_store::{parse_pdb, PdbStore};
use crate::windows::{WindowsFFI, WindowsVersion};
type BoxResult<T> = Result<T, Box<dyn Error>>;
@ -39,19 +41,33 @@ pub enum DriverAction {
ScanPool,
ScanPoolRemote,
DereferenceAddress,
HideProcess
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)
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)
}
}
}
}
@ -62,7 +78,7 @@ pub struct EprocessPoolChunk {
pub eprocess_addr: u64,
pub eprocess_name: String,
pub create_time: u64,
pub exit_time: u64
pub exit_time: u64,
}
impl PartialEq for EprocessPoolChunk {
@ -82,17 +98,20 @@ impl DriverState {
pub fn new() -> Self {
Self {
pdb_store: parse_pdb().expect("Cannot get PDB file"),
windows_ffi: WindowsFFI::new()
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)
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);
self.windows_ffi.device_io(
DriverAction::SetupOffset.get_code(),
&mut input,
&mut Nothing,
);
s
}
@ -100,79 +119,101 @@ impl DriverState {
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 connect(&mut self) {
self.windows_ffi.file_connect();
}
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")?;
pub fn is_supported(&self) -> bool {
self.windows_ffi.short_version.is_supported()
}
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
});
pub fn hide_notepad(&self) {
let s = String::from("notepad.exe");
let s_bytes = s.as_bytes();
let mut name = [0u8; 15];
for i in 0..s.len() {
name[i] = s_bytes[i];
}
let mut input = InputData {
hide_process: HideProcess {
name,
size: s.len() as u64,
},
_ => {}
};
self.deref_addr(ptr + flink_offset, &mut ptr);
}
Ok(result)
self.windows_ffi.device_io(
DriverAction::HideProcess.get_code(),
&mut input,
&mut Nothing,
);
}
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)
pub fn use_old_tag(&self) -> bool {
// use old tag to scan, for Window < 8
if self.windows_ffi.short_version < WindowsVersion::Windows8 {
true
} else {
false
}
}
pub fn get_kernel_base(&self) -> Address {
let mut ntosbase = 0u64;
self.windows_ffi.device_io(
DriverAction::GetKernelBase.get_code(),
&mut Nothing,
&mut ntosbase,
);
Address::from_base(ntosbase)
}
pub fn scan_pool<F>(
&self,
tag: &[u8; 4],
expected_struct: &str,
mut handler: F,
) -> BoxResult<bool>
where
F: FnMut(Address, &[u8], Address) -> BoxResult<bool>, // F(Pool Address, Pool Header Data, Pool Data Address)
// TODO: Pool Header as a real struct
{
let ntosbase = self.get_kernel_base();
// TODO: scan large pool
// TODO: make generator, in hold: https://github.com/rust-lang/rust/issues/43122
// Making this function a generator will turn the call to a for loop
// https://docs.rs/gen-iter/0.2.0/gen_iter/
// >> More flexibility in code
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 minimum_block_size = self
.pdb_store
.get_offset_r(&format!("{}.struct_size", expected_struct))?
+ pool_header_size;
let code = DriverAction::ScanPoolRemote.get_code();
let range = self.get_nonpaged_range(ntosbase)?;
let start_address = range[0];
let end_address = range[1];
let ntosbase = self.get_kernel_base();
let [start_address, end_address] = self.get_nonpaged_range(&ntosbase)?;
println!(
"kernel base: {}; non-paged pool (start, end): ({}, {}); tag: {:?} {}",
ntosbase, start_address, end_address, tag, expected_struct
);
let mut ptr = start_address;
while ptr < end_address {
let mut next_found = 0u64;
let mut input = InputData {
scan_range: ScanPoolData::new(&[ptr, end_address], tag)
scan_range: ScanPoolData::new(&[ptr.address(), end_address.address()], tag),
};
self.windows_ffi.device_io(code, &mut input, &mut ptr);
// println!("found: 0x{:x}", ptr);
self.windows_ffi
.device_io(code, &mut input, &mut next_found);
ptr = Address::from_base(next_found);
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 pool_addr = Address::from_base(ptr.address());
let header: Vec<u8> = self.deref_array(&pool_addr, 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
if pool_addr.address() + chunk_size > end_address.address() {
// the chunk surpasses the non page pool range
break;
}
@ -182,139 +223,175 @@ impl DriverState {
continue;
}
let success = handler(pool_addr, &header, pool_addr + pool_header_size)?;
let data_addr = Address::from_base(pool_addr.address() + pool_header_size);
let success = handler(pool_addr, &header, data_addr).unwrap_or(false);
if success {
ptr += chunk_size; /* pass this chunk */
// ptr += 0x4;
}
else {
ptr += 0x4; /* search next */
ptr += chunk_size; // skip this chunk
} 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 address_of(&self, addr: &Address, name: &str) -> BoxResult<u64> {
let resolver = |p| self.deref_addr_new(p);
let r = self.pdb_store.decompose(&addr, &name)?;
Ok(r.get(&resolver))
}
pub fn decompose<T: Default>(&self, addr: &Address, name: &str) -> BoxResult<T> {
// interface to pdb_store.decompose
let resolver = |p| self.deref_addr_new(p);
let r: T = self.deref_addr_new(self.pdb_store.decompose(&addr, &name)?.get(&resolver));
Ok(r)
}
pub fn decompose_array<T: Default + Clone>(
&self,
addr: &Address,
name: &str,
len: u64,
) -> BoxResult<Vec<T>> {
// interface to pdb_store.decompose for array
let r: Vec<T> = self.deref_array(&self.pdb_store.decompose(&addr, &name)?, len);
Ok(r)
}
pub fn deref_addr_new<T: Default>(&self, addr: u64) -> T {
let mut r: T = Default::default();
if addr != 0 {
self.deref_addr(addr, &mut r);
}
r
}
pub fn deref_array<T: Default + Clone>(&self, addr: &Address, len: u64) -> Vec<T> {
let resolver = |p| self.deref_addr_new(p);
let mut r: Vec<T> = vec![Default::default(); len as usize];
let size_in_byte = (len as usize) * size_of::<T>();
self.deref_addr_ptr(addr.get(&resolver), r.as_mut_ptr(), size_in_byte as u64);
r
}
// #[deprecated(note="use deref_addr_new<T>")]
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
}
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) {
// #[deprecated(note="use deref_array<T>")]
pub fn deref_addr_ptr<T>(&self, addr: u64, outptr: *mut T, output_len_as_byte: u64) {
let code = DriverAction::DereferenceAddress.get_code();
let mut input = InputData {
deref_addr: DerefAddr {
addr,
size: output_len
}
size: output_len_as_byte,
},
};
self.windows_ffi.device_io_raw(code,
&mut input as *mut _ as *mut c_void, size_of_val(&input) as DWORD,
outptr as *mut c_void, output_len as DWORD);
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_byte as DWORD,
);
}
pub fn get_unicode_string(&self, unicode_str_addr: u64) -> BoxResult<String> {
if unicode_str_addr == 0 {
return Err("Not a valid address".into());
}
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")?;
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);
// TODO: BUG with deref_array, len is wrong,
// >> the size of vector is strlen / 2
// >> the size to dereference is strlen
// XXX: use Vec<u8> and turn to Vec<u16>
// let buf: Vec<u16> = self.deref_array(&Address::from_base(bufaddr), (strlen / 2) as u64);
Ok(String::from_utf16(&buf)?)
}
pub fn get_nonpaged_range(&self, ntosbase: u64) -> BoxResult<[u64; 2]> {
pub fn get_nonpaged_range(&self, ntosbase: &Address) -> BoxResult<[Address; 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);
WindowsVersion::WindowsFastRing => {
let mistate = ntosbase.clone() + self.pdb_store.get_offset_r("MiState")?;
let path_first_va: String = vec![
"_MI_SYSTEM_INFORMATION",
"Hardware",
"SystemNodeNonPagedPool",
"NonPagedPoolFirstVa",
]
.join(".");
let path_last_va: String = vec![
"_MI_SYSTEM_INFORMATION",
"Hardware",
"SystemNodeNonPagedPool",
"NonPagedPoolLastVa",
]
.join(".");
let first_va = Address::from_base(self.decompose(&mistate, &path_first_va)?);
let last_va = Address::from_base(self.decompose(&mistate, &path_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);
}
WindowsVersion::Windows10_2019 | WindowsVersion::Windows10_2018 => {
let mistate = ntosbase.clone() + self.pdb_store.get_offset_r("MiState")?;
let path_first_va: String = vec![
"_MI_SYSTEM_INFORMATION",
"Hardware",
"SystemNodeInformation",
"NonPagedPoolFirstVa",
]
.join(".");
let path_last_va: String = vec![
"_MI_SYSTEM_INFORMATION",
"Hardware",
"SystemNodeInformation",
"NonPagedPoolLastVa",
]
.join(".");
let first_va = Address::from_base(self.decompose(&mistate, &path_first_va)?);
let last_va = Address::from_base(self.decompose(&mistate, &path_last_va)?);
Ok([first_va, last_va])
},
_ => {
Err("Windows version for nonpaged pool algorithm is not implemented".into())
}
WindowsVersion::Windows7 => {
let path_first_va =
ntosbase.clone() + self.pdb_store.get_offset_r("MmNonPagedPoolStart")?;
let path_last_va =
ntosbase.clone() + self.pdb_store.get_offset_r("MiNonPagedPoolEnd")?;
let first_va = Address::from_base(self.deref_addr_new(path_first_va.address()));
let last_va = Address::from_base(self.deref_addr_new(path_last_va.address()));
Ok([first_va, last_va])
}
_ => Err("Windows version for nonpaged pool algorithm is not implemented".into()),
}
}
}
}

View File

@ -21,22 +21,101 @@ pub struct OffsetData {
// 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 {
// TODO: Fix the backend so that only neccessary fields are used
// This is too much, most of the functionality has been move to the frontend
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),
WindowsVersion::WindowsFastRing => 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),
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),
large_page_size_offset: pdb_store
.get_offset("PoolBigPageTableSize")
.unwrap_or(0u64),
pool_chunk_size: pdb_store
.get_offset("_POOL_HEADER.struct_size")
.unwrap_or(0u64),
},
WindowsVersion::Windows10_2019 | WindowsVersion::Windows10_2018 => Self {
eprocess_name_offset: pdb_store
.get_offset("_EPROCESS.ImageFileName")
.unwrap_or(0u64),
eprocess_link_offset: pdb_store
.get_offset("_EPROCESS.ActiveProcessLinks")
.unwrap_or(0u64),
list_blink_offset: pdb_store.get_offset("_LIST_ENTRY.Blink").unwrap_or(0u64),
process_head_offset: pdb_store.get_offset("PsActiveProcessHead").unwrap_or(0u64),
mistate_offset: pdb_store.get_offset("MiState").unwrap_or(0u64),
hardware_offset: pdb_store
.get_offset("_MI_SYSTEM_INFORMATION.Hardware")
.unwrap_or(0u64),
system_node_offset: pdb_store
.get_offset("_MI_HARDWARE_STATE.SystemNodeInformation")
.unwrap_or(0u64),
first_va_offset: pdb_store
.get_offset("_MI_SYSTEM_NODE_INFORMATION.NonPagedPoolFirstVa")
.unwrap_or(0u64),
last_va_offset: pdb_store
.get_offset("_MI_SYSTEM_NODE_INFORMATION.NonPagedPoolLastVa")
.unwrap_or(0u64),
large_page_table_offset: pdb_store.get_offset("PoolBigPageTable").unwrap_or(0u64),
large_page_size_offset: pdb_store
.get_offset("PoolBigPageTableSize")
.unwrap_or(0u64),
pool_chunk_size: pdb_store
.get_offset("_POOL_HEADER.struct_size")
.unwrap_or(0u64),
},
WindowsVersion::Windows7 => Self {
eprocess_name_offset: pdb_store
.get_offset("_EPROCESS.ImageFileName")
.unwrap_or(0u64),
eprocess_link_offset: pdb_store
.get_offset("_EPROCESS.ActiveProcessLinks")
.unwrap_or(0u64),
list_blink_offset: pdb_store.get_offset("_LIST_ENTRY.Blink").unwrap_or(0u64),
process_head_offset: pdb_store.get_offset("PsActiveProcessHead").unwrap_or(0u64),
mistate_offset: pdb_store.get_offset("MiState").unwrap_or(0u64),
hardware_offset: pdb_store
.get_offset("_MI_SYSTEM_INFORMATION.Hardware")
.unwrap_or(0u64),
system_node_offset: pdb_store
.get_offset("_MI_HARDWARE_STATE.SystemNodeInformation")
.unwrap_or(0u64),
first_va_offset: pdb_store
.get_offset("_MI_SYSTEM_NODE_INFORMATION.NonPagedPoolFirstVa")
.unwrap_or(0u64),
last_va_offset: pdb_store
.get_offset("_MI_SYSTEM_NODE_INFORMATION.NonPagedPoolLastVa")
.unwrap_or(0u64),
large_page_table_offset: pdb_store.get_offset("PoolBigPageTable").unwrap_or(0u64),
large_page_size_offset: pdb_store
.get_offset("PoolBigPageTableSize")
.unwrap_or(0u64),
pool_chunk_size: pdb_store
.get_offset("_POOL_HEADER.struct_size")
.unwrap_or(0u64),
},
// TODO: Add other version of Windows here
// TODO: Warn user of unknown windows version, because BSOD will occur
_ => Self {
eprocess_name_offset: 0u64,
eprocess_link_offset: 0u64,
@ -50,7 +129,7 @@ impl OffsetData {
large_page_table_offset: 0u64,
large_page_size_offset: 0u64,
pool_chunk_size: 0u64,
}
},
}
}
}
@ -59,7 +138,7 @@ impl OffsetData {
#[derive(Debug, Copy, Clone)]
pub struct DerefAddr {
pub addr: u64,
pub size: u64
pub size: u64,
}
#[repr(C)]
@ -67,15 +146,15 @@ pub struct DerefAddr {
pub struct ScanPoolData {
pub start: u64,
pub end: u64,
pub tag: u32
pub tag: u32,
}
impl ScanPoolData{
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)
tag: u32::from_le_bytes(*tag),
}
}
}
@ -84,7 +163,7 @@ impl ScanPoolData{
#[derive(Debug, Copy, Clone)]
pub struct HideProcess {
pub name: [u8; 15],
pub size: u64
pub size: u64,
}
#[repr(C)]

View File

@ -1,8 +1,594 @@
extern crate chrono;
extern crate app_dirs;
extern crate chrono;
pub mod address;
pub mod commands;
pub mod driver_state;
pub mod ioctl_protocol;
pub mod object;
pub mod pdb_store;
pub mod windows;
pub mod ioctl_protocol;
pub mod driver_state;
use app_dirs::AppInfo;
use chrono::{DateTime, Local, TimeZone};
use serde_json::{json, Value};
use std::error::Error;
use address::Address;
use driver_state::DriverState;
use object::*;
type BoxResult<T> = Result<T, Box<dyn Error>>;
pub const APP_INFO: AppInfo = AppInfo {
name: "lpus",
author: "nganhkhoa",
};
pub fn to_epoch(filetime: u64) -> DateTime<Local> {
// return seconds from epoch
let windows_epoch_diff = 11_644_473_600_000 * 10_000;
if filetime < windows_epoch_diff {
return Local.timestamp(0, 0);
}
let filetime_epoch = (filetime - windows_epoch_diff) / 10_000_000;
Local.timestamp(filetime_epoch as i64, 0)
}
pub fn get_irp_name(idx: usize) -> String {
let irp_names = vec![
"IRP_MJ_CREATE",
"IRP_MJ_CREATE_NAMED_PIPE",
"IRP_MJ_CLOSE",
"IRP_MJ_READ",
"IRP_MJ_WRITE",
"IRP_MJ_QUERY_INFORMATION",
"IRP_MJ_SET_INFORMATION",
"IRP_MJ_QUERY_EA",
"IRP_MJ_SET_EA",
"IRP_MJ_FLUSH_BUFFERS",
"IRP_MJ_QUERY_VOLUME_INFORMATION",
"IRP_MJ_SET_VOLUME_INFORMATION",
"IRP_MJ_DIRECTORY_CONTROL",
"IRP_MJ_FILE_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CONTROL",
"IRP_MJ_INTERNAL_DEVICE_CONTROL",
"IRP_MJ_SHUTDOWN",
"IRP_MJ_LOCK_CONTROL",
"IRP_MJ_CLEANUP",
"IRP_MJ_CREATE_MAILSLOT",
"IRP_MJ_QUERY_SECURITY",
"IRP_MJ_SET_SECURITY",
"IRP_MJ_POWER",
"IRP_MJ_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CHANGE",
"IRP_MJ_QUERY_QUOTA",
"IRP_MJ_SET_QUOTA",
"IRP_MJ_PNP",
]
.iter()
.map(|x| x.to_string())
.collect::<Vec<String>>();
if let Some(name) = irp_names.get(idx) {
name.clone()
} else {
"UNKNOWN".to_string()
}
}
fn get_device_type(typ: u32) -> String {
match typ {
0x00000027 => "FILE_DEVICE_8042_PORT",
0x00000032 => "FILE_DEVICE_ACPI",
0x00000029 => "FILE_DEVICE_BATTERY",
0x00000001 => "FILE_DEVICE_BEEP",
0x0000002a => "FILE_DEVICE_BUS_EXTENDER",
0x00000002 => "FILE_DEVICE_CD_ROM",
0x00000003 => "FILE_DEVICE_CD_ROM_FILE_SYSTEM",
0x00000030 => "FILE_DEVICE_CHANGER",
0x00000004 => "FILE_DEVICE_CONTROLLER",
0x00000005 => "FILE_DEVICE_DATALINK",
0x00000006 => "FILE_DEVICE_DFS",
0x00000035 => "FILE_DEVICE_DFS_FILE_SYSTEM",
0x00000036 => "FILE_DEVICE_DFS_VOLUME",
0x00000007 => "FILE_DEVICE_DISK",
0x00000008 => "FILE_DEVICE_DISK_FILE_SYSTEM",
0x00000033 => "FILE_DEVICE_DVD",
0x00000009 => "FILE_DEVICE_FILE_SYSTEM",
0x0000003a => "FILE_DEVICE_FIPS",
0x00000034 => "FILE_DEVICE_FULLSCREEN_VIDEO",
0x0000000a => "FILE_DEVICE_INPORT_PORT",
0x0000000b => "FILE_DEVICE_KEYBOARD",
0x0000002f => "FILE_DEVICE_KS",
0x00000039 => "FILE_DEVICE_KSEC",
0x0000000c => "FILE_DEVICE_MAILSLOT",
0x0000002d => "FILE_DEVICE_MASS_STORAGE",
0x0000000d => "FILE_DEVICE_MIDI_IN",
0x0000000e => "FILE_DEVICE_MIDI_OUT",
0x0000002b => "FILE_DEVICE_MODEM",
0x0000000f => "FILE_DEVICE_MOUSE",
0x00000010 => "FILE_DEVICE_MULTI_UNC_PROVIDER",
0x00000011 => "FILE_DEVICE_NAMED_PIPE",
0x00000012 => "FILE_DEVICE_NETWORK",
0x00000013 => "FILE_DEVICE_NETWORK_BROWSER",
0x00000014 => "FILE_DEVICE_NETWORK_FILE_SYSTEM",
0x00000028 => "FILE_DEVICE_NETWORK_REDIRECTOR",
0x00000015 => "FILE_DEVICE_NULL",
0x00000016 => "FILE_DEVICE_PARALLEL_PORT",
0x00000017 => "FILE_DEVICE_PHYSICAL_NETCARD",
0x00000018 => "FILE_DEVICE_PRINTER",
0x00000019 => "FILE_DEVICE_SCANNER",
0x0000001c => "FILE_DEVICE_SCREEN",
0x00000037 => "FILE_DEVICE_SERENUM",
0x0000001a => "FILE_DEVICE_SERIAL_MOUSE_PORT",
0x0000001b => "FILE_DEVICE_SERIAL_PORT",
0x00000031 => "FILE_DEVICE_SMARTCARD",
0x0000002e => "FILE_DEVICE_SMB",
0x0000001d => "FILE_DEVICE_SOUND",
0x0000001e => "FILE_DEVICE_STREAMS",
0x0000001f => "FILE_DEVICE_TAPE",
0x00000020 => "FILE_DEVICE_TAPE_FILE_SYSTEM",
0x00000038 => "FILE_DEVICE_TERMSRV",
0x00000021 => "FILE_DEVICE_TRANSPORT",
0x00000022 => "FILE_DEVICE_UNKNOWN",
0x0000002c => "FILE_DEVICE_VDM",
0x00000023 => "FILE_DEVICE_VIDEO",
0x00000024 => "FILE_DEVICE_VIRTUAL_DISK",
0x00000025 => "FILE_DEVICE_WAVE_IN",
0x00000026 => "FILE_DEVICE_WAVE_OUT",
_ => "UNKNOWN",
}
.to_string()
}
pub fn scan_eprocess(driver: &DriverState) -> BoxResult<Vec<Value>> {
let mut result: Vec<Value> = Vec::new();
let tag = if driver.use_old_tag() {
b"Pro\xe3"
} else {
b"Proc"
};
driver.scan_pool(tag, "_EPROCESS", |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_valid_start = &data_addr;
let eprocess_valid_end = (pool_addr.clone() + chunk_size) - eprocess_size;
let mut try_eprocess_ptr = eprocess_valid_start.clone();
while try_eprocess_ptr <= eprocess_valid_end {
let create_time: u64 = driver.decompose(&try_eprocess_ptr, "_EPROCESS.CreateTime")?;
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);
}
result.push(make_eprocess(driver, &try_eprocess_ptr)?);
Ok(true)
})?;
Ok(result)
}
pub fn scan_file(driver: &DriverState) -> BoxResult<Vec<Value>> {
let mut result: Vec<Value> = Vec::new();
let tag = if driver.use_old_tag() {
b"Fil\xe5"
} else {
b"File"
};
driver.scan_pool(tag, "_FILE_OBJECT", |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 valid_end = (pool_addr.clone() + chunk_size) - fob_size;
let mut try_ptr = data_addr;
while try_ptr <= valid_end {
let ftype: u16 = driver.decompose(&try_ptr, "_FILE_OBJECT.Type")?;
let size: u16 = driver.decompose(&try_ptr, "_FILE_OBJECT.Size")?;
if (size as u64) == fob_size && ftype == 5u16 {
break;
}
try_ptr += 0x4; // search exhaustively
}
if try_ptr > valid_end {
return Ok(false);
}
let fob_addr = &try_ptr;
let read_ok: u8 = driver.decompose(fob_addr, "_FILE_OBJECT.ReadAccess")?;
let write_ok: u8 = driver.decompose(fob_addr, "_FILE_OBJECT.WriteAccess")?;
let delete_ok: u8 = driver.decompose(fob_addr, "_FILE_OBJECT.DeleteAccess")?;
let share_read_ok: u8 = driver.decompose(fob_addr, "_FILE_OBJECT.SharedRead")?;
let share_write_ok: u8 = driver.decompose(fob_addr, "_FILE_OBJECT.SharedWrite")?;
let share_delete_ok: u8 = driver.decompose(fob_addr, "_FILE_OBJECT.SharedDelete")?;
let filename_ptr = driver.address_of(fob_addr, "_FILE_OBJECT.FileName")?;
let devicename_ptr: u64 = driver.address_of(
fob_addr,
"_FILE_OBJECT.DeviceObject.DriverObject.DriverName",
)?;
let hardware_ptr: u64 = driver.decompose(
fob_addr,
"_FILE_OBJECT.DeviceObject.DriverObject.HardwareDatabase",
)?;
let filename = if read_ok == 0 {
"[NOT READABLE]".to_string()
} else if let Ok(n) = driver.get_unicode_string(filename_ptr) {
n
} else {
"[NOT A VALID _UNICODE_STRING]".to_string()
};
let devicename = driver
.get_unicode_string(devicename_ptr)
.unwrap_or("".to_string());
let hardware = driver
.get_unicode_string(hardware_ptr)
.unwrap_or("".to_string());
result.push(json!({
"pool": format!("0x{:x}", pool_addr.address()),
"address": format!("0x{:x}", fob_addr.address()),
"type": "_FILE_OBJECT",
"path": filename,
"device": devicename,
"hardware": hardware,
"access": {
"r": read_ok == 1,
"w": write_ok == 1,
"d": delete_ok == 1,
"R": share_read_ok == 1,
"W": share_write_ok == 1,
"D": share_delete_ok == 1
}
}));
Ok(true)
})?;
Ok(result)
}
pub fn scan_ethread(driver: &DriverState) -> BoxResult<Vec<Value>> {
let mut result: Vec<Value> = Vec::new();
let tag = if driver.use_old_tag() {
b"Thr\xe5"
} else {
b"Thre"
};
driver.scan_pool(tag, "_ETHREAD", |pool_addr, header, data_addr| {
let chunk_size = (header[2] as u64) * 16u64;
let object_header_size = driver
.pdb_store
.get_offset_r("_OBJECT_HEADER.struct_size")?;
let header_size = driver.pdb_store.get_offset_r("_POOL_HEADER.struct_size")?;
let ethread_size = driver.pdb_store.get_offset_r("_ETHREAD.struct_size")?;
let ethread_valid_start = &data_addr;
let ethread_valid_end = (pool_addr.clone() + chunk_size) - ethread_size;
let mut try_ethread_ptr = ethread_valid_start.clone();
if chunk_size == header_size + object_header_size + ethread_size {
try_ethread_ptr = ethread_valid_end.clone();
} else {
while try_ethread_ptr <= ethread_valid_end {
let create_time: u64 = driver.decompose(&try_ethread_ptr, "_ETHREAD.CreateTime")?;
if driver.windows_ffi.valid_process_time(create_time) {
break;
}
try_ethread_ptr += 0x4; // search exhaustively
}
if try_ethread_ptr > ethread_valid_end {
return Ok(false);
}
}
result.push(make_ethread(driver, &try_ethread_ptr)?);
Ok(true)
})?;
Ok(result)
}
// Unstable, do not use
// pub fn scan_mutant(driver: &DriverState) -> BoxResult<Vec<Value>> {
// let mut result: Vec<Value> = Vec::new();
//
// let ntosbase = driver.get_kernel_base();
// let [start, end] = driver.get_nonpaged_range(&ntosbase)?;
//
// let tag =
// if driver.use_old_tag() { b"Mut\xe1" }
// else { b"Muta" };
// driver.scan_pool(tag, "_KMUTANT", |pool_addr, header, data_addr| {
// let chunk_size = (header[2] as u64) * 16u64;
//
// let kmutant_size = driver.pdb_store.get_offset_r("_KMUTANT.struct_size")?;
//
// let kmutant_valid_start = data_addr;
// let kmutant_valid_end = (pool_addr.clone() + chunk_size) - kmutant_size;
// let mut try_kmutant_ptr = kmutant_valid_start.clone();
//
// while try_kmutant_ptr <= kmutant_valid_end {
// // TODO: Stronger constrain
// let kthread_ptr = driver.address_of(&try_kmutant_ptr, "_KMUTANT.OwnerThread")?;
// if kthread_ptr > start.address() && kthread_ptr < end.address() {
// break;
// }
// try_kmutant_ptr += 0x4; // search exhaustively
// }
// if try_kmutant_ptr > kmutant_valid_end {
// return Ok(false);
// }
//
// let kmutant_ptr = try_kmutant_ptr;
// let ethread_ptr = Address::from_base(driver.address_of(&kmutant_ptr, "_KMUTANT.OwnerThread")?);
//
// let pid: u64 = driver.decompose(&ethread_ptr, "_ETHREAD.Cid.UniqueProcess")?;
// let tid: u64 = driver.decompose(&ethread_ptr, "_ETHREAD.Cid.UniqueThread")?;
// let unicode_str_ptr: u64 = driver.address_of(&ethread_ptr, "_ETHREAD.ThreadName")?;
//
// let thread_name =
// if let Ok(name) = driver.get_unicode_string(unicode_str_ptr) {
// name
// }
// else {
// "".to_string()
// };
//
// result.push(json!({
// "pool": format!("0x{:x}", pool_addr.address()),
// "address": format!("0x{:x}", ethread_ptr.address()),
// "type": "_KMUTANT",
// "pid": pid,
// "tid": tid,
// "name": thread_name
// }));
// Ok(true)
// })?;
//
// Ok(result)
// }
pub fn scan_driver(driver: &DriverState) -> BoxResult<Vec<Value>> {
let mut result: Vec<Value> = Vec::new();
let tag = if driver.use_old_tag() {
b"Dri\xf6"
} else {
b"Driv"
};
driver.scan_pool(tag, "_DRIVER_OBJECT", |pool_addr, header, data_addr| {
let chunk_size = (header[2] as u64) * 16u64;
let dob_size = driver
.pdb_store
.get_offset_r("_DRIVER_OBJECT.struct_size")?;
let valid_end = (pool_addr.clone() + chunk_size) - dob_size;
let mut try_ptr = data_addr;
while try_ptr <= valid_end {
// No documentation on type constrain
let size: u16 = driver.decompose(&try_ptr, "_DRIVER_OBJECT.Size")?;
if (size as u64) == dob_size {
break;
}
try_ptr += 0x4; // search exhaustively
}
if try_ptr > valid_end {
return Ok(false);
}
result.push(make_driver(driver, &try_ptr)?);
Ok(true)
})?;
Ok(result)
}
pub fn scan_kernel_module(driver: &DriverState) -> BoxResult<Vec<Value>> {
let mut result: Vec<Value> = Vec::new();
driver.scan_pool(
b"MmLd",
"_LDR_DATA_TABLE_ENTRY",
|_pool_addr, _, data_addr| {
// By reversing, this structure does not have any header
result.push(make_ldr(driver, &data_addr)?);
Ok(true)
},
)?;
Ok(result)
}
pub fn traverse_loadedmodulelist(driver: &DriverState) -> BoxResult<Vec<Value>> {
let ntosbase = driver.get_kernel_base();
let module_list_head = ntosbase + driver.pdb_store.get_offset_r("PsLoadedModuleList")?;
let result = make_list_entry(
driver,
module_list_head.clone(),
"_LDR_DATA_TABLE_ENTRY.InLoadOrderLinks",
)?
.iter()
.map(|x| make_ldr(driver, &x).unwrap_or(json!({})))
.collect();
Ok(result)
}
// dx Debugger.Utility.Collections.FromListEntry( *(nt!_LIST_ENTRY*)&(nt!PsActiveProcessHead), "nt!_EPROCESS", "ActiveProcessLinks")
pub fn traverse_activehead(driver: &DriverState) -> BoxResult<Vec<Value>> {
let mut result: Vec<Value> = Vec::new();
let ntosbase = driver.get_kernel_base();
let process_list_head = ntosbase + driver.pdb_store.get_offset_r("PsActiveProcessHead")?;
let eprocess_listentry_offset = driver
.pdb_store
.get_offset_r("_EPROCESS.ActiveProcessLinks")?;
// TODO: make_list_entry
let mut ptr: u64 = driver.decompose(&process_list_head, "_LIST_ENTRY.Flink")?;
while ptr != process_list_head.address() {
let eprocess_ptr = Address::from_base(ptr - eprocess_listentry_offset);
result.push(make_eprocess(driver, &eprocess_ptr)?);
ptr = driver.decompose(&eprocess_ptr, "_EPROCESS.ActiveProcessLinks.Flink")?;
}
Ok(result)
}
// TODO: where is afd!
// dx Debugger.Utility.Collections.FromListEntry( *(nt!_LIST_ENTRY*)&(afd!AfdEndpointListHead), "nt!_EPROCESS", "ActiveProcessLinks")
// pub fn traverse_afdendpoint(driver: &DriverState) -> BoxResult<Vec<Value>> {
// let mut result: Vec<Value> = Vec::new();
//
// let ntosbase = driver.get_kernel_base();
// let process_list_head = ntosbase + driver.pdb_store.get_offset_r("PsActiveProcessHead")?;
// let eprocess_listentry_offset = driver.pdb_store.get_offset_r("_EPROCESS.ActiveProcessLinks")?;
//
// let mut ptr: u64 = driver.decompose(&process_list_head, "_LIST_ENTRY.Flink")?;
// while ptr != process_list_head.address() {
// let eprocess_ptr = Address::from_base(ptr - eprocess_listentry_offset);
//
// let pid: u64 = driver.decompose(&eprocess_ptr, "_EPROCESS.UniqueProcessId")?;
// let ppid: u64 = driver.decompose(&eprocess_ptr, "_EPROCESS.InheritedFromUniqueProcessId")?;
// let image_name: Vec<u8> = driver.decompose_array(&eprocess_ptr, "_EPROCESS.ImageFileName", 15)?;
// let unicode_str_ptr = driver.address_of(&eprocess_ptr, "_EPROCESS.ImageFilePointer.FileName")?;
//
// let eprocess_name =
// if let Ok(name) = from_utf8(&image_name) {
// name.to_string().trim_end_matches(char::from(0)).to_string()
// } else {
// "".to_string()
// };
// let binary_path = driver.get_unicode_string(unicode_str_ptr)
// .unwrap_or("".to_string());
//
// result.push(json!({
// "address": format!("0x{:x}", &eprocess_ptr.address()),
// "type": "_EPROCESS",
// "pid": pid,
// "ppid": ppid,
// "name": eprocess_name,
// "path": binary_path
// }));
//
// ptr = driver.decompose(&eprocess_ptr, "_EPROCESS.ActiveProcessLinks.Flink")?;
// }
//
// Ok(result)
// }
// dx Debugger.Utility.Collections.FromListEntry( *(nt!_LIST_ENTRY*)&(nt!KiProcessListHead), "nt!_KPROCESS", "ProcessListEntry").Select( p => new {Process = (nt!_EPROCESS*)&p )
pub fn traverse_kiprocesslist(driver: &DriverState) -> BoxResult<Vec<Value>> {
let mut result: Vec<Value> = Vec::new();
let ntosbase = driver.get_kernel_base();
let process_list_head = ntosbase + driver.pdb_store.get_offset_r("KiProcessListHead")?;
let eprocess_listentry_offset = driver
.pdb_store
.get_offset_r("_KPROCESS.ProcessListEntry")?;
// TODO: make_list_entry
let mut ptr: u64 = driver.decompose(&process_list_head, "_LIST_ENTRY.Flink")?;
while ptr != process_list_head.address() {
let eprocess_ptr = Address::from_base(ptr - eprocess_listentry_offset);
result.push(make_eprocess(driver, &eprocess_ptr)?);
ptr = driver.decompose(&eprocess_ptr, "_KPROCESS.ProcessListEntry.Flink")?;
}
Ok(result)
}
// dx Debugger.Utility.Collections.FromListEntry(*(nt!_LIST_ENTRY*)&nt!HandleTableListHead, "nt!_HANDLE_TABLE", "HandleTableList").Where(h => h.QuotaProcess != 0).Select( qp => new {Process= qp.QuotaProcess} )
pub fn traverse_handletable(driver: &DriverState) -> BoxResult<Vec<Value>> {
let mut result: Vec<Value> = Vec::new();
let ntosbase = driver.get_kernel_base();
let process_list_head = ntosbase + driver.pdb_store.get_offset_r("HandleTableListHead")?;
let handle_list_offset = driver
.pdb_store
.get_offset_r("_HANDLE_TABLE.HandleTableList")?;
let mut ptr: u64 = driver.decompose(&process_list_head, "_LIST_ENTRY.Flink")?;
while ptr != process_list_head.address() {
let handle_ptr = Address::from_base(ptr - handle_list_offset);
let quota_process: u64 = driver.decompose(&handle_ptr, "_HANDLE_TABLE.QuotaProcess")?;
if quota_process != 0 {
let eprocess_ptr = Address::from_base(quota_process);
result.push(make_eprocess(driver, &eprocess_ptr)?);
}
ptr = driver.decompose(&handle_ptr, "_HANDLE_TABLE.HandleTableList.Flink")?;
}
Ok(result)
}
pub fn traverse_unloadeddrivers(driver: &DriverState) -> BoxResult<Vec<Value>> {
let mut result: Vec<Value> = Vec::new();
let ntosbase = driver.get_kernel_base();
let unload_array_ptr = ntosbase.clone() + driver.pdb_store.get_offset_r("MmUnloadedDrivers")?;
let num_unload_ptr =
ntosbase.clone() + driver.pdb_store.get_offset_r("MmLastUnloadedDriver")?;
let unload_array = driver.deref_addr_new::<u64>(unload_array_ptr.address());
if unload_array == 0 {
return Err("The unload driver list pointer is null".into());
}
// by reversing MmLocateUnloadedDriver
let num_unload = driver.deref_addr_new::<u32>(num_unload_ptr.address()) as u64;
let bound = if num_unload > 0x32 { 0x32 } else { num_unload };
let drivers = (0..bound).map(|i| Address::from_base(unload_array + (i * 0x28)));
for driver_addr in drivers {
let name = driver
.get_unicode_string(driver_addr.address())
.unwrap_or("".to_string());
let start_addr: u64 = driver.decompose(&driver_addr, "_UNLOADED_DRIVERS.StartAddress")?;
let end_addr: u64 = driver.decompose(&driver_addr, "_UNLOADED_DRIVERS.EndAddress")?;
let current_time: u64 = driver.decompose(&driver_addr, "_UNLOADED_DRIVERS.CurrentTime")?;
let time = to_epoch(current_time);
result.push(json!({
"address": format!("0x{:x}", driver_addr.address()),
"type": "_UNLOADED_DRIVERS",
"name": name,
"start_addr": format!("0x{:x}", start_addr),
"end_addr": format!("0x{:x}", end_addr),
"time_unix": time.timestamp(),
"time_rfc2822": time.to_rfc2822()
}));
}
Ok(result)
}
pub fn ssdt_table(driver: &DriverState) -> BoxResult<Vec<u64>> {
// https://github.com/volatilityfoundation/volatility3/blob/master/volatility/framework/plugins/windows/ssdt.py
let ntosbase = driver.get_kernel_base();
let servicetable = ntosbase.clone() + driver.pdb_store.get_offset_r("KiServiceTable")?;
let servicelimit_ptr = ntosbase.clone() + driver.pdb_store.get_offset_r("KiServiceLimit")?;
let servicelimit = driver.deref_addr_new::<u32>(servicelimit_ptr.address()) as u64;
let ssdt: Vec<u64> = driver
.deref_array::<i32>(&servicetable, servicelimit)
.iter()
.map(|entry| {
// the entry can be negative, we need to do calculation using signed int
// and convert back to unsigned int for address
((servicetable.address() as i64) + ((*entry >> 4) as i64)) as u64
})
.collect();
Ok(ssdt)
}

290
src/object.rs Normal file
View File

@ -0,0 +1,290 @@
use crate::address::Address;
use crate::driver_state::DriverState;
use crate::{get_device_type, to_epoch};
use serde_json::{json, Value};
use std::error::Error;
use std::str::from_utf8;
type BoxResult<T> = Result<T, Box<dyn Error>>;
pub fn make_list_entry(d: &DriverState, a: Address, next: &str) -> BoxResult<Vec<Address>> {
// `a` is the address to the _LIST_ENTRY
// `next` is the _LIST_ENTRY field in the object
// return a list of address for object
let mut result: Vec<Address> = Vec::new();
let list_offset = d.pdb_store.get_offset_r(next)?;
let mut ptr: u64 = d.deref_addr_new(a.address());
while ptr != a.address() {
let obj_ptr = Address::from_base(ptr - list_offset);
ptr = d.decompose(&obj_ptr, &format!("{}.Flink", next))?;
result.push(obj_ptr);
}
Ok(result)
}
pub fn make_eprocess(d: &DriverState, a: &Address) -> BoxResult<Value> {
let createtime: u64 = d.decompose(a, "_EPROCESS.CreateTime")?;
let exittime: u64 = d.decompose(a, "_EPROCESS.ExitTime")?;
let pid: u64 = d.decompose(a, "_EPROCESS.UniqueProcessId")?;
let ppid: u64 = d.decompose(a, "_EPROCESS.InheritedFromUniqueProcessId")?;
let image_name: Vec<u8> = d.decompose_array(a, "_EPROCESS.ImageFileName", 15)?;
let filename_ptr = d
.address_of(a, "_EPROCESS.ImageFilePointer.FileName")
.unwrap_or(0); // ImageFilePointer is after Windows 10 Anniversary
let eprocess_name = if let Ok(name) = from_utf8(&image_name) {
name.to_string().trim_end_matches(char::from(0)).to_string()
} else {
"".to_string()
};
let binary_path = d.get_unicode_string(filename_ptr).unwrap_or("".to_string());
let thread_head = d.address_of(a, "_EPROCESS.ThreadListHead")?;
let threads: Vec<Value> = make_list_entry(
d,
Address::from_base(thread_head),
"_ETHREAD.ThreadListEntry",
)
.unwrap_or(Vec::new())
.iter()
.map(|thread_addr| {
make_ethread(d, thread_addr).unwrap_or(json!({})) // unlikely
})
.collect();
let c_t = to_epoch(createtime);
let e_t = to_epoch(exittime);
Ok(json!({
"address": format!("0x{:x}", a.address()),
"type": "_EPROCESS",
"pid": pid,
"ppid": ppid,
"name": eprocess_name,
"path": binary_path,
"threads": threads,
"createtime": {
"unix": c_t.timestamp(),
"rfc2822": c_t.to_rfc2822()
},
"exittime": {
"unix": e_t.timestamp(),
"rfc2822": e_t.to_rfc2822(),
}
}))
}
pub fn make_ethread(d: &DriverState, a: &Address) -> BoxResult<Value> {
// let createtime: u64 = d.decompose(a, "_ETHREAD.CreateTime")?;
// let exittime: u64 = d.decompose(a, "_ETHREAD.ExitTime")?;
let pid: u64 = d.decompose(a, "_ETHREAD.Cid.UniqueProcess")?;
let tid: u64 = d.decompose(a, "_ETHREAD.Cid.UniqueThread")?;
let eprocess: u64 = d.decompose(a, "_ETHREAD.Tcb.Process")?;
let flags: u32 = d.decompose(a, "_ETHREAD.CrossThreadFlags")?;
let state = match d.decompose::<u8>(a, "_ETHREAD.Tcb.State")? {
0 => "Initialized",
1 => "Ready",
2 => "Running",
3 => "Standby",
4 => "Terminated",
5 => "Waiting",
6 => "Transition",
7 => "DeferredReady",
8 => "GateWait",
_ => "Unknown",
};
let wait = match d.decompose::<u8>(a, "_ETHREAD.Tcb.WaitReason")? {
0 => "Executive",
1 => "FreePage",
2 => "PageIn",
3 => "PoolAllocation",
4 => "DelayExecution",
5 => "Suspended",
6 => "UserRequest",
7 => "WrExecutive",
8 => "WrFreePage",
9 => "WrPageIn",
10 => "WrPoolAllocation",
11 => "WrDelayExecution",
12 => "WrSuspended",
13 => "WrUserRequest",
14 => "WrEventPair",
15 => "WrQueue",
16 => "WrLpcReceive",
17 => "WrLpcReply",
18 => "WrVirtualMemory",
19 => "WrPageOut",
20 => "WrRendezvous",
21 => "Spare2",
22 => "Spare3",
23 => "Spare4",
24 => "Spare5",
25 => "Spare6",
26 => "WrKernel",
27 => "WrResource",
28 => "WrPushLock",
29 => "WrMutex",
30 => "WrQuantumEnd",
31 => "WrDispatchInt",
32 => "WrPreempted",
33 => "WrYieldExecution",
34 => "WrFastMutex",
35 => "WrGuardedMutex",
36 => "WrRundown",
37 => "MaximumWaitReason",
_ => "Unknown",
};
let name_ptr: u64 = d.address_of(a, "_ETHREAD.ThreadName").unwrap_or(0); // ThreadName is after Windows 10 Anniversary
let thread_name = if let Ok(name) = d.get_unicode_string(name_ptr) {
name
} else {
"".to_string()
};
// let c_t = to_epoch(createtime);
// let e_t = to_epoch(exittime);
Ok(json!({
"address": format!("0x{:x}", a.address()),
"type": "_ETHREAD",
"tid": tid,
"pid": pid,
"name": thread_name,
"eprocess": format!("0x{:x}", eprocess),
"state": state,
"wait_reason": wait,
"flags": {
"raw": format!("0x{:x}", flags),
"PS_CROSS_THREAD_FLAGS_TERMINATED": flags & 1 != 0,
"PS_CROSS_THREAD_FLAGS_DEADTHREAD": flags & 2 != 0,
"PS_CROSS_THREAD_FLAGS_HIDEFROMDBG": flags & 3 != 0,
"PS_CROSS_THREAD_FLAGS_IMPERSONATING": flags & 4 != 0,
"PS_CROSS_THREAD_FLAGS_SYSTEM": flags & 5 != 0,
"PS_CROSS_THREAD_FLAGS_HARD_ERRORS_DISABLED": flags & 6 != 0,
"PS_CROSS_THREAD_FLAGS_BREAK_ON_TERMINATION": flags & 7 != 0,
"PS_CROSS_THREAD_FLAGS_SKIP_CREATION_MSG": flags & 8 != 0,
"PS_CROSS_THREAD_FLAGS_SKIP_TERMINATION_MSG": flags & 9 != 0,
},
// "createtime": {
// "unix": c_t.timestamp(),
// "rfc2822": c_t.to_rfc2822()
// },
// "exittime": {
// "unix": e_t.timestamp(),
// "rfc2822": e_t.to_rfc2822(),
// }
}))
}
pub fn make_driver(d: &DriverState, a: &Address) -> BoxResult<Value> {
let devicename_ptr = d.address_of(a, "_DRIVER_OBJECT.DriverName")?;
let servicekey_ptr = d.address_of(a, "_DRIVER_OBJECT.DriverExtension.ServiceKeyName")?;
let hardware_ptr: u64 = d.decompose(a, "_DRIVER_OBJECT.HardwareDatabase")?;
let major_function: Vec<u64> = d.decompose_array(a, "_DRIVER_OBJECT.MajorFunction", 28)?;
let start: u64 = d.decompose(a, "_DRIVER_OBJECT.DriverStart")?;
let init: u64 = d.decompose(a, "_DRIVER_OBJECT.DriverInit")?;
let unload: u64 = d.decompose(a, "_DRIVER_OBJECT.DriverUnload")?;
let size: u64 = d.decompose(a, "_DRIVER_OBJECT.DriverSize")?;
let devicename = d
.get_unicode_string(devicename_ptr)
.unwrap_or("".to_string());
let hardware = d.get_unicode_string(hardware_ptr).unwrap_or("".to_string());
let servicekey = d
.get_unicode_string(servicekey_ptr)
.unwrap_or("".to_string());
// device tree walk
let devices = {
let mut driver_devices: Vec<Value> = Vec::new();
let mut device_ptr: u64 = d.decompose(a, "_DRIVER_OBJECT.DeviceObject")?;
while device_ptr != 0 {
let addr = Address::from_base(device_ptr);
let device_type: u32 = d.decompose(&addr, "_DEVICE_OBJECT.DeviceType")?;
// get attached devices
let mut attached_ptr: u64 = d.decompose(&addr, "_DEVICE_OBJECT.AttachedDevice")?;
let mut attached_devices: Vec<Value> = Vec::new();
while attached_ptr != 0 {
let attached = Address::from_base(attached_ptr);
let attached_device_type: u32 =
d.decompose(&attached, "_DEVICE_OBJECT.DeviceType")?;
attached_devices.push(json!({
"address": format!("0x{:x}", attached_ptr),
"type": "_DEVICE_OBJECT",
"devicetype": get_device_type(attached_device_type)
}));
attached_ptr = d.decompose(&attached, "_DEVICE_OBJECT.AttachedDevice")?;
}
driver_devices.push(json!({
"address": format!("0x{:x}", device_ptr),
"type": "_DEVICE_OBJECT",
"devicetype": get_device_type(device_type),
"attached": attached_devices
}));
device_ptr = d.decompose(&addr, "_DEVICE_OBJECT.NextDevice")?;
}
driver_devices
};
Ok(json!({
"address": format!("0x{:x}", a.address()),
"type": "_DRIVER_OBJECT",
"device": devicename,
"hardware": hardware,
"major_function": major_function.into_iter()
.map(|func| format!("0x{:x}", func))
.collect::<Vec<String>>(),
"servicekey": servicekey,
"start": format!("0x{:x}", start),
"init": format!("0x{:x}", init),
"unload": format!("0x{:x}", unload),
"size": format!("0x{:x}", size),
"devicetree": devices
}))
}
pub fn make_ldr(d: &DriverState, a: &Address) -> BoxResult<Value> {
let dllbase: u64 = d.decompose(a, "_LDR_DATA_TABLE_ENTRY.DllBase")?;
let entry: u64 = d.decompose(a, "_LDR_DATA_TABLE_ENTRY.EntryPoint")?;
let size: u64 = d.decompose(a, "_LDR_DATA_TABLE_ENTRY.SizeOfImage")?;
let fullname_ptr = d.address_of(a, "_LDR_DATA_TABLE_ENTRY.FullDllName")?;
let basename_ptr = d.address_of(a, "_LDR_DATA_TABLE_ENTRY.BaseDllName")?;
let fullname = d.get_unicode_string(fullname_ptr).unwrap_or("".to_string());
let basename = d.get_unicode_string(basename_ptr).unwrap_or("".to_string());
let ldr_load: Vec<String> =
make_list_entry(d, a.clone(), "_LDR_DATA_TABLE_ENTRY.InLoadOrderLinks")?
.iter()
.map(|x| format!("0x{:x}", x.address()))
.collect();
let ldr_mem: Vec<String> =
make_list_entry(d, a.clone(), "_LDR_DATA_TABLE_ENTRY.InMemoryOrderLinks")?
.iter()
.map(|x| format!("0x{:x}", x.address()))
.collect();
let ldr_init: Vec<String> = make_list_entry(
d,
a.clone(),
"_LDR_DATA_TABLE_ENTRY.InInitializationOrderLinks",
)?
.iter()
.map(|x| format!("0x{:x}", x.address()))
.collect();
Ok(json!({
"address": format!("0x{:x}", a.address()),
"type": "_LDR_DATA_TABLE_ENTRY",
"dllbase": format!("0x{:x}", dllbase),
"entry": format!("0x{:x}", entry),
"size": format!("0x{:x}", size),
"FullName": fullname,
"BaseName": basename,
"ldr_load": ldr_load,
"ldr_mem": ldr_mem,
"ldr_init": ldr_init
}))
}

View File

@ -1,18 +1,18 @@
use std::error::Error;
use std::io;
use std::io::{Read};
use std::path::{PathBuf};
use std::fs::File;
use std::collections::HashMap;
use std::error::Error;
use std::fs::File;
use std::io;
use std::io::Read;
use std::path::PathBuf;
use app_dirs::{app_dir, AppDataType};
use pdb::{
PDB, SymbolData, TypeData, ClassType, ModifierType, Rva,
FallibleIterator, TypeFinder, TypeIndex
ClassType, FallibleIterator, ModifierType, Rva, SymbolData, TypeData, TypeFinder, TypeIndex,
PDB,
};
use app_dirs::{AppInfo, AppDataType, app_dir};
const APP_INFO: AppInfo = AppInfo { name: "lpus", author: "nganhkhoa" };
use crate::address::Address;
use crate::APP_INFO;
const KERNEL_PDB_NAME: &str = "ntkrnlmp.pdb";
const NTOSKRNL_PATH: &str = "C:\\Windows\\System32\\ntoskrnl.exe";
@ -25,7 +25,7 @@ type StructStore = HashMap<String, HashMap<String, (String, u64)>>;
pub struct PdbStore {
pub symbols: SymbolStore,
pub structs: StructStore
pub structs: StructStore,
}
impl PdbStore {
@ -38,25 +38,22 @@ impl PdbStore {
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(member_info) => match member_info.get(v[1]) {
Some((_memtype, offset)) => Some(*offset),
None => None
}
None => None,
},
None => None
None => None,
}
}
else {
} else {
match self.symbols.get(name) {
Some(offset) => Some(*offset),
None => None
None => None,
}
}
}
#[allow(dead_code)]
pub fn addr_decompose(&self, addr: u64, full_name: &str) -> BoxResult<u64>{
pub fn addr_decompose(&self, addr: u64, full_name: &str) -> BoxResult<u64> {
if !full_name.contains(".") {
return Err("Not decomposable".into());
}
@ -64,79 +61,143 @@ impl PdbStore {
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(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());
return Err(format!(
"Cannot dereference pointer at {} {}",
memtype, name_part[1]
)
.into());
}
next.insert(0, memtype);
self.addr_decompose(addr + *offset, &next.join("."))
}
else {
} else {
Ok(addr + *offset)
}
},
None => Err(format!("Not found member {}", name_part[1]).into())
}
None => Err(format!("Not found member {}", name_part[1]).into()),
},
None => Err(format!("Struct {} not found", name_part[0]).into())
None => Err(format!("Struct {} not found", name_part[0]).into()),
}
}
pub fn decompose(&self, source: &Address, full_name: &str) -> BoxResult<Address> {
// println!("decompose {}", full_name);
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();
let member_info = self
.structs
.get(name_part[0])
.ok_or(format!("No struct {}", name_part[0]))?;
let (memtype, offset) = member_info
.get(name_part[1])
.ok_or(format!("No member {} in {}", name_part[1], name_part[0]))?;
if next.len() == 0 {
return Ok(source.clone() + *offset);
}
if memtype.contains("*") {
let mut t = memtype.clone(); // remove *
t.pop();
next.insert(0, &t);
let p = Address::from_ptr(source.clone() + *offset);
self.decompose(&p, &next.join("."))
} else {
next.insert(0, memtype);
self.decompose(&(source.clone() + *offset), &next.join("."))
}
}
#[allow(dead_code)]
pub fn print_default_information(&self) {
let need_symbols = [
"PsLoadedModuleList", "PsActiveProcessHead", "KeNumberNodes",
"PoolBigPageTable", "PoolBigPageTableSize",
"PsLoadedModuleList",
"PsActiveProcessHead",
"KeNumberNodes",
"PoolBigPageTable",
"PoolBigPageTableSize",
// "PoolVector", "ExpNumberOfNonPagedPools",
"KdDebuggerDataBlock", "MmNonPagedPoolStart", "MmNonPagedPoolEnd", // Windows XP
"MiNonPagedPoolStartAligned", "MiNonPagedPoolEnd", "MiNonPagedPoolBitMap", // Windows 7, 8
"MiNonPagedPoolBitMap", "MiNonPagedPoolVaBitMap",
"MiState" // Windows 10
"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(
"_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![
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
]);
"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![
need_structs.insert(
"_MI_SYSTEM_INFORMATION",
vec![
"Hardware", // windows 10 2016+
"SystemNodeInformation" // windows 10 2015
]);
need_structs.insert("_MI_HARDWARE_STATE", vec![
"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",
"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
]);
"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
@ -153,36 +214,60 @@ impl PdbStore {
Some(member_info) => {
for &member in members {
match member_info.get(member) {
Some((memtype, offset)) =>
println!("0x{:x} {} {}.{}", offset, memtype, struct_name, member),
Some((memtype, offset)) => {
println!("0x{:x} {} {}.{}", offset, memtype, struct_name, member)
}
None => {}
}
}
},
}
None => {}
}
}
}
pub fn dt(&self, struct_name: &str) -> BoxResult<()> {
let member_info = self
.structs
.get(struct_name)
.ok_or(format!("no struct named {}", struct_name))?;
let (_, struct_size) = member_info.get("struct_size").ok_or("")?;
println!("// 0x{:x} bytes", struct_size);
println!("struct {} {{", struct_name);
// Vec<(offset, type, name)>
let mut members: Vec<(u64, String, String)> = Vec::new();
for (name, (t, offset)) in member_info.iter() {
if name != "struct_size" {
members.push((*offset, t.to_string(), name.to_string()));
}
}
members.sort_by(|(o1, _, _), (o2, _, _)| o1.partial_cmp(o2).unwrap());
for (offset, memtype, member) in members.iter() {
println!(" +0x{:x} {} {};", offset, memtype, member);
}
println!("}} // {}", struct_name);
Ok(())
}
}
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::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)
},
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")
// },
@ -210,28 +295,82 @@ fn get_type_as_str(type_finder: &TypeFinder, typ: &TypeIndex) -> String {
TypeData::Procedure(pt) => {
let rettype = match pt.return_type {
Some(rt) => get_type_as_str(type_finder, &rt),
_ => "UNKNOWN".to_string()
_ => "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))
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")
@ -239,25 +378,21 @@ fn get_type_as_str(type_finder: &TypeFinder, typ: &TypeIndex) -> String {
// TypeData::Bitfield(bft) => {
// format!("bitfield")
// },
TypeData::FieldList(_flt) => {
format!("fieldlist")
},
TypeData::FieldList(_flt) => format!("fieldlist"),
// TypeData::ArgumentList(alt) => {
// format!("arglist")
// },
// TypeData::MethodList(mlt) => {
// format!("methodlist")
// },
unk => {
match unk.name() {
unk => match unk.name() {
Some(s) => format!("{}", s.to_string()),
_ => "UNNOWN".to_string()
}
}
_ => "UNNOWN".to_string(),
},
}
}
fn get_guid_age(exe_file: &str) -> BoxResult<(String, u32)>{
fn get_guid_age(exe_file: &str) -> BoxResult<(String, u32)> {
// TODO: Check file existance
let mut file = File::open(exe_file)?;
@ -275,22 +410,36 @@ fn get_guid_age(exe_file: &str) -> BoxResult<(String, u32)>{
buffiter.next().unwrap(),
buffiter.next().unwrap(),
buffiter.next().unwrap(),
].concat();
]
.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("");
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 age = u32::from_le_bytes([raw_age[0], raw_age[1], raw_age[2], raw_age[3]]);
Ok((guid, age))
}
@ -304,14 +453,20 @@ fn pdb_exists(pdbname: &str, guid: &str, age: u32) -> BoxResult<(bool, PathBuf)>
// |--file.pdb
// |--|--GUID
// |--|--|--file.pdb
let mut pdb_location = app_dir(AppDataType::UserData, &APP_INFO,
&format!("{}/{}/{}", pdbname, guid, age))?;
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);
let downloadurl = format!(
"{}/{}/{}{:X}/{}",
PDB_SERVER_PATH, pdbname, guid, age, pdbname
);
println!("{}", downloadurl);
let mut resp = reqwest::blocking::get(&downloadurl)?;
@ -336,8 +491,12 @@ pub fn parse_pdb() -> BoxResult<PdbStore> {
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));
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();
@ -356,9 +515,8 @@ pub fn parse_pdb() -> BoxResult<PdbStore> {
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);
},
_ => {
}
_ => {}
}
}
@ -366,29 +524,50 @@ pub fn parse_pdb() -> BoxResult<PdbStore> {
iter = type_information.iter();
while let Some(typ) = iter.next().unwrap() {
match typ.parse() {
Ok(TypeData::Class(ClassType {name, fields: Some(fields), size, ..})) => {
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));
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));
format!("{}", member.name),
(mem_typ, member.offset as u64),
);
}
}
}
_ => {}
}
struct_extracted.insert(format!("{}", name), struct_fields);
},
}
_ => {}
}
}
{
// https://github.com/Zer0Mem0ry/ntoskrnl/blob/master/Include/mm.h#L1107
let mut unload_driver_member = HashMap::new();
unload_driver_member.insert("struct_size".to_string(), ("U32".to_string(), 0x30));
unload_driver_member.insert("Name".to_string(), ("_UNICODE_STRING".to_string(), 0));
unload_driver_member.insert("StartAddress".to_string(), ("PVOID".to_string(), 0x10));
unload_driver_member.insert("EndAddress".to_string(), ("PVOID".to_string(), 0x18));
unload_driver_member.insert(
"CurrentTime".to_string(),
("_LARGE_INTEGER".to_string(), 0x20),
);
struct_extracted.insert("_UNLOADED_DRIVERS".to_string(), unload_driver_member);
}
Ok(PdbStore {
symbols: symbol_extracted,
structs: struct_extracted
structs: struct_extracted,
})
}

View File

@ -1,42 +1,66 @@
use std::ffi::{c_void, CString};
use std::mem::{transmute, size_of_val};
use std::mem::{size_of_val, transmute};
use std::ptr::null_mut;
use std::time::{SystemTime, UNIX_EPOCH};
use app_dirs::{app_dir, AppDataType};
use widestring::U16CString;
use winapi::shared::ntdef::*;
use crate::APP_INFO;
use winapi::shared::minwindef::{DWORD, HKEY, HMODULE};
use winapi::shared::ntdef::*;
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
FILE_ATTRIBUTE_NORMAL, GENERIC_READ, GENERIC_WRITE, KEY_WRITE, LUID_AND_ATTRIBUTES,
OSVERSIONINFOW, PRTL_OSVERSIONINFOW, REG_DWORD, REG_OPTION_NON_VOLATILE, REG_SZ,
SE_PRIVILEGE_ENABLED, TOKEN_ADJUST_PRIVILEGES, TOKEN_PRIVILEGES,
};
use winapi::um::ioapiset::{DeviceIoControl};
use winapi::um::errhandlingapi::{GetLastError};
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::handleapi::{CloseHandle, INVALID_HANDLE_VALUE};
use winapi::um::ioapiset::DeviceIoControl;
use winapi::um::libloaderapi::{GetProcAddress, LoadLibraryA};
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};
use winapi::um::securitybaseapi::AdjustTokenPrivileges;
use winapi::um::sysinfoapi::GetTickCount64;
use winapi::um::winbase::LookupPrivilegeValueA;
use winapi::um::winreg::{RegCloseKey, RegCreateKeyExA, RegSetValueExA, HKEY_LOCAL_MACHINE};
const STR_DRIVER_REGISTRY_PATH: &str = "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\lpus";
const STR_DRIVER_REGISTRY_PATH: &str =
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\lpus";
#[allow(dead_code)]
#[derive(Debug, Copy, Clone)]
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub enum WindowsVersion {
Windows7,
Windows8,
Windows10Legacy,
Windows10_2015,
Windows10_2016,
Windows10_2017,
Windows10_2018,
Windows10_2019,
Windows10_2020,
Windows10FastRing,
Windows10VersionUnknown
WindowsFastRing,
WindowsUnknown,
}
impl WindowsVersion {
pub fn not_supported(self) -> bool {
match self {
WindowsVersion::Windows10Legacy
| WindowsVersion::Windows10_2015
| WindowsVersion::Windows10_2016
| WindowsVersion::Windows10_2017
| WindowsVersion::Windows8
| WindowsVersion::WindowsUnknown => true,
_ => false,
}
}
pub fn is_supported(self) -> bool {
!self.not_supported()
}
}
#[allow(dead_code)]
@ -60,8 +84,17 @@ impl WindowsFFI {
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_driver_path = {
let mut driver_location =
app_dir(AppDataType::UserData, &APP_INFO, &format!("driver")).unwrap();
driver_location.push("lpus.sys");
if driver_location.is_file() {
let p = driver_location.to_str().unwrap();
CString::new(format!("\\??\\{}", p)).unwrap()
} else {
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();
@ -99,25 +132,43 @@ impl WindowsFFI {
// 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()
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_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)
(
str_image_path.as_ptr(),
REG_SZ,
str_driver_path.as_ptr() as *const u8,
str_driver_path.to_bytes().len() + 1,
),
];
for &(key, keytype, value_ptr, size_in_bytes) in &registry_values {
RegSetValueExA(
registry_key, key, 0,
keytype, value_ptr, size_in_bytes as u32
registry_key,
key,
0,
keytype,
value_ptr,
size_in_bytes as u32,
);
}
RegCloseKey(registry_key);
@ -125,28 +176,46 @@ impl WindowsFFI {
// Setup privilege SeLoadDriverPrivilege
let mut token_handle: HANDLE = null_mut();
let mut luid = LUID::default();
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &mut token_handle);
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
}]
Attributes: SE_PRIVILEGE_ENABLED,
}],
};
AdjustTokenPrivileges(
token_handle, 0, &mut new_token_state, 16, null_mut(), null_mut());
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 {
// 2600 => WindowsVersion::WindowsXP,
// 6000 | 6001 | 6002 => WindowsVersion::WindowsVista,
7600 | 7601 => WindowsVersion::Windows7,
9200 | 9600 => WindowsVersion::Windows8,
10240 => WindowsVersion::Windows10Legacy,
10586 => WindowsVersion::Windows10_2015,
14393 => WindowsVersion::Windows10_2016,
15063 | 16299 => WindowsVersion::Windows10_2017,
17134 | 17763 => WindowsVersion::Windows10_2018,
18362 | 18363 => WindowsVersion::Windows10_2019,
18363 | 18362 => WindowsVersion::Windows10_2019,
19041 => WindowsVersion::Windows10_2020,
_ if version_info.dwBuildNumber >= 19536 => WindowsVersion::Windows10FastRing,
_ => WindowsVersion::Windows10VersionUnknown
x if x >= 19536 => WindowsVersion::WindowsFastRing,
_ => WindowsVersion::WindowsUnknown,
};
Self {
@ -157,36 +226,47 @@ impl WindowsFFI {
nt_load_driver,
nt_unload_driver,
rtl_init_unicode_str,
rtl_get_version
rtl_get_version,
}
}
pub fn driver_loaded(self) -> bool {
pub fn driver_loaded(&self) -> bool {
self.driver_handle != INVALID_HANDLE_VALUE
}
pub fn file_connect(&mut self) {
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;
}
}
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);
(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;
}
self.file_connect();
status
}
@ -204,7 +284,8 @@ impl WindowsFFI {
#[allow(dead_code)]
pub fn print_version(&self) {
println!("Windows version: {}.{}.{} {:?}",
println!(
"Windows version: {}.{}.{} {:?}",
self.version_info.dwMajorVersion,
self.version_info.dwMinorVersion,
self.version_info.dwBuildNumber,
@ -212,6 +293,15 @@ impl WindowsFFI {
);
}
pub fn to_epoch(&self, filetime: u64) -> u64 {
let windows_epoch_diff = 11644473600000 * 10000;
if filetime < windows_epoch_diff {
return 0;
}
let process_time_epoch = (filetime - windows_epoch_diff) / 10000;
process_time_epoch
}
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;
@ -219,9 +309,13 @@ impl WindowsFFI {
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;
let process_time_epoch = (filetime - windows_epoch_diff) / 10000; // in milisecond
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 - (10 * 3600 * 1000/* 10 minutes penalty */);
if process_time_epoch < system_start_up_time_ms {
false
@ -233,21 +327,36 @@ impl WindowsFFI {
}
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)
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 {
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());
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());
}