//! Obfuscate the embedded rule pack at build time. //! //! An antivirus that ships its signatures as literal strings inside its //! own binary detects itself. Hound's built-in pack matches on //! "stratum+tcp://", "donate-level", "xmrig", "RTLD_NEXT" and //! "ld.so.preload"; with the pack embedded verbatim, `/usr/bin/houndd` //! matched Linux.Coinminer.XMRig and Linux.Rootkit.Preload. The goodware //! gate caught it on the first packaged install. //! //! That is not cosmetic. With the execution gate armed, Hound would have //! refused to execute itself, or quarantined its own binary — a scanner //! that eats its own daemon the moment protection is switched on. //! //! A single-byte XOR is enough. This is not a secret: the rules are open //! source and anybody can read them in the repository. The only job is to //! stop the literal bytes appearing in the executable, and a trivial //! transform does that as well as an elaborate one would. use std::io::Write; /// Chosen only so the transform is not the identity function. const MASK: u8 = 0x5A; fn main() { let src = "rules/hound-builtin.yar"; println!("cargo:rerun-if-changed={src}"); let plain = std::fs::read(src).expect("reading the built-in rule pack"); let masked: Vec = plain.iter().map(|b| b ^ MASK).collect(); let out = std::path::PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR")) .join("hound-builtin.yar.masked"); let mut f = std::fs::File::create(&out).expect("creating the masked pack"); f.write_all(&masked).expect("writing the masked pack"); }