From a63f45235e6fe3da6648722bb26293d99c0e2c00 Mon Sep 17 00:00:00 2001 From: frk Date: Thu, 11 Jan 2018 15:42:43 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20Initial=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + Cargo.lock | 275 +++++++++++++++++ Cargo.toml | 12 + LICENSE | 21 ++ memlib-rs/Cargo.lock | 223 ++++++++++++++ memlib-rs/Cargo.toml | 11 + memlib-rs/src/findpattern.rs | 23 ++ memlib-rs/src/lib.rs | 4 + memlib-rs/src/module.rs | 121 ++++++++ memlib-rs/src/process.rs | 123 ++++++++ memlib-rs/src/snapshot.rs | 41 +++ src/csgo/mod.rs | 1 + src/csgo/netvars.rs | 203 +++++++++++++ src/default.json | 561 +++++++++++++++++++++++++++++++++++ src/main.rs | 271 +++++++++++++++++ 15 files changed, 1893 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 memlib-rs/Cargo.lock create mode 100644 memlib-rs/Cargo.toml create mode 100644 memlib-rs/src/findpattern.rs create mode 100644 memlib-rs/src/lib.rs create mode 100644 memlib-rs/src/module.rs create mode 100644 memlib-rs/src/process.rs create mode 100644 memlib-rs/src/snapshot.rs create mode 100644 src/csgo/mod.rs create mode 100644 src/csgo/netvars.rs create mode 100644 src/default.json create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c3d9ae5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +target +csgo.* +.vscode diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..7e43357 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,275 @@ +[[package]] +name = "aho-corasick" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "chrono" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hazedumper-rs" +version = "1.0.0" +dependencies = [ + "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", + "memlib 0.2.0", + "toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "json" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memlib" +version = "0.2.0" +dependencies = [ + "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-bigint" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-complex" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-iter" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-rational" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "regex" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "thread_local" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "toml" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "1.0.0" +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 = "winapi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" +"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" +"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483" +"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" +"checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb" +"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" +"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" +"checksum num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "bdc1494b5912f088f260b775799468d9b9209ac60885d8186a547a0476289e23" +"checksum num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "58de7b4bf7cf5dbecb635a5797d489864eadd03b107930cbccf9e0fd7428b47c" +"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" +"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" +"checksum num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7cb72a95250d8a370105c828f388932373e0e94414919891a0f945222310fe" +"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" +"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" +"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" +"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" +"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" +"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" +"checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b09fb3b6f248ea4cd42c9a65113a847d612e17505d6ebd1f7357ad68a8bf8693" +"checksum winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec6667f60c23eca65c561e63a13d81b44234c2e38a6b6c959025ee907ec614cc" +"checksum winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98f12c52b2630cd05d2c3ffd8e008f7f48252c042b4871c72aed9dc733b96668" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..872081e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +authors = ["frk "] +name = "hazedumper-rs" +version = "1.0.0" + +[dependencies] +chrono = "0.4" +json = "0.11" +toml = "0.2" + +[dependencies.memlib] +path = "./memlib-rs" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5aec5bf --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016-2018 frk + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/memlib-rs/Cargo.lock b/memlib-rs/Cargo.lock new file mode 100644 index 0000000..cc82f38 --- /dev/null +++ b/memlib-rs/Cargo.lock @@ -0,0 +1,223 @@ +[[package]] +name = "aho-corasick" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memlib" +version = "0.2.0" +dependencies = [ + "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-bigint" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-complex" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-iter" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-rational" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "thread_local" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "1.0.0" +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 = "winapi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" +"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" +"checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb" +"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" +"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" +"checksum num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "bdc1494b5912f088f260b775799468d9b9209ac60885d8186a547a0476289e23" +"checksum num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "58de7b4bf7cf5dbecb635a5797d489864eadd03b107930cbccf9e0fd7428b47c" +"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" +"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" +"checksum num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7cb72a95250d8a370105c828f388932373e0e94414919891a0f945222310fe" +"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" +"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" +"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" +"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b09fb3b6f248ea4cd42c9a65113a847d612e17505d6ebd1f7357ad68a8bf8693" +"checksum winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec6667f60c23eca65c561e63a13d81b44234c2e38a6b6c959025ee907ec614cc" +"checksum winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98f12c52b2630cd05d2c3ffd8e008f7f48252c042b4871c72aed9dc733b96668" diff --git a/memlib-rs/Cargo.toml b/memlib-rs/Cargo.toml new file mode 100644 index 0000000..e76d98e --- /dev/null +++ b/memlib-rs/Cargo.toml @@ -0,0 +1,11 @@ +[package] +authors = ["frk "] +name = "memlib" +version = "0.2.0" + +[dependencies] +num = "0.1" +regex = "0.2" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["basetsd","handleapi","memoryapi","minwindef","ntdef","processthreadsapi","tlhelp32","winnt"] } diff --git a/memlib-rs/src/findpattern.rs b/memlib-rs/src/findpattern.rs new file mode 100644 index 0000000..9abc7c4 --- /dev/null +++ b/memlib-rs/src/findpattern.rs @@ -0,0 +1,23 @@ +extern crate regex; +use self::regex::bytes::Regex; + +/// Enables the user to generate a byte regex out of the normal signature format. +pub fn generate_regex(raw: &str) -> Option { + let mut res = raw.to_string() + .split_whitespace() + .map(|x| match &x { + &"?" => ".".to_string(), + x => format!("\\x{}", x), + }) + .collect::>() + .join(""); + res.insert_str(0, "(?s-u)"); + Regex::new(&res).ok() +} + +/// Find pattern. +pub fn find_pattern(data: &[u8], pattern: &str) -> Option { + generate_regex(pattern) + .and_then(|r| r.find(data)) + .and_then(|m| Some(m.start())) +} diff --git a/memlib-rs/src/lib.rs b/memlib-rs/src/lib.rs new file mode 100644 index 0000000..898914a --- /dev/null +++ b/memlib-rs/src/lib.rs @@ -0,0 +1,4 @@ +pub mod findpattern; +pub mod process; +pub mod module; +mod snapshot; diff --git a/memlib-rs/src/module.rs b/memlib-rs/src/module.rs new file mode 100644 index 0000000..eccf613 --- /dev/null +++ b/memlib-rs/src/module.rs @@ -0,0 +1,121 @@ +extern crate num; +extern crate winapi; + +use std::{mem, ptr}; + +use findpattern; +use snapshot::SnapshotHandle; + +use self::winapi::shared::basetsd::SIZE_T; +use self::winapi::shared::minwindef::{DWORD, LPCVOID, LPVOID}; +use self::winapi::shared::minwindef::FALSE; +use self::winapi::shared::ntdef::HANDLE; +use self::winapi::um::memoryapi::ReadProcessMemory; +use self::winapi::um::tlhelp32::{MODULEENTRY32W, Module32FirstW, Module32NextW, TH32CS_SNAPMODULE, + TH32CS_SNAPMODULE32}; + +#[derive(Debug, Clone)] +pub struct Module { + pub name: String, + pub base: usize, + pub size: usize, + pub data: Vec, +} + +/// Enum for the different signature modes: +/// +/// - `Nop`: No operation +/// - `Read`: Read address +/// - `Substract`: Subtract base address +/// - `ReadSubtract`: Read and subtract base address +#[derive(Debug, Clone, PartialEq)] +pub enum Mode { + Nop, + Read, + Subtract, + ReadSubtract, +} + +impl Module { + fn new() -> Self { + Module { + name: "".to_string(), + base: 0, + size: 0, + data: vec![], + } + } + + pub fn find_pattern( + &self, + pattern: &str, + mode: Mode, + offset: i32, + extra: i32, + ) -> Option + where + T: num::NumCast, + { + findpattern::find_pattern(&self.data, pattern).and_then(|pos| { + let mut pos = pos as isize; + pos += offset as isize; + + pos = match mode { + Mode::Read | Mode::ReadSubtract => { + let tmp: T = + unsafe { mem::transmute_copy(self.data.get_unchecked(pos as usize)) }; + num::cast(tmp).unwrap_or(0) + } + _ => pos, + }; + + pos = match mode { + Mode::Nop => pos + self.base as isize, + Mode::ReadSubtract => pos - self.base as isize, + _ => pos, + }; + + Some((pos + extra as isize) as usize) + }) + } +} + +pub fn get(name: &str, pid: u32, handle: &HANDLE) -> Option { + if name.is_empty() || pid == 0 || handle.is_null() { + return None; + } + + let snapshot = SnapshotHandle::new(pid, TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32)?; + + let mut remote_module: MODULEENTRY32W = unsafe { mem::zeroed() }; + remote_module.dwSize = mem::size_of::() as DWORD; + + if unsafe { Module32FirstW(*snapshot, &mut remote_module) } != 0 { + loop { + let s = String::from_utf16_lossy(&remote_module.szModule) + .trim_matches('\0') + .to_string(); + if name == s { + let mut buffer = Module::new(); + buffer.name = s; + buffer.base = remote_module.modBaseAddr as usize; + buffer.size = remote_module.modBaseSize as usize; + buffer.data.resize(buffer.size, 0u8); + unsafe { + ReadProcessMemory( + *handle, + buffer.base as LPCVOID, + buffer.data.as_mut_ptr() as LPVOID, + buffer.size as SIZE_T, + ptr::null_mut::(), + ); + } + return Some(buffer); + } + if unsafe { Module32NextW(*snapshot, &mut remote_module) } == FALSE { + break; + } + } + } + None +} diff --git a/memlib-rs/src/process.rs b/memlib-rs/src/process.rs new file mode 100644 index 0000000..c7ecd31 --- /dev/null +++ b/memlib-rs/src/process.rs @@ -0,0 +1,123 @@ +extern crate winapi; + +use std::{mem, ptr}; +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; + +use self::winapi::shared::basetsd::SIZE_T; +use self::winapi::shared::minwindef::{FALSE, LPCVOID, LPVOID, TRUE}; +use self::winapi::shared::ntdef::HANDLE; +use self::winapi::um::handleapi::CloseHandle; +use self::winapi::um::memoryapi::{ReadProcessMemory, WriteProcessMemory}; +use self::winapi::um::processthreadsapi::OpenProcess; +use self::winapi::um::tlhelp32::{PROCESSENTRY32W, Process32FirstW, Process32NextW, + TH32CS_SNAPPROCESS}; +use self::winapi::um::winnt::PROCESS_ALL_ACCESS; + +use snapshot::SnapshotHandle; + +#[derive(Debug)] +pub struct Process { + pub id: u32, + handle: HANDLE, + modules: RefCell>>, +} + +impl Process { + pub fn read(&self, address: usize) -> Option { + let mut buffer = unsafe { mem::zeroed::() }; + match unsafe { + ReadProcessMemory( + self.handle, + address as LPCVOID, + &mut buffer as *mut T as LPVOID, + mem::size_of::() as SIZE_T, + ptr::null_mut::(), + ) + } { + TRUE => Some(buffer), + _ => None, + } + } + + pub fn read_ptr(&self, buf: *mut T, address: usize, count: usize) -> bool { + unsafe { + ReadProcessMemory( + self.handle, + address as LPCVOID, + buf as *mut T as LPVOID, + mem::size_of::() as SIZE_T * count, + ptr::null_mut::(), + ) == TRUE + } + } + + pub fn write(&self, address: u32, buf: &T) -> bool { + unsafe { + WriteProcessMemory( + self.handle, + address as LPVOID, + buf as *const T as LPCVOID, + mem::size_of::() as SIZE_T, + ptr::null_mut::(), + ) == TRUE + } + } +} + +impl Process { + pub fn get_module(&self, name: &str) -> Option> { + let mut b = self.modules.borrow_mut(); + if b.contains_key(name) { + return b.get(name).cloned(); + } + + super::module::get(name, self.id, &self.handle) + .and_then(|m| b.insert(name.to_string(), Rc::new(m))); + + b.get(name).cloned() + } +} + +impl Drop for Process { + fn drop(&mut self) { + if !self.handle.is_null() { + unsafe { CloseHandle(self.handle) }; + } + } +} + +pub fn from_pid(pid: u32) -> Option { + let handle = unsafe { OpenProcess(PROCESS_ALL_ACCESS, 0, pid) }; + if handle.is_null() { + return None; + } + Some(Process { + id: pid, + handle: handle, + modules: RefCell::new(HashMap::new()), + }) +} + +pub fn from_name(name: &str) -> Option { + let snapshot = SnapshotHandle::new(0, TH32CS_SNAPPROCESS)?; + let mut process: PROCESSENTRY32W = unsafe { mem::zeroed() }; + process.dwSize = mem::size_of::() as u32; + + if unsafe { Process32FirstW(*snapshot, &mut process) } == FALSE { + return None; + } + + loop { + let pn = String::from_utf16(&process.szExeFile).unwrap_or_else(|_| String::new()); + if pn.contains(name) { + return from_pid(process.th32ProcessID); + } + if unsafe { Process32NextW(*snapshot, &mut process) } == FALSE { + break; + } + } + + None +} diff --git a/memlib-rs/src/snapshot.rs b/memlib-rs/src/snapshot.rs new file mode 100644 index 0000000..7ce81f3 --- /dev/null +++ b/memlib-rs/src/snapshot.rs @@ -0,0 +1,41 @@ +extern crate winapi; +use std::ops::Deref; + +use self::winapi::shared::ntdef::HANDLE; +use self::winapi::um::handleapi::{CloseHandle, INVALID_HANDLE_VALUE}; +use self::winapi::um::tlhelp32::CreateToolhelp32Snapshot; + +/// Wrapper around the windows `HANDLE` returned from `kernel32::CreateToolhelp32Snapshot`. +pub struct SnapshotHandle { + pub handle: HANDLE, +} + +impl SnapshotHandle { + /// Constructs a new `SnapshotHandle`. + /// + /// Calls the `kernel32::CreateToolhelp32Snapshot` windows api. + pub fn new(pid: u32, flags: u32) -> Option { + let handle = unsafe { CreateToolhelp32Snapshot(flags, pid) }; + if handle.is_null() || handle == INVALID_HANDLE_VALUE { + return None; + } + + Some(SnapshotHandle { handle }) + } +} + +impl Drop for SnapshotHandle { + fn drop(&mut self) { + unsafe { + CloseHandle(self.handle); + } + } +} + +impl Deref for SnapshotHandle { + type Target = HANDLE; + + fn deref(&self) -> &HANDLE { + &self.handle + } +} diff --git a/src/csgo/mod.rs b/src/csgo/mod.rs new file mode 100644 index 0000000..feb24d7 --- /dev/null +++ b/src/csgo/mod.rs @@ -0,0 +1 @@ +pub mod netvars; diff --git a/src/csgo/netvars.rs b/src/csgo/netvars.rs new file mode 100644 index 0000000..818b701 --- /dev/null +++ b/src/csgo/netvars.rs @@ -0,0 +1,203 @@ +extern crate memlib; +use std::collections::HashMap; + +#[derive(Debug)] +pub struct ClientClass { + base: u32, + ptr_next_class: u32, + ptr_recv_table: u32, + class_id: i32, + class_name: String, +} + +#[derive(Debug)] +pub struct RecvTable { + base: u32, + ptr_recv_prop: u32, + count_props: u32, + table_name: String, +} + +#[derive(Debug)] +pub struct RecvProp { + base: u32, + ptr_recv_table: u32, + offset: u32, + var_name: String, +} + +#[derive(Debug)] +pub struct NetvarManager { + pub recv_tables: HashMap, +} + +fn read_c_string(process: &memlib::process::Process, offset: usize, count: usize) -> String { + let mut buf = vec![0u8; count]; + process.read_ptr(buf.as_mut_ptr(), offset, count); + + let cstr = String::from_utf8_lossy(&buf).to_string(); + let first_0 = cstr.find('\0').unwrap_or_else(|| cstr.len()); + cstr[..first_0].to_string() +} + +impl ClientClass { + pub fn new() -> Self { + ClientClass { + base: 0, + ptr_next_class: 0, + ptr_recv_table: 0, + class_id: 0, + class_name: "".to_string(), + } + } + + pub fn update(&mut self, process: &memlib::process::Process, ptr: u32) { + let ptr_class_name: u32 = process.read(ptr as usize + 0x8).unwrap(); + + self.base = ptr; + self.ptr_next_class = process.read(ptr as usize + 0x10).unwrap(); + self.ptr_recv_table = process.read(ptr as usize + 0xC).unwrap(); + self.class_id = process.read(ptr as usize + 0x14).unwrap(); + self.class_name = read_c_string(process, ptr_class_name as usize, 0x20); + } + + pub fn get(process: &memlib::process::Process, ptr: u32) -> Option { + if ptr == 0 { + return None; + } + + let mut buf = Self::new(); + buf.update(process, ptr); + Some(buf) + } +} + +impl RecvTable { + pub fn new() -> Self { + RecvTable { + base: 0, + ptr_recv_prop: 0, + count_props: 0, + table_name: "".to_string(), + } + } + + pub fn update(&mut self, process: &memlib::process::Process, ptr: u32) { + let ptr_table_name: u32 = process.read(ptr as usize + 0xC).unwrap(); + + self.base = ptr; + self.ptr_recv_prop = process.read(ptr as usize).unwrap(); + self.count_props = process.read(ptr as usize + 0x4).unwrap(); + self.table_name = read_c_string(process, ptr_table_name as usize, 0x20); + } + + pub fn get(process: &memlib::process::Process, ptr: u32) -> Option { + if ptr == 0 { + return None; + } + + let mut buf = Self::new(); + buf.update(process, ptr); + Some(buf) + } + + fn get_prop(&self, i: u32) -> u32 { + self.ptr_recv_prop + 0x3C * i + } +} + +impl RecvProp { + pub fn new() -> Self { + RecvProp { + base: 0, + ptr_recv_table: 0, + offset: 0, + var_name: "".to_string(), + } + } + + pub fn update(&mut self, process: &memlib::process::Process, ptr: u32) { + let ptr_var_name: u32 = process.read(ptr as usize).unwrap(); + + self.base = ptr; + self.ptr_recv_table = process.read(ptr as usize + 0x28).unwrap(); + self.offset = process.read(ptr as usize + 0x2C).unwrap(); + self.var_name = read_c_string(process, ptr_var_name as usize, 0x40); + } + + pub fn get(process: &memlib::process::Process, ptr: u32) -> Option { + if ptr == 0 { + return None; + } + + let mut buf = Self::new(); + buf.update(process, ptr); + Some(buf) + } +} + +impl NetvarManager { + fn new() -> Self { + NetvarManager { + recv_tables: HashMap::new(), + } + } + + pub fn load_netdata(process: &memlib::process::Process, mut ptr_class: usize) -> Option { + let process: &memlib::process::Process = process; + let mut manager = Self::new(); + + // We have to dereference twice + ptr_class = process.read(ptr_class).unwrap(); + + while let Some(cclass) = ClientClass::get(process, ptr_class as u32) { + if let Some(table) = RecvTable::get(process, cclass.ptr_recv_table) { + manager.recv_tables.insert(table.table_name.clone(), table); + } + ptr_class = cclass.ptr_next_class as usize; + } + + Some(manager) + } + + fn get_recv_prop_ref( + &self, + process: &memlib::process::Process, + table: &RecvTable, + prop_name: &str, + ) -> Option { + if table.count_props == 0 { + return None; + } + + let mut offset: usize = 0; + for i in 0..table.count_props { + if let Some(prop) = RecvProp::get(process, table.get_prop(i)) { + RecvTable::get(process, prop.ptr_recv_table).map_or((), |child| { + offset += self.get_recv_prop_ref(process, &child, prop_name) + .map_or(0, |tmp| prop.offset as usize + tmp); + }); + if prop_name == prop.var_name { + return Some(offset + prop.offset as usize); + } + } + } + + if offset > 0 { + Some(offset) + } else { + None + } + } + + pub fn get_recv_prop( + &self, + process: &memlib::process::Process, + table_name: &str, + prop_name: &str, + ) -> Option { + self.recv_tables + .get(table_name) + .and_then(|table| self.get_recv_prop_ref(process, table, prop_name)) + } +} diff --git a/src/default.json b/src/default.json new file mode 100644 index 0000000..1c3cd55 --- /dev/null +++ b/src/default.json @@ -0,0 +1,561 @@ +{ + "netvars": { + "m_ArmorValue": { + "netvar": "m_ArmorValue", + "table": "DT_CSPlayer" + }, + "m_Collision": { + "netvar": "m_Collision", + "table": "DT_BasePlayer" + }, + "m_CollisionGroup": { + "netvar": "m_CollisionGroup", + "table": "DT_CSPlayer" + }, + "m_Local": { + "netvar": "m_Local", + "table": "DT_BasePlayer" + }, + "m_MoveType": { + "netvar": "m_nRenderMode", + "offset": 1, + "table": "DT_CSPlayer" + }, + "m_OriginalOwnerXuidHigh": { + "netvar": "m_OriginalOwnerXuidHigh", + "table": "DT_BaseAttributableItem" + }, + "m_OriginalOwnerXuidLow": { + "netvar": "m_OriginalOwnerXuidLow", + "table": "DT_BaseAttributableItem" + }, + "m_aimPunchAngle": { + "netvar": "m_aimPunchAngle", + "table": "DT_BasePlayer" + }, + "m_aimPunchAngleVel": { + "netvar": "m_aimPunchAngleVel", + "table": "DT_BasePlayer" + }, + "m_bGunGameImmunity": { + "netvar": "m_bGunGameImmunity", + "table": "DT_CSPlayer" + }, + "m_bHasDefuser": { + "netvar": "m_bHasDefuser", + "table": "DT_CSPlayer" + }, + "m_bHasHelmet": { + "netvar": "m_bHasHelmet", + "table": "DT_CSPlayer" + }, + "m_bInReload": { + "netvar": "m_flNextPrimaryAttack", + "offset": 109, + "table": "DT_BaseCombatWeapon" + }, + "m_bIsDefusing": { + "netvar": "m_bIsDefusing", + "table": "DT_CSPlayer" + }, + "m_bIsScoped": { + "netvar": "m_bIsScoped", + "table": "DT_CSPlayer" + }, + "m_bSpotted": { + "netvar": "m_bSpotted", + "table": "DT_BaseEntity" + }, + "m_bSpottedByMask": { + "netvar": "m_bSpottedByMask", + "table": "DT_BaseEntity" + }, + "m_dwBoneMatrix": { + "netvar": "m_nForceBone", + "offset": 28, + "table": "DT_BaseAnimating" + }, + "m_fAccuracyPenalty": { + "netvar": "m_fAccuracyPenalty", + "table": "DT_WeaponCSBase" + }, + "m_fFlags": { + "netvar": "m_fFlags", + "table": "DT_CSPlayer" + }, + "m_flFallbackWear": { + "netvar": "m_flFallbackWear", + "table": "DT_BaseAttributableItem" + }, + "m_flFlashDuration": { + "netvar": "m_flFlashDuration", + "table": "DT_CSPlayer" + }, + "m_flFlashMaxAlpha": { + "netvar": "m_flFlashMaxAlpha", + "table": "DT_CSPlayer" + }, + "m_flNextPrimaryAttack": { + "netvar": "m_flNextPrimaryAttack", + "table": "DT_BaseCombatWeapon" + }, + "m_hActiveWeapon": { + "netvar": "m_hActiveWeapon", + "table": "DT_BasePlayer" + }, + "m_hMyWeapons": { + "netvar": "m_hActiveWeapon", + "offset": -256, + "table": "DT_BasePlayer" + }, + "m_hObserverTarget": { + "netvar": "m_hObserverTarget", + "table": "DT_BasePlayer" + }, + "m_hOwner": { + "netvar": "m_hOwner", + "table": "DT_PredictedViewModel" + }, + "m_hOwnerEntity": { + "netvar": "m_hOwnerEntity", + "table": "DT_CSPlayer" + }, + "m_iAccountID": { + "netvar": "m_iAccountID", + "table": "DT_BaseAttributableItem" + }, + "m_iClip1": { + "netvar": "m_iClip1", + "table": "DT_BaseCombatWeapon" + }, + "m_iCompetitiveRanking": { + "netvar": "m_iCompetitiveRanking", + "table": "DT_CSPlayerResource" + }, + "m_iCompetitiveWins": { + "netvar": "m_iCompetitiveWins", + "table": "DT_CSPlayerResource" + }, + "m_iCrosshairId": { + "netvar": "m_bHasDefuser", + "offset": 92, + "table": "DT_CSPlayer" + }, + "m_iEntityQuality": { + "netvar": "m_iEntityQuality", + "table": "DT_BaseAttributableItem" + }, + "m_iFOVStart": { + "netvar": "m_iFOVStart", + "table": "DT_CSPlayer" + }, + "m_iGlowIndex": { + "netvar": "m_flFlashDuration", + "offset": 24, + "table": "DT_CSPlayer" + }, + "m_iHealth": { + "netvar": "m_iHealth", + "table": "DT_BasePlayer" + }, + "m_iItemDefinitionIndex": { + "netvar": "m_iItemDefinitionIndex", + "table": "DT_BaseCombatWeapon" + }, + "m_iItemIDHigh": { + "netvar": "m_iItemIDHigh", + "table": "DT_BaseAttributableItem" + }, + "m_iObserverMode": { + "netvar": "m_iObserverMode", + "table": "DT_BasePlayer" + }, + "m_iShotsFired": { + "netvar": "m_iShotsFired", + "table": "DT_CSPlayer" + }, + "m_iState": { + "netvar": "m_iState", + "table": "DT_BaseCombatWeapon" + }, + "m_iTeamNum": { + "netvar": "m_iTeamNum", + "table": "DT_BasePlayer" + }, + "m_lifeState": { + "netvar": "m_lifeState", + "table": "DT_CSPlayer" + }, + "m_nFallbackPaintKit": { + "netvar": "m_nFallbackPaintKit", + "table": "DT_BaseAttributableItem" + }, + "m_nFallbackSeed": { + "netvar": "m_nFallbackSeed", + "table": "DT_BaseAttributableItem" + }, + "m_nFallbackStatTrak": { + "netvar": "m_nFallbackStatTrak", + "table": "DT_BaseAttributableItem" + }, + "m_nForceBone": { + "netvar": "m_nForceBone", + "table": "DT_BaseAnimating" + }, + "m_nTickBase": { + "netvar": "m_nTickBase", + "table": "DT_BasePlayer" + }, + "m_rgflCoordinateFrame": { + "netvar": "m_CollisionGroup", + "offset": -48, + "table": "DT_CSPlayer" + }, + "m_szCustomName": { + "netvar": "m_szCustomName", + "table": "DT_BaseAttributableItem" + }, + "m_szLastPlaceName": { + "netvar": "m_szLastPlaceName", + "table": "DT_CSPlayer" + }, + "m_vecOrigin": { + "netvar": "m_vecOrigin", + "table": "DT_BasePlayer" + }, + "m_vecVelocity": { + "netvar": "m_vecVelocity[0]", + "table": "DT_CSPlayer" + }, + "m_vecViewOffset": { + "netvar": "m_vecViewOffset[0]", + "table": "DT_CSPlayer" + }, + "m_viewPunchAngle": { + "netvar": "m_viewPunchAngle", + "table": "DT_BasePlayer" + } + }, + "signatures": { + "dwClientState": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "engine.dll", + "offset": 1, + "pattern": "A1 ? ? ? ? 33 D2 6A 00 6A 00 33 C9 89 B0" + }, + "dwClientState_GetLocalPlayer": { + "extra": 0, + "mode_read": true, + "mode_subtract": false, + "module": "engine.dll", + "offset": 2, + "pattern": "8B 80 ? ? ? ? 40 C3" + }, + "dwClientState_IsHLTV": { + "extra": 0, + "mode_read": true, + "mode_subtract": false, + "module": "engine.dll", + "offset": 2, + "pattern": "80 BF ? ? ? ? ? 0F 84 ? ? ? ? 32 DB" + }, + "dwClientState_Map": { + "extra": 0, + "mode_read": true, + "mode_subtract": false, + "module": "engine.dll", + "offset": 1, + "pattern": "05 ? ? ? ? C3 CC CC CC CC CC CC CC A1" + }, + "dwClientState_MapDirectory": { + "extra": 0, + "mode_read": true, + "mode_subtract": false, + "module": "engine.dll", + "offset": 1, + "pattern": "05 ? ? ? ? C3 CC CC CC CC CC CC CC 80 3D" + }, + "dwClientState_MaxPlayer": { + "extra": 0, + "mode_read": true, + "mode_subtract": false, + "module": "engine.dll", + "offset": 7, + "pattern": "A1 ? ? ? ? 8B 80 ? ? ? ? C3 CC CC CC CC 55 8B EC 8A 45 08" + }, + "dwClientState_PlayerInfo": { + "extra": 0, + "mode_read": true, + "mode_subtract": false, + "module": "engine.dll", + "offset": 2, + "pattern": "8B 89 ? ? ? ? 85 C9 0F 84 ? ? ? ? 8B 01" + }, + "dwClientState_State": { + "extra": 0, + "mode_read": true, + "mode_subtract": false, + "module": "engine.dll", + "offset": 2, + "pattern": "83 B8 ? ? ? ? ? 0F 94 C0 C3" + }, + "dwClientState_ViewAngles": { + "extra": 0, + "mode_read": true, + "mode_subtract": false, + "module": "engine.dll", + "offset": 4, + "pattern": "F3 0F 11 80 ? ? ? ? D9 46 04 D9 05" + }, + "dwEntityList": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 1, + "pattern": "BB ? ? ? ? 83 FF 01 0F 8C ? ? ? ? 3B F8" + }, + "dwForceAttack": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 2, + "pattern": "89 0D ? ? ? ? 8B 0D ? ? ? ? 8B F2 8B C1 83 CE 04" + }, + "dwForceAttack2": { + "extra": 12, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 2, + "pattern": "89 0D ? ? ? ? 8B 0D ? ? ? ? 8B F2 8B C1 83 CE 04" + }, + "dwForceBackward": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 287, + "pattern": "55 8B EC 51 53 8A 5D 08" + }, + "dwForceForward": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 245, + "pattern": "55 8B EC 51 53 8A 5D 08" + }, + "dwForceJump": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 2, + "pattern": "8B 0D ? ? ? ? 8B D6 8B C1 83 CA 02" + }, + "dwForceLeft": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 465, + "pattern": "55 8B EC 51 53 8A 5D 08" + }, + "dwForceRight": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 512, + "pattern": "55 8B EC 51 53 8A 5D 08" + }, + "dwGameDir": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "engine.dll", + "offset": 1, + "pattern": "68 ? ? ? ? 8D 85 ? ? ? ? 50 68 ? ? ? ? 68" + }, + "dwGameRulesProxy": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 1, + "pattern": "A1 ? ? ? ? 85 C0 0F 84 ? ? ? ? 80 B8 ? ? ? ? ? 0F 84 ? ? ? ? 0F 10 05" + }, + "dwGetAllClasses": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 1, + "pattern": "A1 ? ? ? ? C3 CC CC CC CC CC CC CC CC CC CC A1 ? ? ? ? B9" + }, + "dwGlobalVars": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "engine.dll", + "offset": 1, + "pattern": "68 ? ? ? ? 68 ? ? ? ? FF 50 08 85 C0" + }, + "dwGlowObjectManager": { + "extra": 4, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 1, + "pattern": "A1 ? ? ? ? A8 01 75 4B" + }, + "dwInput": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 1, + "pattern": "B9 ? ? ? ? F3 0F 11 04 24 FF 50 10" + }, + "dwInterfaceLinkList": { + "extra": 0, + "mode_read": false, + "mode_subtract": true, + "module": "client.dll", + "offset": 0, + "pattern": "8B 35 ? ? ? ? 57 85 F6 74 ? 8B 7D 08 8B 4E 04 8B C7 8A 11 3A 10" + }, + "dwLocalPlayer": { + "extra": 16, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 1, + "pattern": "A3 ? ? ? ? C7 05 ? ? ? ? ? ? ? ? E8 ? ? ? ? 59 C3 6A ?" + }, + "dwMouseEnable": { + "extra": 48, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 1, + "pattern": "B9 ? ? ? ? FF 50 34 85 C0 75 10" + }, + "dwMouseEnablePtr": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 1, + "pattern": "B9 ? ? ? ? FF 50 34 85 C0 75 10" + }, + "dwPlayerResource": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 2, + "pattern": "8B 3D ? ? ? ? 85 FF 0F 84 ? ? ? ? 81 C7" + }, + "dwRadarBase": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 1, + "pattern": "A1 ? ? ? ? 8B 0C B0 8B 01 FF 50 ? 46 3B 35 ? ? ? ? 7C EA 8B 0D" + }, + "dwSensitivity": { + "extra": 44, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 2, + "pattern": "81 F9 ? ? ? ? 75 1D F3 0F 10 05 ? ? ? ? F3 0F 11 44 24 ? 8B 44 24 18 35 ? ? ? ? 89 44 24 0C EB 0B" + }, + "dwSensitivityPtr": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 2, + "pattern": "81 F9 ? ? ? ? 75 1D F3 0F 10 05 ? ? ? ? F3 0F 11 44 24 ? 8B 44 24 18 35 ? ? ? ? 89 44 24 0C EB 0B" + }, + "dwSetClanTag": { + "extra": 0, + "mode_read": false, + "mode_subtract": true, + "module": "engine.dll", + "offset": 0, + "pattern": "53 56 57 8B DA 8B F9 FF 15" + }, + "dwViewMatrix": { + "extra": 176, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 3, + "pattern": "0F 10 05 ? ? ? ? 8D 85 ? ? ? ? B9" + }, + "dwWeaponTable": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 1, + "pattern": "B9 ? ? ? ? 6A 00 FF 50 08 C3" + }, + "dwWeaponTableIndex": { + "extra": 0, + "mode_read": true, + "mode_subtract": false, + "module": "client.dll", + "offset": 2, + "pattern": "39 86 ? ? ? ? 74 06 89 86 ? ? ? ? 8B 86" + }, + "dwYawPtr": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 2, + "pattern": "81 F9 ? ? ? ? 75 1D F3 0F 10 05 ? ? ? ? F3 0F 11 44 24 ? 8B 44 24 1C 35 ? ? ? ? 89 44 24 18 EB 0B 8B 01 8B 40 30 FF D0 D9 5C 24 18 F3 0F 10 06" + }, + "dwZoomSensitivityRatioPtr": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "client.dll", + "offset": 2, + "pattern": "81 F9 ? ? ? ? 75 1A F3 0F 10 05 ? ? ? ? F3 0F 11 45 ? 8B 45 F4 35 ? ? ? ? 89 45 FC EB 0A 8B 01 8B 40 30 FF D0 D9 5D FC A1" + }, + "dwbSendPackets": { + "extra": 0, + "mode_read": false, + "mode_subtract": true, + "module": "engine.dll", + "offset": 1, + "pattern": "B3 01 8B 01 8B 40 10 FF D0 84 C0 74 0F 80 BF ? ? ? ? ? 0F 84" + }, + "dwppDirect3DDevice9": { + "extra": 0, + "mode_read": true, + "mode_subtract": true, + "module": "shaderapidx9.dll", + "offset": 1, + "pattern": "A1 ? ? ? ? 50 8B 08 FF 51 0C" + }, + "m_pStudioHdr": { + "extra": 0, + "mode_read": true, + "mode_subtract": false, + "module": "client.dll", + "offset": 2, + "pattern": "8B B6 ? ? ? ? 85 F6 74 05 83 3E 00 75 02 33 F6 F3 0F 10 44 24" + } + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..eefebf5 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,271 @@ +extern crate chrono; +extern crate json; +extern crate memlib; +extern crate toml; + +use std::fs::File; +use std::io::prelude::*; + +mod csgo; + +use chrono::*; +use json::*; +use memlib::process::Process; + +const DEFAULT_CONFIG: &str = include_str!("default.json"); + +fn main() { + println!("> -------------------------------- <"); + println!("> Hazedumper v1.0.0 - Rust version <"); + println!("> https://haze-productions.com <"); + println!("> -------------------------------- <\n"); + + let data = scan_game().unwrap(); + + dump_json("csgo", &data); + dump_hpp("csgo", &data).expect("Could not dump .hpp"); + dump_toml("csgo", &data).expect("Could not dump .toml"); + dump_csharp("csgo", &data).expect("Could not dump .cs"); + dump_vbnet("csgo", &data).expect("Could not dump .vb"); + + println!("\n> Done. Press any key to exit."); + + let mut stdin = std::io::stdin(); + let input = &mut [0u8]; + assert!(stdin.read(input).is_ok()); +} + +fn scan_game() -> Option { + let mut config = JsonValue::new_object(); + load_config(&mut config).unwrap_or_else(|_| write_default_config(&mut config)); + + let process = memlib::process::from_name("csgo.exe").expect("Error! Could not open csgo.exe!"); + let mut data = JsonValue::new_object(); + + data["timestamp"] = Local::now().timestamp().into(); + data["modules"]["client.dll"]["size"] = process.get_module("client.dll")?.size.into(); + data["modules"]["engine.dll"]["size"] = process.get_module("engine.dll")?.size.into(); + + println!("--- Signatures ---"); + scan_signatures(&config, &mut data, &process); + + println!("\n--- Netvars ---"); + match data["signatures"]["dwGetAllClasses"].as_usize() { + Some(first_class) => { + scan_netvars(&config, &mut data, &process, first_class); + } + None => { + println!("\n - You need a working 'dwGetAllClasses' signature to dump netvars! -\n"); + } + } + + Some(data) +} + +fn scan_signatures(config: &JsonValue, data: &mut JsonValue, process: &Process) -> Option<()> { + use memlib::module::Mode; + let get_bool = |j: &JsonValue, p: &str| j[p].as_bool().unwrap_or(false); + + let find_sig = |v: &JsonValue| -> Option { + let module = process.get_module(v["module"].as_str()?)?; + let m_read = get_bool(&v, "mode_read"); + let m_sub = get_bool(&v, "mode_subtract"); + + let s_mode = match m_read { + true if m_sub => Mode::ReadSubtract, + true if !m_sub => Mode::Read, + false if m_sub => Mode::Subtract, + _ => Mode::Nop, + }; + + let s_pattern = v["pattern"].as_str()?; + let s_offset = v["offset"].as_i32().unwrap_or(0); + let s_extra = v["extra"].as_i32().unwrap_or(0); + + module.find_pattern::(s_pattern, s_mode, s_offset, s_extra) + }; + + for (k, v) in config["signatures"].entries() { + match find_sig(v) { + Some(addr) => { + println!("{:<30} => 0x{:X}", k, addr); + data["signatures"][k.to_string()] = addr.into(); + } + None => println!("{:<30} => FAILED!", k), + } + } + + None +} + +fn scan_netvars( + config: &JsonValue, + data: &mut JsonValue, + process: &Process, + first_class: usize, +) -> Option<()> { + use csgo::netvars::NetvarManager; + let first_class = first_class + process.get_module("client.dll")?.base; + let manager = NetvarManager::load_netdata(&process, first_class)?; + + let get_recv_prop = |v: &JsonValue| -> Option { + let table = v["table"].as_str()?; + let netvar = v["netvar"].as_str()?; + manager.get_recv_prop(&process, table, netvar) + }; + + for (k, v) in config["netvars"].entries() { + let offset = v["offset"].as_i32().unwrap_or(0); + + match get_recv_prop(v) { + Some(val) => { + let val = (val as i32 + offset) as usize; + println!("{:<30} => 0x{:X}", k, val); + data["netvars"][k.to_string()] = val.into(); + } + None => { + println!("{:<30} => FAILED!", k); + } + } + } + + None +} + +fn load_config(j: &mut JsonValue) -> std::io::Result<()> { + let mut f = File::open("config.json")?; + let mut s = String::new(); + f.read_to_string(&mut s)?; + *j = json::parse(&s).unwrap(); + Ok(()) +} + +fn write_default_config(j: &mut JsonValue) { + *j = json::parse(DEFAULT_CONFIG).unwrap(); + File::create("config.json") + .ok() + .map_or((), |mut f| write!(&mut f, "{}", j.pretty(2)).unwrap_or(())); +} + +fn dump_json(name: &str, j: &JsonValue) { + File::create(format!("{}.json", name)) + .ok() + .map_or((), |mut f| write!(&mut f, "{}", j.pretty(2)).unwrap_or(())); + File::create(format!("{}.min.json", name)) + .ok() + .map_or((), |mut f| write!(&mut f, "{}", j.dump()).unwrap_or(())); +} + +fn dump_hpp(name: &str, j: &JsonValue) -> std::io::Result<()> { + let mut f = File::create(format!("{}.hpp", name))?; + writeln!(&mut f, "#pragma once")?; + writeln!(&mut f, "#include \n")?; + writeln!(&mut f, "// Offsets timestamp")?; + writeln!(&mut f, "// {}\n", Local::now().to_rfc2822())?; + + writeln!(&mut f, "namespace hazedumper {{")?; + writeln!(&mut f, "namespace netvars {{")?; + for (key, val) in j["netvars"].entries() { + writeln!( + &mut f, + "constexpr ::std::ptrdiff_t {} = 0x{:X};", + key, + val.as_u32().unwrap() + )?; + } + writeln!(&mut f, "}} // namespace netvars")?; + writeln!(&mut f, "namespace signatures {{")?; + for (key, val) in j["signatures"].entries() { + writeln!( + &mut f, + "constexpr ::std::ptrdiff_t {} = 0x{:X};", + key, + val.as_u32().unwrap() + )?; + } + writeln!(&mut f, "}} // namespace signatures")?; + writeln!(&mut f, "}} // namespace hazedumper")?; + Ok(()) +} + +fn dump_csharp(name: &str, j: &JsonValue) -> std::io::Result<()> { + let mut f = File::create(format!("{}.cs", name))?; + writeln!(&mut f, "using System;\n")?; + writeln!(&mut f, "// Offsets timestamp")?; + writeln!(&mut f, "// {}\n", Local::now().to_rfc2822())?; + + writeln!(&mut f, "namespace hazedumper\n{{")?; + writeln!(&mut f, " public static class netvars\n {{")?; + for (key, val) in j["netvars"].entries() { + writeln!( + &mut f, + " public const Int32 {} = 0x{:X};", + key, + val.as_u32().unwrap() + )?; + } + writeln!(&mut f, " }}")?; + writeln!(&mut f, " public static class signatures\n {{")?; + for (key, val) in j["signatures"].entries() { + writeln!( + &mut f, + " public const Int32 {} = 0x{:X};", + key, + val.as_u32().unwrap() + )?; + } + writeln!(&mut f, " }}")?; + writeln!(&mut f, "}} // namespace hazedumper")?; + Ok(()) +} + +fn dump_vbnet(name: &str, j: &JsonValue) -> std::io::Result<()> { + let mut f = File::create(format!("{}.vb", name))?; + writeln!(&mut f, "' {}\n", Local::now().to_rfc2822())?; + + writeln!(&mut f, "Namespace hazedumper")?; + writeln!(&mut f, " Public Shared Class netvars")?; + for (key, val) in j["netvars"].entries() { + writeln!( + &mut f, + " Public Const {} as Integer = &H{:X}", + key, + val.as_u32().unwrap() + )?; + } + writeln!(&mut f, " End Class")?; + writeln!(&mut f, " Public Shared Class signatures")?; + for (key, val) in j["signatures"].entries() { + writeln!( + &mut f, + " Public Const {} as Integer = &H{:X}", + key, + val.as_u32().unwrap() + )?; + } + writeln!(&mut f, " End Class")?; + writeln!(&mut f, "End Namespace")?; + Ok(()) +} + +fn dump_toml(name: &str, j: &JsonValue) -> std::io::Result<()> { + let mut t = toml::Table::new(); + let mut netvars = toml::Table::new(); + let mut signatures = toml::Table::new(); + let timestamp = Local::now(); + t.insert( + "timestamp".to_string(), + toml::Value::Integer(timestamp.timestamp()), + ); + for (key, val) in j["netvars"].entries() { + netvars.insert(key.to_string(), toml::Value::Integer(val.as_i64().unwrap())); + } + for (key, val) in j["signatures"].entries() { + signatures.insert(key.to_string(), toml::Value::Integer(val.as_i64().unwrap())); + } + t.insert("netvars".to_string(), toml::encode(&netvars)); + t.insert("signatures".to_string(), toml::encode(&signatures)); + let mut f = File::create(format!("{}.toml", name))?; + writeln!(&mut f, "# {}", timestamp.to_rfc2822())?; + write!(&mut f, "{}", toml::encode_str(&t)) +}