caver
ELF64 code cave injection library for Rust.
caver creates executable code caves in ELF64 binaries by appending a new loadable segment. This is useful when a binary has little or no natural slack space for patching or instrumentation.
The injected cave is exported as a symbol, allowing reverse-engineering tools such as Binary Ninja, Ghidra, and IDA Pro to automatically detect it.
The library focuses only on structural ELF modification (creating space for new code). Assembly payloads, hooks, and patching are intended to be written inside a disassembler after injection.
Goals
caver is intentionally small in scope. It aims to:
- Create executable code caves in binaries that lack natural slack space
- Append a new executable
PT_LOADsegment safely - Expose the cave as a symbol for easy discovery in disassemblers
- Provide utilities for inspecting ELF layout and locating existing caves
It does not attempt to:
- assemble payloads
- generate trampolines
- automatically hook functions
- patch instructions
These tasks are better handled inside reverse-engineering tools.
Supported Architectures
- x86_64
- AArch64
- RISC-V 64
All architectures require ELF64 little-endian binaries.
Install
[]
= "0.2"
Usage
Inject caves
name is the ELF section name and must start with .. symbol is the exported
symbol name visible in disassemblers — if not set, caver derives one automatically
from the section name.
use ;
use ElfFile;
Inspect an existing binary
use ElfFile;
Cave Symbols
The exported symbol name is derived automatically from the section name and fill pattern:
| Fill | Auto symbol | Disassembler treatment |
|---|---|---|
FillByte::ArchNop |
caverfn_<name> |
function entry point |
FillByte::Zero |
caverobj_<name> |
data variable |
For example, injecting .mycode with FillByte::ArchNop produces caverfn_mycode, which most disassemblers will automatically treat as a function. Injecting .mydata with FillByte::Zero produces caverobj_mydata, treated as a data variable.
Use .symbol("my_name") in the builder to override the auto-generated name entirely.
Note that name and symbol serve different purposes — name is the internal ELF section name used to identify the cave structurally, while symbol is the exported name visible to disassemblers and tooling.
Finding Natural Caves
The find_caves function scans the binary for runs of 0x00 or 0x90 bytes that meet a minimum size threshold. Results are sorted largest first. This is useful for locating existing slack space before deciding whether to inject a new segment at all.
License
MIT