obfstr Rust Documentation

repository·master·Indexed 20 days ago

https://github.com/casualx/obfstr

A Rust crate for compile-time string constant obfuscation to prevent strings from appearing plainly in binaries. It provides the obfstr! macro for obfuscation, wide! for UTF-16 constants, hash! for DJB2 string hashing, and random! for generating compile-time pseudorandom values for various types.

Tokens
1.1K
Snippets
6
Records
7
Agent score
20%

What's inside obfstr

  1. Obfuscate string constants with obfstr!

    master

    Use the obfstr! macro to embed string constants in an obfuscated form. The macro returns the deobfuscated string as a temporary value. Because it is a temporary value, you must use the result in the same statement it was generated (e.g., in an assertion, a function call, or an assignment) to avoid lifetime issues.

    If you need to obfuscate formatting strings (like those used in format!), consider using the fmtools crate with the obfstr dependency enabled.

    use obfstr::obfstr as s;
    assert_eq!(s!("Hello 🌍"), "Hello 🌍");
  2. Generate compiletime random values with random!

    master

    The random! macro generates compiletime random values. These values are reproducible and based on file!(), line!(), column!(), and a fixed seed.

    To change the seed used for these values, set the OBFSTR_SEED environment variable.

    const RND: i32 = obfstr::random!(u8) as i32;
    assert!(RND >= 0 && RND <= 255);
  3. Generate compiletime UTF-16 string constants with wide!

    master

    The wide! macro provides compiletime UTF-16 string constants. This is useful when you need a slice of u16 values representing a string, often for interacting with Windows APIs or other wide-character interfaces.

    let expected = &['W' as u16, 'i' as u16, 'd' as u16, 'e' as u16, 0];
    assert_eq!(obfstr::wide!("Wide\0"), expected);
  4. Configure the global RNG seed via `OBFSTR_SEED`

    master

    The base entropy for all compile-time random generation is derived from the OBFSTR_SEED environment variable.

    • If OBFSTR_SEED is set, it is used to derive the global SEED constant.
    • If OBFSTR_SEED is absent, a fixed default value is used.

    Changing this environment variable will cause all downstream dependents that use random! or related entropy functions to be recompiled automatically.

  5. Compute compile-time string hashes with `hash!`

    master

    The hash! macro computes a compile-time hash of a string constant using a variation of the DJB2 hash function. This is useful for generating unique identifiers or keys from strings at compile time.

    const STRING: &str = "Hello World";
    const HASHED: u32 = obfstr::hash!(STRING);
    const STRING: &str = "Hello World";
    assert_eq!(obfstr::hash!(STRING), 0x6E4A573D);
  6. Use `splitmix` for compile-time bitmixing

    master

    The splitmix function is a compile-time bitmixing utility. It takes a 64-bit seed and increases its entropy to provide better distribution. This is useful when you have a hash that might not be thoroughly mixed and need to transform it into a higher-quality pseudorandom value.

    pub const fn splitmix(seed: u64) -> u64
  7. Generate compile-time random values with `random!`

    master

    The random! macro generates a pseudorandom value at compile time. It uses file, line, and column information along with optional seeds to ensure uniqueness.

    Supported Types

    • Integers: u8, u16, u32, u64, usize, i8, i16, i32, i64, isize (generates values in their respective range).
    • Booleans: bool.
    • Floats: f32, f64 (generates values in the range [1.0, 2.0)).

    Important Usage Notes

    • Macro Nesting: When random! is used inside the definition of another macro, it may not behave as expected (it might produce the same value for different calls) because the expansion happens at a different stage. To fix this, provide a unique literal seed.
    • Seeding: You can provide additional unique seeds to ensure different values when using the macro in repeated contexts or within other macros.

    Example

    // Basic usage
    const RND: i32 = obfstr::random!(u8) as i32;
    
    // Using unique seeds to ensure different values in macros
    macro_rules! seeded {
        () => {
            assert_ne!(obfstr::random!(u64, "lhs"), obfstr::random!(u64, "rhs"));
        };
    }
    seeded!();
    const RND: i32 = obfstr::random!(u8) as i32;
    assert!(RND >= 0 && RND <= 255);
    
    // To ensure uniqueness in macros, provide literal seeds:
    macro_rules! seeded {
        () => {
            assert_ne!(obfstr::random!(u64, "lhs"), obfstr::random!(u64, "rhs"));
        };
    }
    seeded!();