rust_native_obf/
string.rs1use 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