rust_native_obf/
string.rs

1use core::ptr::{read_volatile, write};
2
3const fn pcg_step(mut state: u32) -> u32 {
4    state = state.wrapping_mul(747796405).wrapping_add(2891336453);
5    let word = ((state >> ((state >> 28) + 4)) ^ state).wrapping_mul(277803737);
6    (word >> 22) ^ word
7}
8
9pub const fn gen_keystream<const N: usize>(seed: u32) -> [u8; N] {
10    let mut keys = [0u8; N];
11    let mut state = seed;
12    let mut i = 0;
13    while i < N {
14        state = pcg_step(state);
15        let bytes = state.to_ne_bytes();
16        let mut j = 0;
17        while j < 4 && i + j < N {
18            keys[i + j] = bytes[j];
19            j += 1;
20        }
21        i += 4;
22    }
23    keys
24}
25
26pub const fn encrypt_bytes<const N: usize>(data: &[u8], keys: &[u8; N]) -> [u8; N] {
27    let mut result = [0u8; N];
28    let mut i = 0;
29    while i < N {
30        result[i] = data[i] ^ keys[i];
31        i += 1;
32    }
33    result
34}
35
36pub fn decrypt_bytes<const N: usize>(data: &[u8; N], keys: &[u8; N]) -> [u8; N] {
37    let mut result = [0u8; N];
38    let mut i = 0;
39    unsafe {
40        let src = data.as_ptr();
41        let dst = result.as_mut_ptr();
42        #[cfg(target_pointer_width = "64")]
43        while i + 8 <= N {
44            let enc = read_volatile(src.add(i) as *const u64);
45            let key = u64::from_ne_bytes([
46                keys[i], keys[i+1], keys[i+2], keys[i+3],
47                keys[i+4], keys[i+5], keys[i+6], keys[i+7],
48            ]);
49            write(dst.add(i) as *mut u64, enc ^ key);
50            i += 8;
51        }
52        while i + 4 <= N {
53            let enc = read_volatile(src.add(i) as *const u32);
54            let key = u32::from_ne_bytes([keys[i], keys[i+1], keys[i+2], keys[i+3]]);
55            write(dst.add(i) as *mut u32, enc ^ key);
56            i += 4;
57        }
58        while i < N {
59            let enc = read_volatile(src.add(i));
60            write(dst.add(i), enc ^ keys[i]);
61            i += 1;
62        }
63    }
64    result
65}
66
67#[inline(always)]
68pub fn bytes_to_str(bytes: &[u8]) -> &str {
69    #[cfg(debug_assertions)]
70    return core::str::from_utf8(bytes).unwrap();
71    #[cfg(not(debug_assertions))]
72    return unsafe { core::str::from_utf8_unchecked(bytes) };
73}
74
75#[macro_export]
76macro_rules! obf_str {
77    ($s:expr) => {{
78        const _SRC: &[u8] = $s.as_bytes();
79        const _LEN: usize = _SRC.len();
80        const _KEYS: [u8; _LEN] = $crate::string::gen_keystream::<_LEN>(
81            $crate::ct_rand!(u32, stringify!($s)));
82        static _ENC: [u8; _LEN] = $crate::string::encrypt_bytes::<_LEN>(_SRC, &_KEYS);
83        $crate::string::bytes_to_str(&$crate::string::decrypt_bytes::<_LEN>(&_ENC, &_KEYS))
84    }};
85}
86
87#[macro_export]
88macro_rules! obf_bytes {
89    ($s:expr) => {{
90        const _SRC: &[u8] = $s;
91        const _LEN: usize = _SRC.len();
92        const _KEYS: [u8; _LEN] = $crate::string::gen_keystream::<_LEN>(
93            $crate::ct_rand!(u32, stringify!($s)));
94        static _ENC: [u8; _LEN] = $crate::string::encrypt_bytes::<_LEN>(_SRC, &_KEYS);
95        $crate::string::decrypt_bytes::<_LEN>(&_ENC, &_KEYS)
96    }};
97}
98