HowTo :: Patching binary files in Linux
Introduction
Learn to patch binary files directly without source code using hex editing and binary diff tools; essential for fixing bugs, applying security patches, or modifying executables.
What is Binary Patching?
Binary patching is the process of modifying compiled executable files without access to their source code. This technique is useful for:
- Fixing bugs in production binaries when recompilation isn’t possible
- Applying security patches to legacy systems
- Reverse engineering and understanding how programs work
- CTF challenges and vulnerability research
- Modifying behavior of closed-source applications
- Creating binary diffs for distributing patches
Instead of editing high-level source code and recompiling, you directly modify the machine code bytes in the executable file. This requires understanding hexadecimal representation and executable file formats.
What You’ll Need
Before patching binaries, ensure you have:
- xxd - Hex dump tool (included in most Linux distributions with vim-common)
- diff - Text comparison tool (standard on all Linux systems)
- bsdiff - Binary diff/patch tool (install separately:
apt install bsdiff) - Backup copies of any files you plan to modify
- Basic hex knowledge - Understanding hexadecimal representation (0x00-0xFF)
Method 1: Using xxd (Hex Editing)
The xxd command creates hexadecimal representations of binary files that you can edit with text editors, then convert back to binary.
Step 1: Convert Binary to Hex
First, create hex dumps of the binary files you want to work with:
| |
This converts prog1.bin into a human-readable hexadecimal format saved in b1.hex.
Example output format:
| |
Each line shows:
- Byte offset (left): Position in the file
- Hex values (middle): The actual bytes in hexadecimal
- ASCII representation (right): Printable characters (dots for non-printable)
. represents non-printable characters.Step 2: Edit the Hex File
Now you can edit b1.hex with any text editor. Modify the hex values in the middle columns:
| |
Example modification: Change instruction opcodes, string values, or jump addresses by editing the hex bytes.
Only modify the hex values in the middle columns. Don’t change:
- The byte offsets (left column)
- The line structure or spacing
- The ASCII representation (right column) - it’s auto-generated
Even a small mistake can corrupt the binary and make it unexecutable.
Step 3: Convert Hex Back to Binary
After editing, convert the hex file back to a binary:
| |
The -r flag tells xxd to reverse the conversion (hex to binary).
Step 4: Compare Binaries Using Hex Diffs
To see what changed between two versions, create hex dumps of both and compare:
| |
Or use vimdiff for visual comparison:
| |
This shows exactly which bytes changed, making it easy to document or reverse your modifications.
For a more concise binary comparison, you can also use:
| |
This shows byte positions and values that differ between the two files.
Method 2: Using bsdiff (Binary Patches)
The bsdiff tool creates and applies binary patch files, useful for distributing modifications without sharing entire binaries.
Step 1: Install bsdiff
If not already installed:
| |
Step 2: Create a Binary Patch
Generate a patch file from an old and new version of a binary:
| |
This creates patch.bin, which contains only the differences between the two files; much smaller than distributing the entire new binary.
What this does:
- Analyzes differences between
old_prog.binandnew_prog.bin - Creates compressed patch file containing only changed bytes
- Patch file can be distributed separately from the full binary
Step 3: Apply a Binary Patch
To apply a patch file to the original binary:
| |
This applies the modifications from patch.bin to old_prog.bin, creating output.bin which matches new_prog.bin.
Use cases:
- Distributing security fixes without sharing entire executables
- Applying community patches to games or applications
- Version control for binary files
- Minimizing download sizes for updates
Step 4: Verify the Result
Always verify the patched binary matches expectations:
| |
Practical Example: Patching a Simple Binary
Here’s a complete workflow for patching a binary to change a string:
| |
Troubleshooting
Issue: Patched binary crashes or doesn’t execute Solution:
- Verify hex file wasn’t corrupted during editing
- Check that you didn’t modify file offsets or structure
- Ensure executable permissions:
chmod +x patched.bin - Compare with original to identify unexpected changes
Issue: bspatch fails with “corrupt patch” Solution:
- Ensure the patch file wasn’t corrupted during transfer
- Verify you’re using the correct original binary version
- Check file permissions on all involved files
Issue: String replacement causes crashes Solution:
- Replacement strings must be same length or shorter
- Pad with null bytes (00) if shorter
- Check for null terminators (00) at end of strings
Issue: Changes don’t seem to take effect Solution:
- Clear any cached versions:
rm -f cached_version - Verify you’re running the patched binary, not original
- Check if binary has anti-tampering or signature verification
Best Practices
- Always backup original files before patching
- Document changes you make for future reference
- Test thoroughly after applying patches
- Use version control for patch files themselves
- Verify checksums after applying patches
- Keep patch files small by only modifying necessary bytes
- Consider legal implications before modifying binaries
Next Steps
Now that you understand binary patching:
- Learn assembly: Read Linux Syscalls in Assembly to understand what you’re modifying
- Master GDB: Use GDB to inspect binaries and find patch locations
- Study ELF format: Learn about executable file structure to patch safely
- Practice with CTFs: Capture The Flag challenges often require binary patching skills
For more sophisticated binary modification:
- radare2 - Reverse engineering framework with patching capabilities
- Binary Ninja - Commercial binary analysis platform
- Ghidra - NSA’s free reverse engineering tool
- objcopy - GNU tool for modifying object files
See Also
- Getting Started with GDB - Debug and inspect binaries to find patch locations
- Linux Syscalls in Assembly - Understand low-level program execution
- GCC Compiling Cheat Sheet - Learn about compilation and linking
- xxd Manual - Complete xxd documentation
- bsdiff Documentation - Official bsdiff documentation