diff --git a/Cargo.lock b/Cargo.lock index 9bba7d0..b9e5075 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -184,7 +184,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chaudloader" -version = "0.9.2" +version = "0.10.0" dependencies = [ "anyhow", "byteorder", @@ -203,6 +203,7 @@ dependencies = [ "proc-macro2", "pulldown-cmark", "retour", + "run_script", "semver", "serde", "serde_plain", @@ -403,6 +404,12 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + [[package]] name = "dxgi-shim" version = "0.1.0" @@ -508,6 +515,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fsio" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad0ce30be0cc441b325c5d705c8b613a0ca0d92b6a8953d41bd236dc09a36d0" +dependencies = [ + "dunce", + "rand", +] + [[package]] name = "generator" version = "0.7.4" @@ -996,6 +1013,12 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1050,11 +1073,35 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] [[package]] name = "redox_syscall" @@ -1130,6 +1177,15 @@ dependencies = [ "slice-pool", ] +[[package]] +name = "run_script" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829f98fdc58d78989dd9af83be28bc15c94a7d77f9ecdb54abbbc0b1829ba9c7" +dependencies = [ + "fsio", +] + [[package]] name = "rustc-hash" version = "1.1.0" diff --git a/README.md b/README.md index 13d5cff..3214b54 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,8 @@ chaudloader has some development options which can be enabled to aid with mod de - `developer_mode` (type: boolean, default: `false`): Enables developer mode. Required to be `true` in order to use any of the other development options. - `enable_hook_guards` (type: boolean, default: `false`): Enables hook guards. +- `stage0_commands` (type: string array, default: `[]`): List of shell commands to run during stage0 before the game's entry point. If any of the commands returns a nonzero exit code, loading is aborted. The following variables can be used in commands: + - `%PID%`: Replaced by the game's process ID. ## For developers diff --git a/chaudloader/Cargo.toml b/chaudloader/Cargo.toml index 5bd0e56..049f0ea 100644 --- a/chaudloader/Cargo.toml +++ b/chaudloader/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chaudloader" -version = "0.9.2" +version = "0.10.0" edition = "2021" [lib] @@ -33,3 +33,4 @@ maud = "0.25" url = "2" opener = "0.6" proc-macro2 = "^1.0.60" +run_script = "0.10.1" diff --git a/chaudloader/src/config.rs b/chaudloader/src/config.rs index dda9e76..a19ba94 100644 --- a/chaudloader/src/config.rs +++ b/chaudloader/src/config.rs @@ -15,6 +15,7 @@ pub struct Config { // Secret options pub developer_mode: Option, pub enable_hook_guards: Option, // requires developer_mode + pub stage0_commands: Option>, // requires developer_mode } const CONFIG_FILE_NAME: &str = "chaudloader.toml"; diff --git a/chaudloader/src/hooks/stage0.rs b/chaudloader/src/hooks/stage0.rs index 25c8ec2..c1b793f 100644 --- a/chaudloader/src/hooks/stage0.rs +++ b/chaudloader/src/hooks/stage0.rs @@ -224,6 +224,18 @@ pub unsafe fn install() -> Result<(), anyhow::Error> { let config = config::load()?; + if config.developer_mode == Some(true) { + for cmd in config.stage0_commands.iter().flatten() { + let (code, _, _) = run_script::run_script!( + cmd + .replace("%PID%", &std::process::id().to_string()) + )?; + if code != 0 { + log::error!("Command {cmd} exited with code {code}"); + } + } + } + unsafe { // Hook GetProcAddress to avoid ntdll.dll hooks being installed GetProcAddressForCaller