Comprehensive test suite for the binary obfuscator, ensuring all obfuscation passes preserve program functionality.
A Rust program designed to exercise all obfuscation transformations. Contains 64+ test cases covering:
- Addition/Subtraction: Basic and overflow scenarios
- Multiplication: Standard and power-of-two optimizations
- Division/Modulo: With zero checks
- Increment/Decrement: Single and loop patterns
- Basic: AND, OR, XOR, NOT
- Shifts: Left and right shifts
- Complex: Compound operations like
(a & b) | (c ^ a) - Bit Counting: Population count patterns
- Simple Conditionals: Single if/else
- Nested Conditionals: Multiple levels of nesting
- Multiple Branches: Switch-like patterns
- Early Returns: Multiple exit points
- Match Patterns: Rust match statements (potential jump tables)
- Simple Loops: While and for loops
- Nested Loops: Multiple nesting levels
- Break/Continue: Early exit and skip patterns
- Recursion: Fibonacci and factorial
- Array Access: Indexing operations
- Array Iteration: Sum, max, reverse
- Pointer Arithmetic: LEA-heavy operations
- Struct Access: Multi-field structures
- Zero Operations: Comparisons with zero
- Overflow/Underflow: Wrapping arithmetic
- Negative Numbers: Sign handling
- All Comparisons: <, <=, >, >=, ==, !=
- Deep Nesting: Nested blocks and expressions
Verifies the unobfuscated test binary passes all its internal tests. Ensures baseline functionality.
Expectations:
- All 64+ tests pass (excluding match pattern tests which may invoke jump-table functions)
- Exit code 0
- Output contains "RESULT: SUCCESS"
The main integration test. Obfuscates the binary and verifies identical output.
Steps:
- Build test-binary
- Run original binary, capture output
- Obfuscate binary
- Run obfuscated binary, capture output
- Compare outputs (must be identical)
Verifications:
- Original binary passes all tests
- Obfuscated binary passes all tests
- Outputs match exactly
- Both exit with code 0
Verifies obfuscation produces larger binaries.
Expectations:
- Obfuscated binary > 10% larger than original
- Typical increase: 20-50%
Tests obfuscation with logging enabled (integration test for error handling).
Verifies multiple obfuscation runs produce consistent results.
Expectations:
- Size variation < 20% (allows for randomization)
- Both runs complete successfully
Verifies obfuscated binary produces well-formed output.
Expectations:
- Contains test markers ([PASS]/[FAIL])
- Contains result summary
- At least some tests pass
Tested by:
- All array operations (LEA chains)
- Pointer arithmetic in
array_reverse_sum,array_index - Complex math operations
- Struct field access (
Point)
What's tested:
- LEA displacement splitting
- Multi-instruction LEA chains
- Compensating arithmetic
Tested by:
- All function calls (PUSH/POP operations)
nested_calls- multiple stack framesdeep_call_chain- deep call stacks- Recursive functions (
fibonacci,factorial)
What's tested:
- PUSH → MOV + LEA expansion
- POP → MOV + LEA expansion
- Stack frame preservation
Tested by:
- All function calls
- Recursive calls
- Nested function calls
What's tested:
- Call instruction obfuscation
- Return address manipulation
- Call target preservation
Tested by:
- All functions (noise inserted between instructions)
- Complex operations provide more insertion opportunities
What's tested:
- Dead store insertion
- Useless arithmetic chains
- Stack reference obfuscation
- Semantic preservation
cargo testcargo test --test integration_testcargo test -- --nocapturecargo test test_obfuscation_preserves_functionalitytest test_original_binary_passes_all_tests ... ok
test test_obfuscation_preserves_functionality ... ok
test test_obfuscation_increases_binary_size ... ok
test test_obfuscation_with_verbose_logging ... ok
test test_multiple_obfuscation_runs_consistent ... ok
test test_obfuscated_binary_output_format ... ok
test result: ok. 6 passed; 0 failed
[PASS] add_i32(5, 3) == 8
[PASS] multiply_i32(6, 7) == 42
[PASS] fibonacci(7) == 13
[PASS] nested_conditions(1, 1, 1) == 3
...
=== RESULT: SUCCESS (75 tests passed) ===
- Add new
#[inline(never)]function - Add test case to
main()usingrunner.run() - Use
black_box()to prevent optimization
#[inline(never)]
fn my_function(x: i32) -> i32 {
x + 1
}
// In main():
runner.run("my_function(5) == 6", || {
black_box(my_function(black_box(5))) == 6
});Add new test function to integration_test.rs:
#[test]
fn test_my_scenario() {
build_package("test-binary");
// ... test implementation
}- Check test logic in
main.rs - Run
cargo build --package test-binary - Run
.\target\debug\test-binary.exedirectly
- Enable verbose logging
- Check which specific tests fail
- Look for patterns (e.g., all arithmetic tests fail)
- May indicate issues in specific obfuscation pass
- Compare outputs line by line
- Look for calculation errors
- Check for deterministic behavior (no timing/randomness)
Typical obfuscation performance (320 functions):
- Analysis: ~50ms
- Obfuscation: ~150ms
- Compilation: ~100ms
- Total: ~300-350ms
Test binary execution:
- Original: 1-5ms
- Obfuscated: 2-10ms
- Overhead: ~2-5x (acceptable for obfuscated code)