A powerful LLVM-based code obfuscation tool for C/C++ programs that generates hardened binaries for Linux and Windows platforms with detailed reporting.
This tool leverages LLVM's compiler infrastructure to apply multiple obfuscation techniques to C/C++ code, making reverse engineering significantly more difficult while maintaining functional correctness.
-
✅ Multiple Obfuscation Techniques
- Bogus code injection (dead code that never executes)
- Fake loop insertion (unreachable loops)
- Instruction substitution (complex equivalents for simple operations)
- Control flow obfuscation
-
✅ Cross-Platform Support
- Linux native binaries
- Windows cross-compilation support
-
✅ Detailed Reporting
- Input parameter logging
- Output file attributes
- Obfuscation statistics
- Code size impact analysis
ollvm/
├── obfuscate # CLI tool executable
├── obfuscator_pass/ # LLVM pass plugin
│ ├── Obfuscator.cpp # Obfuscation logic
│ ├── CMakeLists.txt # Build configuration
│ └── build/
│ └── ObfuscatorPass.so # Compiled plugin
└── obfuscate.cpp # CLI tool source
- LLVM 20+ (with development headers)
- Clang++ (C++ compiler with LLVM support)
- CMake 3.10+ (optional, for build configuration)
- MinGW-w64 (for Windows cross-compilation, optional)
sudo pacman -S llvm clang cmake
# For Windows cross-compilation:
sudo pacman -S mingw-w64-gccsudo apt install llvm clang cmake
# For Windows cross-compilation:
sudo apt install mingw-w64-gcccd ~/ollvm/obfuscator_pass
# Compile the obfuscation pass
clang++ -shared -fPIC \
$(llvm-config --cxxflags) \
-o build/ObfuscatorPass.so \
Obfuscator.cpp \
$(llvm-config --ldflags --libs core passes support)Verify it was built:
ls -lh build/ObfuscatorPass.so
# Should show a file around 100KBcd ~/ollvm
# Compile the CLI tool
clang++ -o obfuscate obfuscate.cpp -std=c++17./obfuscate input.cppThis will:
- Compile
input.cppto LLVM IR - Apply obfuscation transformations
- Generate
input_obfuscatedexecutable - Create
obfuscation_report.txt
./obfuscate [options] <input.cpp>
Options:
-o <file> Output file name (default: <input>_obfuscated)
-r <file> Report file name (default: obfuscation_report.txt)
-l <level> Obfuscation level: low, medium, high (default: medium)
--windows Generate Windows executable
--linux Generate Linux executable (default)
-h, --help Show help message# Basic obfuscation
./obfuscate main.cpp
# Custom output name
./obfuscate main.cpp -o protected_app
# Generate Windows executable
./obfuscate main.cpp --windows -o app_win
# Custom report location
./obfuscate main.cpp -r logs/obfuscation_log.txt
# High obfuscation level (future feature)
./obfuscate main.cpp -l highFor development and debugging:
# Step 1: Compile to LLVM IR
clang++ -emit-llvm -c main.cpp -o main.bc
# Step 2: Apply obfuscation
opt -load-pass-plugin=./obfuscator_pass/build/ObfuscatorPass.so \
-passes="obfuscator-pass" \
main.bc -o main_obf.bc 2>&1
# Step 3: View human-readable IR
llvm-dis main_obf.bc -o main_obf.ll
cat main_obf.ll
# Step 4: Compile to executable
clang++ main_obf.bc -o hello_obfuscatedThe generated report includes:
========================================
LLVM Obfuscation Report
========================================
Generation Time: 2025-10-12 22:59:45
Tool Version: 1.0
--- Input Parameters ---
Input File: main.cpp
Output File: main_obfuscated
Obfuscation Level: medium
Target Platform: linux
String Encryption: Enabled
Bogus Code Injection: Enabled
Fake Loop Insertion: Enabled
Instruction Substitution: Enabled
--- Output File Attributes ---
File Size (original): 103 bytes
File Size (obfuscated): 16384 bytes
Size Increase: 16281 bytes
Methods Applied:
- Control Flow Obfuscation
- Bogus Code Insertion
- Fake Loop Injection
- Instruction Substitution
--- Obfuscation Statistics ---
Total Instructions Processed: 5
Total Basic Blocks: 1
String Obfuscations: 1
Bogus Code Blocks Added: 2
Fake Loops Inserted: 1
Instruction Substitutions: 0
--- Code Size Impact ---
Original Instructions: ~5
Bogus Instructions Added: ~11
Code Size Increase: ~220%
--- Obfuscation Cycles ---
Number of Passes Completed: 1
Functions Obfuscated: 1
========================================
Obfuscation completed successfully!
========================================
Inserts unreachable code blocks with fake computations that appear legitimate but never execute.
Example:
// Original
int x = 5;
// After obfuscation (simplified view)
int x = 5;
if (1 == 0) { // Always false
int fake1 = 42;
int fake2 = fake1 + 13;
// ... more fake operations
}Adds loops that look real but are controlled by impossible conditions.
Example:
// Original
return result;
// After obfuscation
if (false) { // Never executes
for (int i = 0; i < 10; i++) {
// fake computations
}
}
return result;Replaces simple operations with mathematically equivalent but more complex ones.
Example:
// Original
int sum = a + b;
// After obfuscation
int sum = a - (-b); // Equivalent but more complexAdds conditional branches that make the control flow graph more complex.
LLVM IR (Intermediate Representation) is the key to this obfuscation process.
Source Code (.cpp)
↓ [Clang Frontend]
LLVM IR (.bc/.ll)
↓ [Obfuscation Pass]
Obfuscated IR (.bc)
↓ [LLVM Backend]
Machine Code (executable)
# Compile to IR
clang++ -emit-llvm -S main.cpp -o main.ll
# View the IR
cat main.llExample IR for int x = 5;:
%1 = alloca i32, align 4
store i32 5, ptr %1, align 4# Create test file
cat > test.cpp << 'EOF'
#include <iostream>
int main() {
int x = 10;
int y = 20;
int sum = x + y;
std::cout << "Sum: " << sum << std::endl;
return 0;
}
EOF
# Obfuscate it
./obfuscate test.cpp -o test_obf
# Run original
clang++ test.cpp -o test_orig
./test_orig
# Output: Sum: 30
# Run obfuscated
./test_obf
# Output: Sum: 30 (should be identical)# Compare IR before and after
clang++ -emit-llvm -S test.cpp -o test_before.ll
opt -load-pass-plugin=./obfuscator_pass/build/ObfuscatorPass.so \
-passes="obfuscator-pass" \
test.bc -S -o test_after.ll
# Check the difference
diff test_before.ll test_after.ll
# Should show added bogus blocks, fake loops, etc.# Check original size
clang++ test.cpp -o test_orig
ls -lh test_orig
# Check obfuscated size
./obfuscate test.cpp -o test_obf
ls -lh test_obf
# Obfuscated should be larger due to bogus codeSolution: Use the direct clang++ compilation method instead of CMake:
cd obfuscator_pass
clang++ -shared -fPIC \
$(llvm-config --cxxflags) \
-o build/ObfuscatorPass.so \
Obfuscator.cpp \
$(llvm-config --ldflags --libs core passes support)Solution: Verify the plugin exports the correct symbol:
nm -D obfuscator_pass/build/ObfuscatorPass.so | grep llvmGetPassPluginInfoShould show:
000000000000aea0 W llvmGetPassPluginInfo
Solution: Check if the pass is running:
opt -load-pass-plugin=./obfuscator_pass/build/ObfuscatorPass.so \
-passes="obfuscator-pass" \
-debug-pass-manager \
main.bc -o main_obf.bc 2>&1You should see:
Running pass: (anonymous namespace)::ObfuscatorPass on main
Solution: Install MinGW toolchain:
sudo pacman -S mingw-w64-gccOr compile on Linux only (skip --windows flag).
This project uses a Function Pass which operates on individual functions:
struct ObfuscatorPass : public PassInfoMixin<ObfuscatorPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
// Transformation logic here
return PreservedAnalyses::none();
}
};- Platform Independent: Works on any target LLVM supports
- High Level: Easier to analyze than assembly
- Low Level: Close enough to machine code for effective obfuscation
- Standardized: Well-documented format
- Optimization: Makes code faster/smaller
- Obfuscation: Makes code harder to understand
LLVM's optimization passes can be used in reverse to add complexity!
Potential improvements for the project:
- Advanced String Encryption: XOR-based encryption with runtime decryption
- Control Flow Flattening: Convert structured code to switch-based dispatch
- Opaque Predicates: Conditions that are hard to evaluate statically
- Virtual Machine Obfuscation: Convert code to custom bytecode
- Anti-Debugging: Detect and prevent debugger attachment
- Symbol Stripping: Remove function/variable names
- Multiple Pass Cycles: Apply obfuscation repeatedly
- Configurable Intensity: Fine-tune each technique independently
clang++ -g -O0 -shared -fPIC \
$(llvm-config --cxxflags) \
-o build/ObfuscatorPass.so \
Obfuscator.cpp \
$(llvm-config --ldflags --libs core passes support)./obfuscate main.cpp 2>&1 | tee obfuscation.logrm -rf obfuscator_pass/build/*
rm -f *.bc *.ll obfuscateThis LLVM-based obfuscator provides:
- Protection: Multiple layers of code obfuscation
- Transparency: Detailed reporting of all transformations
- Flexibility: Configurable parameters and cross-platform support
- Correctness: Maintains program functionality while adding complexity