Make base62 project independent, more concise macro definitions.

This commit is contained in:
Michael Mikovsky
2026-02-20 14:54:12 -07:00
parent 6c6625e9ad
commit ba1772e512
13 changed files with 120 additions and 94 deletions
Generated
+11
View File
@@ -37,6 +37,16 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "base62"
version = "0.1.0"
dependencies = [
"aes",
"cbc",
"regex",
"sha2",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@@ -613,6 +623,7 @@ name = "ush-obfuscate"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"aes", "aes",
"base62",
"block-padding 0.4.2", "block-padding 0.4.2",
"cbc", "cbc",
"getrandom", "getrandom",
+2 -1
View File
@@ -21,7 +21,8 @@ members = [
"ush-payload", "ush-payload",
# Libraries # Libraries
"ush-obfuscate" "ush-obfuscate",
"base62"
] ]
[features] [features]
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "base62"
version = "0.1.0"
edition = "2024"
[dependencies]
aes = "0.8.4"
cbc = "0.1.2"
regex = "1.12.3"
sha2 = "0.10.9"
@@ -1,3 +1,8 @@
use aes::cipher::{BlockDecryptMut, KeyIvInit, block_padding::Pkcs7};
use regex::Regex;
use crate::{Base62, hash};
pub fn decrypt_aes(input: &str, key_str: &str, iv: [u8; 16]) -> Result<String, String> { pub fn decrypt_aes(input: &str, key_str: &str, iv: [u8; 16]) -> Result<String, String> {
// Hash the env key to get a 32-byte (256-bit) AES key // Hash the env key to get a 32-byte (256-bit) AES key
let mut key = hash(key_str.as_bytes()); let mut key = hash(key_str.as_bytes());
@@ -1,4 +1,4 @@
use crate::crypt::{base62::Base62, hash}; use crate::{base62::Base62, hash};
use aes::cipher::{BlockEncryptMut, KeyIvInit}; use aes::cipher::{BlockEncryptMut, KeyIvInit};
use cbc::cipher::block_padding::Pkcs7; use cbc::cipher::block_padding::Pkcs7;
@@ -1,4 +1,4 @@
use crate::crypt::{STATIC_BYTE_MAP, hash}; use crate::{STATIC_BYTE_MAP, hash};
// Randomly mapped Base62 characters // Randomly mapped Base62 characters
pub struct Base62 { pub struct Base62 {
@@ -1,9 +1,12 @@
pub mod aes_encrypt; mod aes_decrypt;
mod aes_encrypt;
#[allow(dead_code)] #[allow(dead_code)]
pub mod base62; mod base62;
pub const ENV_KEY_NAME: &str = "OBFUSCATION_KEY"; // Exports
pub const BACKUP_ENV_KEY: &str = "OBFUSCATION_KEY_DO_NOT_USE"; pub use aes_decrypt::{decrypt_aes, decrypt_aes_lines};
pub use aes_encrypt::{encrypt_aes, encrypt_aes_lines};
pub use base62::Base62;
pub const STATIC_IV: [u8; 16] = [ pub const STATIC_IV: [u8; 16] = [
0x6d, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x69, 0x76, 0x5f, 0x30, 0x31, 0x32, 0x6d, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x69, 0x76, 0x5f, 0x30, 0x31, 0x32,
+1 -1
View File
@@ -21,7 +21,7 @@ hex-literal = "1.1.0"
regex = "1.12.2" regex = "1.12.2"
sha2 = "0.10.9" sha2 = "0.10.9"
# unshell-crypt = {path = "../unshell-crypt"} base62 = {path = "../base62"}
# Common # Common
static_init = { workspace = true } static_init = { workspace = true }
+9
View File
@@ -0,0 +1,9 @@
const ENV_KEY_NAME: &str = "OBFUSCATION_KEY";
const BACKUP_ENV_KEY: &str = "OBFUSCATION_KEY_DO_NOT_USE";
pub fn get_encryption_key() -> String {
std::env::var(ENV_KEY_NAME).unwrap_or({
println!("Using default encryption key!");
BACKUP_ENV_KEY.to_owned()
})
}
+69 -6
View File
@@ -1,9 +1,72 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::parse::{Parse, ParseStream}; use syn::parse::{Parse, ParseStream};
use syn::{Expr, Lit, Token}; use syn::{Expr, Lit, Token, parse_macro_input};
pub struct PrintlnArgs { pub fn format_obs(input: TokenStream) -> TokenStream {
pub format_str: String, let PrintlnArgs { format_str, args } = parse_macro_input!(input as PrintlnArgs);
pub args: Vec<Expr>,
let segments = parse_format_string(&format_str);
if segments.is_empty() {
return quote! {
print!("\n")
}
.into();
}
let mut parts = Vec::new();
for segment in segments {
match segment {
FormatSegment::Static(text) => {
parts.push(quote! {
obfuscate::symbol!(#text).to_string()
});
}
FormatSegment::Dynamic(spec, idx) => {
if idx >= args.len() {
return syn::Error::new(
proc_macro2::Span::call_site(),
format!("argument {} is missing", idx),
)
.to_compile_error()
.into();
}
let arg = &args[idx];
let fmt_spec = if spec.is_empty() {
quote! { "{}" }
} else {
let full_spec = format!("{{{}}}", spec);
quote! { #full_spec }
};
// quote! {
// println!(#fmt_spec, #arg);
// }
parts.push(quote! {
format!(#fmt_spec, #arg)
});
}
}
}
(quote! {
{
let mut string = String::new();
#(
string.push_str(&#parts);
)*
string
}
})
.into()
}
struct PrintlnArgs {
format_str: String,
args: Vec<Expr>,
} }
impl Parse for PrintlnArgs { impl Parse for PrintlnArgs {
@@ -40,12 +103,12 @@ impl Parse for PrintlnArgs {
} }
#[derive(Debug)] #[derive(Debug)]
pub enum FormatSegment { enum FormatSegment {
Static(String), Static(String),
Dynamic(String, usize), // format spec, arg index Dynamic(String, usize), // format spec, arg index
} }
pub fn parse_format_string(fmt: &str) -> Vec<FormatSegment> { fn parse_format_string(fmt: &str) -> Vec<FormatSegment> {
let mut segments = Vec::new(); let mut segments = Vec::new();
let mut current_static = String::new(); let mut current_static = String::new();
let mut chars = fmt.chars().peekable(); let mut chars = fmt.chars().peekable();
+2 -67
View File
@@ -3,12 +3,9 @@
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use quote::quote;
use syn::parse_macro_input;
mod env;
mod format_helper; mod format_helper;
use format_helper::*;
mod crypt;
#[allow(dead_code, unused_imports)] #[allow(dead_code, unused_imports)]
mod no_obfuscate; mod no_obfuscate;
@@ -43,8 +40,6 @@ pub fn junk_asm(input: TokenStream) -> TokenStream {
obs::junk_asm(input) obs::junk_asm(input)
} }
//
#[proc_macro] #[proc_macro]
pub fn file_symbol(_input: TokenStream) -> TokenStream { pub fn file_symbol(_input: TokenStream) -> TokenStream {
// Get the call site span to extract file information // Get the call site span to extract file information
@@ -58,70 +53,10 @@ pub fn file_symbol(_input: TokenStream) -> TokenStream {
let output = quote! { let output = quote! {
obfuscate::symbol!(#concatted) obfuscate::symbol!(#concatted)
}; };
// let output = quote! {
// #concatted
// };
output.into() output.into()
} }
#[proc_macro] #[proc_macro]
pub fn format_obs(input: TokenStream) -> TokenStream { pub fn format_obs(input: TokenStream) -> TokenStream {
let PrintlnArgs { format_str, args } = parse_macro_input!(input as PrintlnArgs); format_helper::format_obs(input)
let segments = parse_format_string(&format_str);
if segments.is_empty() {
return quote! {
print!("\n")
}
.into();
}
let mut parts = Vec::new();
for segment in segments {
match segment {
FormatSegment::Static(text) => {
parts.push(quote! {
obfuscate::symbol!(#text).to_string()
});
}
FormatSegment::Dynamic(spec, idx) => {
if idx >= args.len() {
return syn::Error::new(
proc_macro2::Span::call_site(),
format!("argument {} is missing", idx),
)
.to_compile_error()
.into();
}
let arg = &args[idx];
let fmt_spec = if spec.is_empty() {
quote! { "{}" }
} else {
let full_spec = format!("{{{}}}", spec);
quote! { #full_spec }
};
// quote! {
// println!(#fmt_spec, #arg);
// }
parts.push(quote! {
format!(#fmt_spec, #arg)
});
}
}
}
(quote! {
{
let mut string = String::new();
#(
string.push_str(&#parts);
)*
string
}
})
.into()
} }
-11
View File
@@ -5,14 +5,3 @@ mod sym_aes_strings;
pub use obs_junk_asm::junk_asm; pub use obs_junk_asm::junk_asm;
pub use obs_xor::xor; pub use obs_xor::xor;
pub use sym_aes_strings::*; pub use sym_aes_strings::*;
use crate::crypt::{BACKUP_ENV_KEY, ENV_KEY_NAME};
fn get_encryption_key() -> String {
std::env::var(ENV_KEY_NAME).unwrap_or({
println!("Using default encryption key!");
BACKUP_ENV_KEY.to_owned()
})
}
// pub fn
@@ -1,9 +1,9 @@
use crate::crypt::{BACKUP_ENV_KEY, ENV_KEY_NAME, STATIC_IV, aes_encrypt::encrypt_aes_lines}; use base62::{STATIC_IV, encrypt_aes_lines};
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use quote::quote;
use syn::{ItemFn, LitStr, parse_macro_input}; use syn::{ItemFn, LitStr, parse_macro_input};
use crate::obfuscate::get_encryption_key; use crate::env::get_encryption_key;
/// Obfuscate function names by encrypting in AES /// Obfuscate function names by encrypting in AES
pub fn aes_fn_name(_attr: TokenStream, item: TokenStream) -> TokenStream { pub fn aes_fn_name(_attr: TokenStream, item: TokenStream) -> TokenStream {