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#[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}