Improve Rust code clarity across the workspace

Document public APIs and non-obvious control flow so the protocol, simulator, and macro crates are easier to follow. Tighten a few helper paths and feature gates while preserving behavior and keeping the workspace warning-free.
This commit is contained in:
Michael Mikovsky
2026-04-25 11:11:19 -06:00
parent f49af7fa22
commit ba3f28a78c
26 changed files with 571 additions and 402 deletions
+3
View File
@@ -1,6 +1,9 @@
const ENV_KEY_NAME: &str = "OBFUSCATION_KEY";
const BACKUP_ENV_KEY: &str = "OBFUSCATION_KEY_DO_NOT_USE";
/// Returns the obfuscation key used by the proc macros.
///
/// The fallback keeps macro expansion deterministic when the environment variable is absent.
pub fn get_encryption_key() -> String {
if let Ok(key) = std::env::var(ENV_KEY_NAME) {
key
+6 -6
View File
@@ -3,6 +3,7 @@ use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::{Expr, Lit, Token, parse_macro_input};
/// Expands `sym_format!` into a string builder that obfuscates static segments only.
pub fn sym_format(input: TokenStream) -> TokenStream {
let PrintlnArgs { format_str, args } = parse_macro_input!(input as PrintlnArgs);
@@ -42,9 +43,6 @@ pub fn sym_format(input: TokenStream) -> TokenStream {
quote! { #full_spec }
};
// quote! {
// println!(#fmt_spec, #arg);
// }
parts.push(quote! {
format!(#fmt_spec, #arg)
});
@@ -105,9 +103,13 @@ impl Parse for PrintlnArgs {
#[derive(Debug)]
enum FormatSegment {
Static(String),
Dynamic(String, usize), // format spec, arg index
Dynamic(String, usize),
}
/// Splits a Rust formatting string into literal and replacement segments.
///
/// This only handles the subset needed by `sym_format!`: positional replacements in order,
/// plus escaped braces.
fn parse_format_string(fmt: &str) -> Vec<FormatSegment> {
let mut segments = Vec::new();
let mut current_static = String::new();
@@ -122,13 +124,11 @@ fn parse_format_string(fmt: &str) -> Vec<FormatSegment> {
continue;
}
// Save current static segment
if !current_static.is_empty() {
segments.push(FormatSegment::Static(current_static.clone()));
current_static.clear();
}
// Parse format spec
let mut spec = String::new();
while let Some(&next_ch) = chars.peek() {
if next_ch == '}' {
+13 -11
View File
@@ -1,5 +1,5 @@
/// Call some other function
macro_rules! passtrough {
macro_rules! passthrough {
($name:tt, $ref:expr) => {
pub fn $name(input: TokenStream) -> TokenStream {
$ref(input)
@@ -42,25 +42,27 @@ pub mod proc_impl {
unwrap_string!(sym_fn);
}
#[cfg(feature = "obfuscate_aes")]
#[cfg(all(feature = "obfuscate_aes", not(feature = "obfuscate_ref")))]
pub mod proc_impl {
use proc_macro::TokenStream;
passtrough!(xor, crate::obfuscate::xor);
passtrough!(junk_asm, crate::obfuscate::junk_asm);
passthrough!(xor, crate::obfuscate::xor);
passthrough!(junk_asm, crate::obfuscate::junk_asm);
passtrough!(sym, crate::symbolic_aes::aes_str);
passtrough!(sym_fn, crate::symbolic_aes::aes_fn_name);
passthrough!(sym, crate::symbolic_aes::aes_str);
passthrough!(sym_fn, crate::symbolic_aes::aes_fn_name);
}
#[cfg(feature = "obfuscate_ref")]
pub mod proc_impl {
use proc_macro::TokenStream;
use syn::{LitStr, parse_macro_input};
passtrough!(xor, crate::obfuscate::xor);
passtrough!(junk_asm, crate::obfuscate::junk_asm);
passthrough!(xor, crate::obfuscate::xor);
passthrough!(junk_asm, crate::obfuscate::junk_asm);
passtrough!(sym, crate::symbolic_ref::sym_ref);
passtrough!(sym_fn, crate::symbolic_ref::sym_ref_fn);
// `sym` and `sym_fn` need one concrete strategy. When both feature flags are enabled,
// prefer symbolic references so `cargo clippy --all-features` still selects a single,
// deterministic implementation.
passthrough!(sym, crate::symbolic_ref::sym_ref);
passthrough!(sym_fn, crate::symbolic_ref::sym_ref_fn);
}
+12 -19
View File
@@ -1,5 +1,3 @@
use std::collections::HashMap;
use base62::{Base62, hash};
use proc_macro::TokenStream;
use quote::quote;
@@ -10,11 +8,13 @@ use crate::env::get_encryption_key;
static mut SYM_COUNTER: Vec<String> = Vec::new();
#[allow(static_mut_refs)]
/// Returns how many unique symbols have been registered in this macro process.
pub fn get_symbol_number() -> usize {
unsafe { SYM_COUNTER.len() }
}
#[allow(static_mut_refs)]
/// Returns the stable numeric ID for `text`, inserting it on first use.
pub fn get_symbol(text: &str) -> usize {
unsafe {
if let Some(n) = SYM_COUNTER.iter().position(|r| r == text) {
@@ -27,47 +27,40 @@ pub fn get_symbol(text: &str) -> usize {
}
}
fn ref_string(input: String) -> String {
let n = get_symbol(&input);
fn encode_symbol_reference(symbol: String) -> String {
let symbol_index = get_symbol(&symbol);
let data = base62::encode_usize(n);
let key = hash(&get_encryption_key().as_bytes());
let data = base62::encode_usize(symbol_index);
let key = hash(get_encryption_key().as_bytes());
let encoded = format!("_{}_", Base62::encode_full(&data, &key));
println!("Aliased '{}' as '{encoded}'", input);
// Macro expansion logs make it easier to correlate exported symbols with their aliases.
println!("Aliased '{}' as '{encoded}'", symbol);
encoded
}
/// Replaces a string literal with its symbolic reference alias.
pub fn sym_ref(input: TokenStream) -> TokenStream {
// Parse the input as a string literal
let lit_str = parse_macro_input!(input as LitStr);
let original_name = lit_str.value();
let encoded = ref_string(original_name);
let encoded = encode_symbol_reference(original_name);
// Expand to a static string literal
TokenStream::from(quote! {
#encoded
})
}
/// Re-exports a function under a symbolic reference alias.
pub fn sym_ref_fn(input: TokenStream) -> TokenStream {
// Parse the input function
let func = parse_macro_input!(input as ItemFn);
// Get the original function name
let fn_name = func.sig.ident.to_string();
// Generate the new, obfuscated name
let obfuscated_name = ref_string(fn_name);
// Create a new string literal for the name
let obfuscated_name = encode_symbol_reference(fn_name);
let new_name_lit = LitStr::new(&obfuscated_name, func.sig.ident.span());
// Re-build the function, but add #[no_mangle]
// and rename the *exported* symbol via #[export_name]
TokenStream::from(quote! {
#[unsafe(export_name = #new_name_lit)]
#func