rust_code_obfuscator_core 0.3.1

Core encryption and obfuscation logic for rustfuscator
Documentation
#[macro_export]
macro_rules! obfuscate_string {
    ($s:literal) => {{
        fn init() -> &'static str {
            static CELL: ::std::sync::OnceLock<&'static str> = ::std::sync::OnceLock::new();
            *CELL.get_or_init(|| {
                let decrypted: ::std::string::String = cryptify::encrypt_string!($s);
                $crate::obfuscator::__verify_literal_round_trip($s, decrypted.as_str());
                ::std::boxed::Box::leak(decrypted.into_boxed_str())
            })
        }
        $crate::ObfStr::new(init)
    }};
    ($other:expr) => {
        compile_error!("obfuscate_string! only accepts string literals");
    };
}

#[macro_export]
macro_rules! obfuscate_str {
    ($s:literal) => {{
        $crate::obfuscate_string!($s).as_str()
    }};
    ($other:expr) => {
        compile_error!("obfuscate_str! only accepts string literals");
    };
}

#[macro_export]
macro_rules! obfuscate_num {
    (-$n:literal) => {{
        let rustfuscator_value = -$n;
        $crate::obfuscator::__obfuscate_num_value(
            rustfuscator_value,
            (::core::line!() as u64)
                ^ ((::core::column!() as u64) << 32)
                ^ 0xa24b_aed4_963e_e407u64,
        )
    }};
    ($n:literal) => {{
        let rustfuscator_value = $n;
        $crate::obfuscator::__obfuscate_num_value(
            rustfuscator_value,
            (::core::line!() as u64)
                ^ ((::core::column!() as u64) << 32)
                ^ 0xa24b_aed4_963e_e407u64,
        )
    }};
    ($($t:tt)*) => {
        compile_error!("obfuscate_num! only accepts integer literals");
    };
}

#[macro_export]
macro_rules! obfuscate_flow {
    () => {
        cryptify::flow_stmt!()
    };
    ($($t:tt)*) => {
        compile_error!("obfuscate_flow! does not accept arguments");
    };
}

#[macro_export]
macro_rules! obfuscate_dummy_branch {
    () => {{
        let rustfuscator_seed =
            ::core::line!() as u64 ^ ((::core::column!() as u64) << 32) ^ 0x9e37_79b9_7f4a_7c15u64;
        if ::core::hint::black_box(rustfuscator_seed.rotate_left(13)) == 0 {
            ::core::hint::black_box(rustfuscator_seed);
        }
    }};
    ($($t:tt)*) => {
        compile_error!("obfuscate_dummy_branch! does not accept arguments");
    };
}

#[doc(hidden)]
#[inline]
pub fn __verify_literal_round_trip(original: &str, decrypted: &str) {
    #[cfg(all(debug_assertions, feature = "verify_literals"))]
    {
        debug_assert_eq!(
            decrypted, original,
            "rustfuscator literal verification failed: decrypted value differs from original"
        );
    }

    #[cfg(not(all(debug_assertions, feature = "verify_literals")))]
    {
        let _ = (original, decrypted);
    }
}

#[doc(hidden)]
pub trait __ObfuscateNum: Copy {
    fn __obfuscate_num(self, seed: u64) -> Self;
}

macro_rules! impl_obfuscate_num {
    ($($ty:ty),* $(,)?) => {
        $(
            impl __ObfuscateNum for $ty {
                #[inline]
                fn __obfuscate_num(self, seed: u64) -> Self {
                    let mask = ::core::hint::black_box(seed as $ty);
                    let offset = ::core::hint::black_box(mask.rotate_left(7));
                    let encoded = (self ^ mask).wrapping_add(offset);
                    ::core::hint::black_box(encoded.wrapping_sub(offset) ^ mask)
                }
            }
        )*
    };
}

impl_obfuscate_num!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);

#[doc(hidden)]
#[inline]
pub fn __obfuscate_num_value<T: __ObfuscateNum>(value: T, seed: u64) -> T {
    value.__obfuscate_num(seed)
}

#[cfg(test)]
mod tests {
    #[test]
    fn obfuscate_string_macro_round_trips_literal() {
        assert_eq!(
            crate::obfuscate_string!("verified literal").as_str(),
            "verified literal"
        );
    }

    #[test]
    fn obfuscate_num_round_trips_unsigned_integer_literals() {
        assert_eq!(crate::obfuscate_num!(0u8), 0u8);
        assert_eq!(crate::obfuscate_num!(255u8), 255u8);
        assert_eq!(crate::obfuscate_num!(65_535u16), 65_535u16);
        assert_eq!(crate::obfuscate_num!(4_294_967_295u32), u32::MAX);
        assert_eq!(
            crate::obfuscate_num!(18_446_744_073_709_551_615u64),
            u64::MAX
        );
        assert_eq!(
            crate::obfuscate_num!(340282366920938463463374607431768211455u128),
            u128::MAX
        );
        assert_eq!(crate::obfuscate_num!(123usize), 123usize);
    }

    #[test]
    fn obfuscate_num_round_trips_signed_integer_literals() {
        assert_eq!(crate::obfuscate_num!(1234), 1234);
        assert_eq!(crate::obfuscate_num!(-42i8), -42i8);
        assert_eq!(crate::obfuscate_num!(-123i16), -123i16);
        assert_eq!(crate::obfuscate_num!(-123_456i32), -123_456i32);
        assert_eq!(crate::obfuscate_num!(-123_456_789i64), -123_456_789i64);
        assert_eq!(
            crate::obfuscate_num!(-123_456_789_123_456_789i128),
            -123_456_789_123_456_789i128
        );
        assert_eq!(crate::obfuscate_num!(-123isize), -123isize);
    }

    #[test]
    fn dummy_branch_macro_is_safe_to_execute() {
        crate::obfuscate_dummy_branch!();
    }

    #[cfg(all(debug_assertions, feature = "verify_literals"))]
    #[test]
    #[should_panic(expected = "rustfuscator literal verification failed")]
    fn literal_verification_panics_on_mismatch_when_enabled() {
        super::__verify_literal_round_trip("original", "different");
    }
}