Skip to content
sanglantesPublic

About

Static PE writer & binary obfuscator.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

100 Commits

Folders and files

Repository files navigation

balloon icon

balloon

balloon is a static x64 PE obfuscator aimed at thwarting signature detection and static analysis.

Description

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.

Installation

It is recommended to download a pre-built binary from the Releases page. However, one may build ballon with:

PowerShell

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\balloon

Due to CGo dependencies, building ballon requires mingw64.

Usage

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.

Showcase

isprime C binary

Original decompilation of a dynamically linked isprime binary.

Demo: original main decompilation Demo: original isprime decompilation

Obfuscated code using the options -f 1,3 -l 20,30 -q=true -c=2 -p=true Demo: obfuscated main decompilation Demo: obfuscated isprime decompilation

Nimbo C2

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.

Original VT Obfuscated VT

Limitations

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.

Raising an issue

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.

Future plans

  • Treatment for all Data Directory entries.
  • Increased modularity/plugin system.

Credits

Powered by:

About

Static PE writer & binary obfuscator.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages