Code virtualizer for compiled 64-bit portable executables.
- Disassembly: input is parsed with exe, and the section containing the entry point is disassembled into basic blocks via iced-x86.
- Mutation: instructions are substituted with algebraically equivalent sequences using dead-flag analysis to preserve correctness.
- Lifting: instructions are translated into a stack-machine bytecode the runtime interprets.
- Permutation: operations are reordered through their logical dependencies into a semantically equivalent sequence.
- Scrambling: operations are placed in a randomized physical layout connected by inserted jumps that follow their original execution order.
- Mutation: operations are rewritten into logically equivalent forms whose structure varies between builds.
- Encryption: immediate values in the bytecode are masked against a rolling key whose state advances between every immediate.
- Chaining: each block's decryption is seeded by the tail state of the previous block.
- Patching: virtualized blocks are replaced with dispatch stubs that transfer control to the VM.
- TLS: VM state lives in Thread Local Storage, so each thread runs the interpreter against its own registers and stacks.
- Dispatch: a stub transfers CPU state to the VM, which interprets the corresponding bytecode through indirect dispatch to handler functions.
- Exceptions: a vectored exception handler catches faults inside the VM region and reconstructs the CPU context for external handlers.
- Attestation: a leading sequence of VM-blocks runs anti-debug and integrity checks whose results feed into the decryption chain.
The tests crate spins up a frankenstein version of the VM, minimally instrumented to allow it to run for testing.
- Instructions: instruction is executed through the VM and the resulting context is compared against the CPU.
- Permutation: instruction sequence's dependency graph is exhaustively executed through the VM and verified.
cargo run --release --bin obfuscator -- <filename> --virtualization --attestation --mutation
- Fork it
- Create your branch (
git checkout -b my-change) - Commit your changes (
git commit -m "changed something") - Push to the branch (
git push origin my-change) - Create new pull request