Obfuscation is not working properly
I clone git and install using "cargo build --release --bin rust-obfuscator", and rust-obfuscator output prorperly.
And I create new cargo repository, and I write "main.rs" and Cargo.toml" like next:
`use cryptify;
mod word_counter;
use std::env;
use std::fs;
use word_counter::count_words;
fn main() {
let b = "Hello World";
println!("{}", b);
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
eprintln!("Usage: {}
fn dummy() { let a = 1; let b = 2; let c = a + b; println!("{}", c); }
fn calc_sum(a: i32, b: i32) -> i32 { cryptify::flow_stmt!(); let c = a + b; c }
fn helloooo(){ println!("hi"); } `
`[package] name = "sample" version = "0.1.0" edition = "2024"
[dependencies] cryptify = "3.1.1"`
As described in the documentation, I attempted to obfuscate my source code using rust-obfuscator "./rust-obfuscator/target/release/rust-obfuscator ./sample/src/main.rs ".
However, the result was as follows:
use cryptify ; mod word_counter ; use std :: env ; use std :: fs ; use word_counter :: count_words ; fn main () { cryptify :: flow_stmt ! () ; let b = cryptify :: encrypt_string ! ("Hello World") ; println ! ("{}" , b) ; let args : Vec < String > = env :: args () . collect () ; if args . len () < 2 { eprintln ! ("Usage: {} <filename>" , args [0]) ; return ; } let filename = & args [1] ; let content = fs :: read_to_string (filename) . expect ("Could not read file") ; let word_counts = count_words (& content) ; for (word , count) in word_counts . iter () { println ! ("{}: {}" , word , count) ; } } fn dummy () { cryptify :: flow_stmt ! () ; let a = 1 ; let b = 2 ; let c = a + b ; println ! ("{}" , c) ; } fn calc_sum (a : i32 , b : i32) -> i32 { cryptify :: flow_stmt ! () ; let c = a + b ; c } fn helloooo () { println ! ("hi") ; }
- first, output code is stripped. every newline character were deleted.
- second, output code is not obfuscated.
Did I use it incorrectly? I would appreciate it if you could provide a solution.
I believe I've figured out how to use it. You will have to use a Rust formatter like rustfmt to get it back to a readable format.
It also states in the README:
String Encryption: Automatically encrypts string literals assigned to local variables at compile time.
- Can also be used for formatted strings, but currently requires manual placement
But I haven't noticed it adding the cryptify anywhere automatically so you may have to do it manually.
I used the --disable_macro argument to use direct source manipulation instead of the macros.
./rust-obfuscator --disable_macro src/main.rs:
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
slint::include_modules!();
use cryptify;
mod app;
mod state;
mod bindings;
use state::AppState;
use jemallocator::Jemalloc;
use std::sync::{ Arc, Mutex };
#[global_allocator]
static GLOBAL: Jemalloc = Jemalloc;
fn main() -> Result<(), slint::PlatformError> {
let app = AppWindow::new()?;
let state = Arc::new(Mutex::new(AppState { counter: 0 }));
let s = "Hello world 1";
println!("{s}");
app.set_counter_text("Count: 0".into());
// Initialize window bindings
bindings::app_window::AppWindowBindings::init(&app, state);
app.run()
}
Obfuscates to:
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
slint::include_modules!();
use cryptify;
mod app;
mod bindings;
mod state;
use jemallocator::Jemalloc;
use state::AppState;
use std::sync::{Arc, Mutex};
#[global_allocator]
static GLOBAL: Jemalloc = Jemalloc;
fn main() -> Result<(), slint::PlatformError> {
{
let _is_dummy_145 = true;
let mut _dummy_counter = 8i32;
let _dummy_increment = 4i32;
let _dummy_upper_bound = 100;
loop {
if _dummy_counter > _dummy_upper_bound {
break;
}
unsafe {
std::ptr::write_volatile(&mut _dummy_counter, _dummy_counter + _dummy_increment);
}
}
}
let app = AppWindow::new()?;
let state = Arc::new(Mutex::new(AppState { counter: 0 }));
let s = "Hello world 1";
println!("{s}");
app.set_counter_text("Count: 0".into());
bindings::app_window::AppWindowBindings::init(&app, state);
app.run()
}
Doesn't seem like much, but this is also a small code sample.
I’m sorry—that was my mistake. The obfuscation itself is working correctly. However, when I use the --var option for variable obfuscation, the compiler throws errors caused by the obfuscated variables. Is there any way to resolve this issue?
I’m sorry—that was my mistake. The obfuscation itself is working correctly. However, when I use the --var option for variable obfuscation, the compiler throws errors caused by the obfuscated variables. Is there any way to resolve this issue?
Hey, thanks for this did notice some issues with var renaming, fix should be up.
The renaming for function parameters seems to be working now. However, there still seems to be a few issues with how renaming is handled with method names and function calls:
- When a function name is changed, the corresponding function calls are not updated to match.
- Method names within impl blocks don't appear to be renamed.
For example, the following code:
struct Foo;
impl Foo {
fn bar(&self) {
let baz = true;
if baz {
qux();
}
}
}
fn qux() {
println!("qux fn");
}
Outputs after running ./rust-obfuscator foo.rs --var:
struct Foo;
impl Foo {
// Method doesn't get renamed
fn bar(&self) {
cryptify::flow_stmt!();
{
let rjwflhhhz = true;
let mut lzlnsk = 9i32;
let q_srdhn_r = 100;
let uffg_q_u = 1i32;
loop {
if lzlnsk > q_srdhn_r {
break;
}
unsafe {
std::ptr::write_volatile(&mut lzlnsk, lzlnsk + uffg_q_u);
}
}
}
let ptkxklg = true;
if ptkxklg {
qux(); // Function call not replaced with new name: rh_lwtr_s
}
}
}
fn rh_lwtr_s() {
println!("qux fn");
}
The function qux() has been renamed to rh_lwtr_s(), but the call site inside bar() was not updated accordingly. This causes a compilation error, since qux() no longer exists.
The method bar() was not renamed.
I also noticed that some areas don't get added control flow statements, like in the qux() function, but I am not sure if this is intended behavior to try and prevent patterns.
Yes not every area is meant to get control flow, Assigned randomly within certain functions for better obfuscation. I'll continue to work on var renaming as it is clearly not fully functional and modify the README to mention it as an experimental feature (for now). Thanks.