balloon is a static x64 PE obfuscator aimed at thwarting signature detection and static analysis.
ballon modifies the .text section of a PE file by adding junk instruction blocks. The blocks are designed to mimic mundane instructions but are never executed. Using conditional branching^[1], the junk blocks cannot be definitively labeled as dead code.
The possible effects of ballon are:
- Failure or slower to decompile treated binaries in IDA, Binary Ninja, Ghidra, etc.
- Invalidating signature detection algorithms such as FLIRT.
- Reduced malware detections or different malware labeling.
[1]: Conditions usually look like cmp REGISTER, RANDOM 32-BIT INTEGER. Therefore, there is a non-zero chance the branch is actually not taken.
It is recommended to download a pre-built binary from the Releases page. However, one may build ballon with:
git clone https://github.com/sanglantes/balloon
cd balloon
$env:CGO_ENABLED=1
$env:CGO_CFLAGS="-I$PWD/dependencies/keystone/include"
$env:CGO_LDFLAGS="-L$PWD/dependencies/keystone/bin -lkeystone"
go build .\cmd\balloonDue to CGo dependencies, building ballon requires mingw64.
Usage of balloon.exe:
-b string
file offsets not to insert blocks in.
-c int
conditional complexity before a jmp instruction.
0: simple jmps only,
1: conditional and simple jmps,
2: conditional jmps only.
(default 2)
-d string
path to instruction database file. (default "config/ins.json")
-f string
frequency of fake instruction blocks. use x,y for a variable range. (default "5,15")
-l string
length of fake instruction blocks. use x,y for a variable range. (default "5,15")
-n string
path to executable.
-o string
path to output file.
-p only insert junk blocks inside of functions specified by .pdata. (default true)
-q use pushfq/popfq for conditional jmps instead of optimal placement heuristics. (default true)
-v verbose mode
-b: Exclude file offsets from junk code block insertions. These are absolute file offsets: not VAs, not RVAs. Example: -w 0x400,0x600:4096,9000 will exclude any junk blocks from appearing at offsets [0x400, 0x600] and [4096, 9000]. If these ranges do not belong to a code section, this option has no effect. balloon will recommend certain ranges if it detects instability in those regions.
-c: Decides how junk blocks are skipped. If 0 is picked, all blocks are prefaced with a single jmp. If 2 is picked, all blocks are prefaced with one or more conditions that will always equate to a jump over the block. If 1 is picked, it's a mix of the aforementioned options.
-d: Path to a JSON file containing the blueprint for all junk instructions. One is already provided with balloon, but it is extendable.
-f: Amount of junk code blocks per instruction. This number/range is not treated strictly, and it is possible for junk code blocks to appear less frequently.
-l: Number of junk instructions per code block (excluding jumps and conditionals). This number/range is not treated strictly, and it is possible for junk instructions blocks to be larger.
-n: Path to PE file to be treated. Must be an AMD64 image.
-o: Path to output file.
-p: If this option is given (-p=true), balloon will only insert fake code blocks into sections defined by the PE exception table. This option increases stability by a lot.
-q: If this option is given (-q=true), all conditionals will be prefaced with a pushfq and suffixed with a popq instruction to ensure that RFLAGS are reset. This makes the code blocks easier to detect, but it is safer. Generally, it is safe to provide q=false.
Original decompilation of a dynamically linked isprime binary.
Obfuscated code using the options -f 1,3 -l 20,30 -q=true -c=2 -p=true
A C2 server written in Nim. The client was obfuscated with: -f 30 -l 10,15 -q=false -c=2 -p=true. The VirusTotal results for the original binary were 26/68. The obfuscated binary hit 15/69.
Binary rewriting can easily destabilize a program. As program complexity grows, so does the risk of balloon corrupting the binary. Proceed with caution if the application uses a GUI.
Managed code as well as programs written in Go are not supported.
If you are experiencing corruptions or unexpected behaviour from a file treated by balloon, please raise an issue. If possible, provide a minimal reproducible example and as much information as possible about the original binary.
Note
In the issue message body, provide a download link to the untreated binary. Make sure it is in a ZIP/RAR archive with the password infected.
- Treatment for all Data Directory entries.
- Increased modularity/plugin system.
Powered by: