Expand description

Rust anti-analysis library for making static and dynamic (debugging) analysis more difficult.

The library targets Linux environments.

It is currently based on ptrace anti-analysis trick and has the following features:

  • Direct syscall invocation without relying on libc (this makes LD_PRELOAD bypass mechanism ineffective);
  • Multiple ptrace syscall invocations. Each call to ptrace must return the expected value and contributes to the computation of an “offset” value that, at the end of the call chain, must match an expected value (see here);
  • ‘ptrace’ is called in nested loops. The loops are unrolled and the number of iterations is randomized at each compilation. Also the "offset“ value is radomized at each iteration;
  • The produced code can be obfuscated even more by enabling the obfuscate feature which relies on goldberg crate;

Overall, this is not the final solution against static and dynamic analysis but for sure it is going to make the reverser/analyst life a little bit more difficult.

to use the crate, add it to your dependencies:

[dependencies]
debugoff = { version = "0.1.0, features = ["obfuscate"] }

Given that the library generates random code at each compilation, be sure to rebuild everything each time. Something like this:

cargo clean
cargo build --release

Also, it would be a good idea to build the project without symbols:

[profile.release]
debug = false
strip = "symbols"
panic = "abort"

Usage Example

// Include only for Linux and when building in release mode
#[cfg(target_os = "linux")]
#[cfg(not(debug_assertions))]
use debugoff;
use std::time::SystemTime;


// Call only for Linux and when building in release mode
#[cfg(target_os = "linux")]
#[cfg(not(debug_assertions))]
debugoff::multi_ptraceme_or_die();

println!(
    "Time: {}",
    SystemTime::now()
        .duration_since(SystemTime::UNIX_EPOCH)
        .unwrap()
        .as_millis()
);

// Call only for Linux and when building in release mode
#[cfg(target_os = "linux")]
#[cfg(not(debug_assertions))]
debugoff::multi_ptraceme_or_die();

println!("Example complete!");

Functions

Call ptrace(PTRACE_TRACEME, ...) multiple times in nested loops.

Call ptrace(PTRACE_TRACEME, ...) to detect the presence of a debugger.