rustcrypt_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, LitStr, LitByteStr, ExprArray, ItemFn};
4
5#[proc_macro]
6pub fn obfuscate_string(input: TokenStream) -> TokenStream {
7    let lit = parse_macro_input!(input as LitStr);
8    let value = lit.value();
9    
10    let key = generate_compile_time_key(&value);
11    let (encrypted_data, nonce) = encrypt_at_compile_time(&value, &key);
12    
13    let expanded = quote! {{
14        const ENCRYPTED_DATA: &[u8] = &[#(#encrypted_data),*];
15        const NONCE: &[u8; 12] = &[#(#nonce),*];
16        const KEY: &[u8; 32] = &[#(#key),*];
17        
18        rustcrypt_core::decrypt_string(ENCRYPTED_DATA, NONCE, KEY)
19    }};
20    
21    TokenStream::from(expanded)
22}
23
24#[proc_macro]
25pub fn obfuscate_bytes(input: TokenStream) -> TokenStream {
26    let lit = parse_macro_input!(input as LitByteStr);
27    let value = lit.value();
28    
29    let key = generate_compile_time_key_bytes(&value);
30    let (encrypted_data, nonce) = encrypt_bytes_at_compile_time(&value, &key);
31    
32    let expanded = quote! {{
33        const ENCRYPTED_DATA: &[u8] = &[#(#encrypted_data),*];
34        const NONCE: &[u8; 12] = &[#(#nonce),*];
35        const KEY: &[u8; 32] = &[#(#key),*];
36        
37        rustcrypt_core::decrypt_bytes(ENCRYPTED_DATA, NONCE, KEY)
38    }};
39    
40    TokenStream::from(expanded)
41}
42
43#[proc_macro]
44pub fn obfuscate_cstr(input: TokenStream) -> TokenStream {
45    let lit = parse_macro_input!(input as LitStr);
46    let mut v = lit.value().into_bytes();
47    v.push(0);
48    let key = generate_compile_time_key_bytes(&v);
49    let (encrypted_data, nonce) = encrypt_bytes_at_compile_time(&v, &key);
50    let expanded = quote! {{
51        const ENCRYPTED_DATA: &[u8] = &[#(#encrypted_data),*];
52        const NONCE: &[u8; 12] = &[#(#nonce),*];
53        const KEY: &[u8; 32] = &[#(#key),*];
54        rustcrypt_core::decrypt_bytes(ENCRYPTED_DATA, NONCE, KEY)
55    }};
56    TokenStream::from(expanded)
57}
58
59#[proc_macro]
60pub fn obfuscate_bytes_array(input: TokenStream) -> TokenStream {
61    let arr = parse_macro_input!(input as ExprArray);
62    let mut values: Vec<u8> = Vec::new();
63    for elem in arr.elems.iter() {
64        if let syn::Expr::Lit(l) = elem {
65            if let syn::Lit::Int(i) = &l.lit {
66                if let Ok(v) = i.base10_parse::<u64>() { values.push((v & 0xFF) as u8); }
67            }
68        }
69    }
70    let key = generate_compile_time_key_bytes(&values);
71    let (encrypted_data, nonce) = encrypt_bytes_at_compile_time(&values, &key);
72    let expanded = quote! {{
73        const ENCRYPTED_DATA: &[u8] = &[#(#encrypted_data),*];
74        const NONCE: &[u8; 12] = &[#(#nonce),*];
75        const KEY: &[u8; 32] = &[#(#key),*];
76        rustcrypt_core::decrypt_bytes(ENCRYPTED_DATA, NONCE, KEY)
77    }};
78    TokenStream::from(expanded)
79}
80
81#[proc_macro]
82pub fn obfuscate_flow(input: TokenStream) -> TokenStream {
83    let _input = input;
84    let expanded = quote! {{
85        let mut _dummy = 0u64;
86        for i in 0..16 {
87            _dummy = _dummy.wrapping_add(i);
88            _dummy = _dummy.rotate_left(3);
89            _dummy ^= 0x5A5A5A5A5A5A5A5A;
90        }
91        std::hint::black_box(_dummy);
92    }};
93    
94    TokenStream::from(expanded)
95}
96
97#[proc_macro]
98pub fn obfuscate_flow_heavy(input: TokenStream) -> TokenStream {
99    let _input = input;
100    let expanded = quote! {{
101        let mut _d0: u64 = 0xA5A5A5A5A5A5A5A5;
102        let mut _d1: u64 = 0x5A5A5A5A5A5A5A5A;
103        for i in 0..128u64 {
104            _d0 = _d0.rotate_left((i % 63) as u32) ^ i;
105            _d1 = _d1.wrapping_add(_d0 ^ (i.wrapping_mul(0x9E3779B97F4A7C15)));
106            if (_d0 & 1) == 0 { _d1 ^= _d0.rotate_right(7); } else { _d0 ^= _d1.rotate_left(11); }
107        }
108        std::hint::black_box((_d0, _d1));
109    }};
110    TokenStream::from(expanded)
111}
112
113#[proc_macro]
114pub fn obfuscate_branch(input: TokenStream) -> TokenStream {
115    let cond = parse_macro_input!(input as syn::Expr);
116    let expanded = quote! {{
117        let __c = { #cond };
118        let mut __t: u64 = 0x9E3779B97F4A7C15;
119        for i in 0..32u64 { __t ^= __t.rotate_left((i % 17) as u32) ^ i; }
120        let __opaque = ((__t ^ 0xA5A5A5A5A5A5A5A5) & 1) == 0;
121        __c && (__opaque || !__opaque)
122    }};
123    TokenStream::from(expanded)
124}
125
126// attribute macro to inject obfuscation into functions
127#[proc_macro_attribute]
128pub fn obfuscate_fn(_attr: TokenStream, item: TokenStream) -> TokenStream {
129    let mut f = parse_macro_input!(item as ItemFn);
130    let prologue = quote! {{
131        let mut __a: u64 = 0xC3D2E1F0A5968778;
132        for i in 0..64u64 { __a = __a.rotate_left((i%23) as u32) ^ (i.wrapping_mul(0x9E37)); }
133        std::hint::black_box(__a);
134    }};
135    let epilogue = quote! {{
136        let mut __b: u64 = 0x0123456789ABCDEF;
137        for i in 0..64u64 { __b = __b.rotate_right((i%19) as u32) ^ (i.wrapping_mul(0xA5A5)); }
138        std::hint::black_box(__b);
139    }};
140    let orig_block = *f.block;
141    let new_block = quote! {{
142        #prologue
143        let __ret = (|| #orig_block)();
144        #epilogue
145        __ret
146    }};
147    f.block = syn::parse2(new_block).expect("valid block");
148    TokenStream::from(quote! { #f })
149}
150
151#[proc_macro]
152pub fn obfuscate_select(input: TokenStream) -> TokenStream {
153    let input = parse_macro_input!(input as syn::ExprTuple);
154    let mut it = input.elems.into_iter();
155    let cond = it.next().expect("cond");
156    let t = it.next().expect("true");
157    let f = it.next().expect("false");
158    let expanded = quote! {{
159        let __c = { #cond };
160        let mut __z: u64 = 0x6A09E667F3BCC909;
161        for i in 0..16u64 { __z ^= __z.rotate_left((i%13) as u32) ^ (i*0x9E37); }
162        let __op = ((__z ^ 0xBB67AE8584CAA73B) & 1) == 1;
163        if __c && (__op || !__op) { (#t)() } else { (#f)() }
164    }};
165    TokenStream::from(expanded)
166}
167
168#[proc_macro]
169pub fn obfuscate_loop(input: TokenStream) -> TokenStream {
170    let input = parse_macro_input!(input as syn::ExprTuple);
171    let mut it = input.elems.into_iter();
172    let n = it.next().expect("count");
173    let body = it.next().expect("body");
174    let expanded = quote! {{
175        let __n: usize = (#n) as usize;
176        let mut __acc: u64 = 0;
177        for i in 0..__n { __acc ^= ((i as u64).wrapping_mul(0x9E3779B97F4A7C15)).rotate_left((i%23) as u32); (#body); }
178        std::hint::black_box(__acc);
179    }};
180    TokenStream::from(expanded)
181}
182
183#[proc_macro]
184pub fn obfuscate_const_bytes(input: TokenStream) -> TokenStream {
185    let lit = parse_macro_input!(input as LitByteStr);
186    let value = lit.value();
187    let key = generate_compile_time_key_bytes(&value);
188    let (encrypted_data, nonce) = encrypt_bytes_at_compile_time(&value, &key);
189    let expanded = quote! {{
190        const ENCRYPTED_DATA: &[u8] = &[#(#encrypted_data),*];
191        const NONCE: &[u8; 12] = &[#(#nonce),*];
192        const KEY: &[u8; 32] = &[#(#key),*];
193        rustcrypt_core::decrypt_bytes(ENCRYPTED_DATA, NONCE, KEY)
194    }};
195    TokenStream::from(expanded)
196}
197
198#[proc_macro]
199pub fn obfuscate_call(input: TokenStream) -> TokenStream {
200    let input = parse_macro_input!(input as syn::ExprCall);
201    
202    let func = &input.func;
203    
204    let expanded = quote! {{
205        let mut _func_ptr: fn() -> _ = unsafe { std::mem::transmute(#func) };
206        let _obfuscated = _func_ptr as usize;
207        let _deobfuscated = _obfuscated ^ 0xDEADBEEF;
208        let _final_func: fn() -> _ = unsafe { std::mem::transmute(_deobfuscated) };
209        _final_func()
210    }};
211    
212    TokenStream::from(expanded)
213}
214
215fn generate_compile_time_key(input: &str) -> [u8; 32] {
216    use std::collections::hash_map::DefaultHasher;
217    use std::hash::{Hash, Hasher};
218    
219    let mut hasher = DefaultHasher::new();
220    input.hash(&mut hasher);
221    let hash = hasher.finish();
222    
223    let mut key = [0u8; 32];
224    for (i, b) in key.iter_mut().enumerate() {
225        *b = ((hash >> (i % 8)) & 0xFF) as u8;
226    }
227    key
228}
229
230fn generate_compile_time_key_bytes(input: &[u8]) -> [u8; 32] {
231    use std::collections::hash_map::DefaultHasher;
232    use std::hash::{Hash, Hasher};
233    
234    let mut hasher = DefaultHasher::new();
235    input.hash(&mut hasher);
236    let hash = hasher.finish();
237    
238    let mut key = [0u8; 32];
239    for (i, b) in key.iter_mut().enumerate() {
240        *b = ((hash >> (i % 8)) & 0xFF) as u8;
241    }
242    key
243}
244
245fn encrypt_at_compile_time(input: &str, key: &[u8; 32]) -> (Vec<u8>, [u8; 12]) {
246    let bytes = input.as_bytes();
247    let mut encrypted = Vec::new();
248    
249    for (i, &byte) in bytes.iter().enumerate() {
250        encrypted.push(byte ^ key[i % 32]);
251    }
252    let mut nonce = [0u8; 12];
253    for i in 0..12 {
254        nonce[i] = key[i % 32];
255    }
256    
257    (encrypted, nonce)
258}
259
260fn encrypt_bytes_at_compile_time(input: &[u8], key: &[u8; 32]) -> (Vec<u8>, [u8; 12]) {
261    let mut encrypted = Vec::new();
262    
263    for (i, &byte) in input.iter().enumerate() {
264        encrypted.push(byte ^ key[i % 32]);
265    }
266    let mut nonce = [0u8; 12];
267    for i in 0..12 {
268        nonce[i] = key[i % 32];
269    }
270    
271    (encrypted, nonce)
272}