use std::time::{SystemTime, UNIX_EPOCH}; fn main() { let root_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); let mh_dir = std::path::Path::new(&root_dir).join("vendor/minhook"); let mh_src = mh_dir.join("src"); let target = std::env::var("TARGET").unwrap(); let arch = target.splitn(4, '-').next().unwrap(); let hde = if arch == "i686" { "hde/hde32.c" } else if arch == "x86_64" { "hde/hde64.c" } else { panic!("unsupported arch {arch}"); }; cc::Build::new() .flag("-ffunction-sections") .flag("-fdata-sections") .file(mh_src.join("buffer.c")) .file(mh_src.join("hook.c")) .file(mh_src.join("trampoline.c")) .file(mh_src.join(hde)) .compile("libminhook.a"); generate_loader_entry(); println!("cargo:rerun-if-changed=vendor/minhook"); println!("cargo:rerun-if-changed=build.rs"); } fn generate_loader_entry() { let seed = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_nanos() as u64 ^ (std::process::id() as u64).wrapping_mul(0x9E37_79B9_7F4A_7C15); let name = format!("x{:06x}", seed & 0xFFFF_FF); let src = format!( "// Generated by build.rs — do not edit.\n\ // Randomized per-build reflective loader export name.\n\ pub(crate) const LOADER_EXPORT: &[u8] = b\"{name}\\0\";\n\ \n\ #[unsafe(no_mangle)]\n\ pub extern \"system\" fn {name}(lpParameter: usize) -> usize {{\n\ \x20 crate::reflective::loader_impl(lpParameter)\n\ }}\n" ); let out_dir = std::env::var("OUT_DIR").unwrap(); std::fs::write(std::path::Path::new(&out_dir).join("loader_entry.rs"), src) .expect("failed to write loader_entry.rs"); println!("cargo:rerun-if-changed=loader_entry.rs"); }