mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-08 22:38:01 -06:00
53 lines
1.6 KiB
Rust
53 lines
1.6 KiB
Rust
use getrandom::fill;
|
|
use proc_macro::TokenStream;
|
|
use quote::quote;
|
|
use syn::{LitStr, parse_macro_input};
|
|
|
|
/// XOR encrypt strings
|
|
pub fn xor(input: TokenStream) -> TokenStream {
|
|
// Parse the input as a string literal
|
|
let lit_str = parse_macro_input!(input as LitStr);
|
|
let original_str = lit_str.value();
|
|
|
|
// Handle empty strings explicitly
|
|
if original_str.is_empty() {
|
|
return TokenStream::from(quote! { String::new() });
|
|
}
|
|
|
|
// --- Obfuscated Branch Logic ---
|
|
// This code runs at compile-time
|
|
|
|
let str_bytes = original_str.as_bytes();
|
|
let len = str_bytes.len();
|
|
|
|
// 1. Generate a unique, random key for this string
|
|
let mut key = vec![0u8; len];
|
|
fill(&mut key).expect("Failed to get random bytes for XOR key");
|
|
|
|
// 2. XOR the string with the key
|
|
let mut obfuscated = Vec::with_capacity(len);
|
|
for i in 0..len {
|
|
obfuscated.push(str_bytes[i] ^ key[i]);
|
|
}
|
|
|
|
// 3. This is the code that will be injected into the user's binary
|
|
// It runs at *runtime* to decrypt the string.
|
|
let obfuscated_expansion = quote! {
|
|
{
|
|
// These static arrays are stored directly in your binary
|
|
static OBFUSCATED_DATA: [u8; #len] = [ #( #obfuscated ),* ];
|
|
static KEY_DATA: [u8; #len] = [ #( #key ),* ];
|
|
|
|
let mut decrypted = Vec::with_capacity(#len);
|
|
for i in 0..#len {
|
|
decrypted.push(OBFUSCATED_DATA[i] ^ KEY_DATA[i]);
|
|
}
|
|
|
|
// We can trust this since the source was a valid String literal
|
|
String::from_utf8(decrypted).unwrap()
|
|
}
|
|
};
|
|
|
|
TokenStream::from(obfuscated_expansion)
|
|
}
|