One binary setup
This commit is contained in:
parent
967684f140
commit
e2eac767e0
119
Cargo.lock
generated
119
Cargo.lock
generated
@ -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"
|
||||
@ -139,6 +147,20 @@ 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"
|
||||
@ -509,14 +531,17 @@ 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)",
|
||||
"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)",
|
||||
"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)",
|
||||
]
|
||||
@ -955,6 +980,35 @@ dependencies = [
|
||||
"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"
|
||||
@ -986,6 +1040,14 @@ 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"
|
||||
@ -1112,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"
|
||||
@ -1155,6 +1222,14 @@ dependencies = [
|
||||
"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"
|
||||
@ -1292,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"
|
||||
@ -1307,6 +1396,16 @@ 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"
|
||||
@ -1447,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"
|
||||
@ -1475,6 +1582,7 @@ 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"
|
||||
@ -1495,6 +1603,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"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"
|
||||
@ -1587,9 +1696,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"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"
|
||||
@ -1606,10 +1719,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"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"
|
||||
@ -1629,9 +1744,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"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"
|
||||
@ -1648,6 +1766,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"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"
|
||||
|
@ -25,3 +25,8 @@ 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"
|
||||
|
8
build.rs
Normal file
8
build.rs
Normal 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!");
|
||||
}
|
143
src/bin/lpus.rs
Normal file
143
src/bin/lpus.rs
Normal 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(())
|
||||
}
|
190
src/commands.rs
Normal file
190
src/commands.rs
Normal 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();
|
||||
}
|
@ -14,8 +14,7 @@ use winapi::um::winioctl::{
|
||||
|
||||
use crate::address::Address;
|
||||
use crate::ioctl_protocol::{
|
||||
DerefAddr, InputData, /* OutputData, */ Nothing, OffsetData,
|
||||
ScanPoolData, /* HideProcess, */
|
||||
DerefAddr, HideProcess, InputData, /* OutputData, */ Nothing, OffsetData, ScanPoolData,
|
||||
};
|
||||
use crate::pdb_store::{parse_pdb, PdbStore};
|
||||
use crate::windows::{WindowsFFI, WindowsVersion};
|
||||
@ -120,10 +119,34 @@ impl DriverState {
|
||||
self.windows_ffi.unload_driver()
|
||||
}
|
||||
|
||||
pub fn connect(&mut self) {
|
||||
self.windows_ffi.file_connect();
|
||||
}
|
||||
|
||||
pub fn is_supported(&self) -> bool {
|
||||
self.windows_ffi.short_version.is_supported()
|
||||
}
|
||||
|
||||
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.windows_ffi.device_io(
|
||||
DriverAction::HideProcess.get_code(),
|
||||
&mut input,
|
||||
&mut Nothing,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn use_old_tag(&self) -> bool {
|
||||
// use old tag to scan, for Window < 8
|
||||
if self.windows_ffi.short_version < WindowsVersion::Windows8 {
|
||||
|
17
src/lib.rs
17
src/lib.rs
@ -2,12 +2,14 @@ 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;
|
||||
|
||||
use app_dirs::AppInfo;
|
||||
use chrono::{DateTime, Local, TimeZone};
|
||||
use serde_json::{json, Value};
|
||||
use std::error::Error;
|
||||
@ -18,6 +20,11 @@ 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;
|
||||
@ -369,9 +376,7 @@ pub fn scan_driver(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
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
|
||||
/* && ftype == 5u16 */
|
||||
{
|
||||
if (size as u64) == dob_size {
|
||||
break;
|
||||
}
|
||||
try_ptr += 0x4; // search exhaustively
|
||||
@ -538,7 +543,7 @@ pub fn traverse_unloadeddrivers(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
|
||||
let unload_array = driver.deref_addr_new::<u64>(unload_array_ptr.address());
|
||||
if unload_array == 0 {
|
||||
return Err("The unload driver list is null".into());
|
||||
return Err("The unload driver list pointer is null".into());
|
||||
}
|
||||
|
||||
// by reversing MmLocateUnloadedDriver
|
||||
@ -553,6 +558,7 @@ pub fn traverse_unloadeddrivers(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
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()),
|
||||
@ -560,7 +566,8 @@ pub fn traverse_unloadeddrivers(driver: &DriverState) -> BoxResult<Vec<Value>> {
|
||||
"name": name,
|
||||
"start_addr": format!("0x{:x}", start_addr),
|
||||
"end_addr": format!("0x{:x}", end_addr),
|
||||
"current_time": driver.windows_ffi.to_epoch(current_time)
|
||||
"time_unix": time.timestamp(),
|
||||
"time_rfc2822": time.to_rfc2822()
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -5,18 +5,14 @@ use std::io;
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use app_dirs::{app_dir, AppDataType, AppInfo};
|
||||
use app_dirs::{app_dir, AppDataType};
|
||||
use pdb::{
|
||||
ClassType, FallibleIterator, ModifierType, Rva, SymbolData, TypeData, TypeFinder, TypeIndex,
|
||||
PDB,
|
||||
};
|
||||
|
||||
use crate::address::Address;
|
||||
|
||||
const APP_INFO: AppInfo = AppInfo {
|
||||
name: "lpus",
|
||||
author: "nganhkhoa",
|
||||
};
|
||||
use crate::APP_INFO;
|
||||
|
||||
const KERNEL_PDB_NAME: &str = "ntkrnlmp.pdb";
|
||||
const NTOSKRNL_PATH: &str = "C:\\Windows\\System32\\ntoskrnl.exe";
|
||||
|
@ -2,8 +2,12 @@ use std::ffi::{c_void, CString};
|
||||
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 crate::APP_INFO;
|
||||
|
||||
use winapi::shared::minwindef::{DWORD, HKEY, HMODULE};
|
||||
use winapi::shared::ntdef::*;
|
||||
use winapi::um::winnt::{
|
||||
@ -80,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();
|
||||
@ -217,21 +230,11 @@ impl WindowsFFI {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn driver_loaded(self) -> bool {
|
||||
pub fn driver_loaded(&self) -> bool {
|
||||
self.driver_handle != INVALID_HANDLE_VALUE
|
||||
}
|
||||
|
||||
pub fn load_driver(&mut self) -> NTSTATUS {
|
||||
// TODO: Move this to new()
|
||||
// If we move this function to new(), self.driver_handle will be init, and thus no mut here
|
||||
let str_driver_reg = U16CString::from_str(STR_DRIVER_REGISTRY_PATH).unwrap();
|
||||
let mut str_driver_reg_unicode = UNICODE_STRING::default();
|
||||
(self.rtl_init_unicode_str)(
|
||||
&mut str_driver_reg_unicode,
|
||||
str_driver_reg.as_ptr() as *const u16,
|
||||
);
|
||||
let status = (self.nt_load_driver)(&mut str_driver_reg_unicode);
|
||||
|
||||
pub fn file_connect(&mut self) {
|
||||
let filename = CString::new("\\\\.\\poolscanner").unwrap();
|
||||
let driver_file_handle: HANDLE = unsafe {
|
||||
CreateFileA(
|
||||
@ -250,6 +253,20 @@ impl WindowsFFI {
|
||||
} 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,
|
||||
);
|
||||
let status = (self.nt_load_driver)(&mut str_driver_reg_unicode);
|
||||
|
||||
self.file_connect();
|
||||
status
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user