pub trait BinaryFormat: Send + Sync {
Show 23 methods
// Required methods
fn load_address(&self) -> u64;
fn byte_at(&self, addr: u64) -> Option<u8>;
fn bytes_at(&self, addr: u64) -> Option<&[u8]>;
fn entry_points(&self) -> Vec<u64>;
fn architecture(&self) -> Arch;
// Provided methods
fn entrypoint(&self) -> Option<u64> { ... }
fn os(&self) -> TargetOs { ... }
fn linked_libraries(&self) -> Vec<String> { ... }
fn symbol_name(&self, _addr: u64) -> Option<&str> { ... }
fn is_external_symbol(&self, _addr: u64) -> bool { ... }
fn import_library(&self, _addr: u64) -> Option<&str> { ... }
fn import_symbol_name(&self, _addr: u64) -> Option<&str> { ... }
fn hex_rows(
&self,
addr: u64,
len: usize,
width: usize,
) -> Vec<(u64, Vec<Option<u8>>)> { ... }
fn contains(&self, addr: u64) -> bool { ... }
fn mapped_regions(&self) -> Vec<(u64, Vec<u8>, bool, bool)> { ... }
fn is_executable(&self, addr: u64) -> bool { ... }
fn segment_bounds(&self, _addr: u64) -> Option<(u64, u64)> { ... }
fn is_known_writable(&self, _addr: u64) -> bool { ... }
fn is_known_read_only(&self, _addr: u64) -> bool { ... }
fn read_bytes(&self, addr: u64, n: usize) -> Option<Vec<u8>> { ... }
fn read_uint(&self, addr: u64, size: usize) -> Option<u64> { ... }
fn read_cstring(&self, addr: u64, max_len: Option<usize>) -> Option<Vec<u8>> { ... }
fn read_printable_cstring(
&self,
addr: u64,
max_len: Option<usize>,
) -> Option<Vec<u8>> { ... }
}Expand description
A trait representing a loaded binary image with one or more mapped regions and one or more known entry points.
Both blob::Blob (raw bytes) and elf::ElfBinary implement this trait
so that arch disassemblers can accept either format through a single
interface, even when the backing image is sparse.
Impls are immutable after parse, so the trait carries Send + Sync bounds:
a parsed binary is shared by reference (Arc<dyn BinaryFormat>) across the
analysis pipeline’s worker threads.
Required Methods§
Sourcefn load_address(&self) -> u64
fn load_address(&self) -> u64
The lowest virtual address mapped by this binary image.
Sourcefn byte_at(&self, addr: u64) -> Option<u8>
fn byte_at(&self, addr: u64) -> Option<u8>
Return the byte mapped at addr, or None if the address is unmapped.
Sourcefn bytes_at(&self, addr: u64) -> Option<&[u8]>
fn bytes_at(&self, addr: u64) -> Option<&[u8]>
Return the contiguous bytes available at addr.
The returned slice covers the current mapped region from addr onward.
Implementations may return an owned buffer when the region is backed by
implicit zero-fill rather than file bytes.
Sourcefn entry_points(&self) -> Vec<u64>
fn entry_points(&self) -> Vec<u64>
Known entry points into this binary (entrypoint, symbol table functions, etc.). The recursive disassembler should be seeded with these addresses.
Sourcefn architecture(&self) -> Arch
fn architecture(&self) -> Arch
Name of the architecture, should use embedded information from known binary format, or raw values from the blob.
Provided Methods§
Sourcefn entrypoint(&self) -> Option<u64>
fn entrypoint(&self) -> Option<u64>
The binary’s primary entry point (e.g. the ELF e_entry), if the format
designates one. Unlike entry_points, this is the single address where
execution begins. Returns None for formats with no distinguished entry.
Sourcefn os(&self) -> TargetOs
fn os(&self) -> TargetOs
The operating system this binary targets, inferred from the container
format. Defaults to TargetOs::Unknown; PE returns Windows, ELF Linux.
Sourcefn linked_libraries(&self) -> Vec<String>
fn linked_libraries(&self) -> Vec<String>
Library names this binary links against: ELF DT_NEEDED sonames,
PE import-directory DLL names (original case; matching is
case-insensitive). Empty when the format has no such notion (Blob).
Sourcefn symbol_name(&self, _addr: u64) -> Option<&str>
fn symbol_name(&self, _addr: u64) -> Option<&str>
Return the symbol name for the function starting at addr, if the
binary format has one (e.g. from an ELF symbol table).
Returns None for formats with no symbol information.
Sourcefn is_external_symbol(&self, _addr: u64) -> bool
fn is_external_symbol(&self, _addr: u64) -> bool
Returns true if addr is an external (imported) function stub,
e.g. a PLT thunk. The recursive disassembler will not lift the body
of external functions. Defaults to false.
Sourcefn import_library(&self, _addr: u64) -> Option<&str>
fn import_library(&self, _addr: u64) -> Option<&str>
Return the name of the library providing the external function stub at
addr: the PE import-directory DLL, or the ELF .gnu.version_r soname
the symbol’s version requirement points at. None when the format does
not record a per-symbol source library (e.g. an unversioned ELF import).
Sourcefn import_symbol_name(&self, _addr: u64) -> Option<&str>
fn import_symbol_name(&self, _addr: u64) -> Option<&str>
Return the imported symbol whose resolver slot lives at addr, if any.
ELF uses this for GOT / PLT relocation slots such as R_X86_64_GLOB_DAT
and R_X86_64_JUMP_SLOT.
Sourcefn hex_rows(
&self,
addr: u64,
len: usize,
width: usize,
) -> Vec<(u64, Vec<Option<u8>>)>
fn hex_rows( &self, addr: u64, len: usize, width: usize, ) -> Vec<(u64, Vec<Option<u8>>)>
Return rows of bytes suitable for a hex viewer.
The first row is aligned down to the nearest width-byte boundary.
Each row is (row_address, bytes) where a byte is None when the
address is unmapped (e.g. a hole in a sparse ELF image).
§Panics
Panics if width is zero.
Sourcefn mapped_regions(&self) -> Vec<(u64, Vec<u8>, bool, bool)>
fn mapped_regions(&self) -> Vec<(u64, Vec<u8>, bool, bool)>
Enumerate the binary’s mapped regions as
(start, bytes, executable, writable).
At snapshot-save time the persistence layer copies these into a
serializable MemoryImage so a reloaded session is self-describing.
Each region’s bytes should cover its full in-memory size (zero-filled
tail included), mirroring byte_at.
Defaults to empty for formats that do not expose their segments.
Sourcefn is_executable(&self, addr: u64) -> bool
fn is_executable(&self, addr: u64) -> bool
Return true if addr lies in an executable region of this binary
image. Defaults to “mapped” for formats that don’t track per-region
permissions; formats with permission information (e.g. ELF segment
flags) should override this.
Sourcefn segment_bounds(&self, _addr: u64) -> Option<(u64, u64)>
fn segment_bounds(&self, _addr: u64) -> Option<(u64, u64)>
The [start, end) bounds of the mapped region containing addr, if
any. Used to key per-segment facts (e.g. executability propositions)
so repeated queries in one region collapse to a single entry. Defaults
to None for formats that do not expose their segments.
Sourcefn is_known_writable(&self, _addr: u64) -> bool
fn is_known_writable(&self, _addr: u64) -> bool
Return true only if addr lies in a region known to be writable
(from the container’s segment flags). Passes that fold a value out of
initialized memory use this to refuse mutable memory — e.g. a GOT slot
the dynamic linker overwrites at load time. Defaults to false
(“not proven writable”); Blob keeps the default.
Sourcefn is_known_read_only(&self, _addr: u64) -> bool
fn is_known_read_only(&self, _addr: u64) -> bool
Return true only if addr lies in a region proven read-only (mapped,
and the container’s own permission data says the region is not writable).
This is not the negation of [is_known_writable]: a format that
records no permissions answers false to both, which reads as “unknown”
rather than “read-only”. Consumers that reconstruct a value out of
initialized memory — the decompiler rendering a .rodata string constant
as a named object — need the positive proof, because a writable byte may
be a different byte at run time.
Defaults to false (“not proven read-only”); Blob and PeBinary keep
the default, the latter because it does not parse section permissions.
Sourcefn read_bytes(&self, addr: u64, n: usize) -> Option<Vec<u8>>
fn read_bytes(&self, addr: u64, n: usize) -> Option<Vec<u8>>
Read n bytes at virtual address addr.
Returns None if any byte in the requested range is unmapped.
Sourcefn read_uint(&self, addr: u64, size: usize) -> Option<u64>
fn read_uint(&self, addr: u64, size: usize) -> Option<u64>
Read a little-endian unsigned integer of size bytes (1..=8) at addr.
Returns None if the size is out of range or any byte is unmapped.
Sourcefn read_cstring(&self, addr: u64, max_len: Option<usize>) -> Option<Vec<u8>>
fn read_cstring(&self, addr: u64, max_len: Option<usize>) -> Option<Vec<u8>>
Read a null-terminated C string at virtual address addr, returning the
bytes up to (but not including) the null terminator.
If max_len is Some(limit), only the first limit bytes are searched
for the null terminator. Returns None if the address is out of range or
no null terminator is found within the (optionally limited) region.
Sourcefn read_printable_cstring(
&self,
addr: u64,
max_len: Option<usize>,
) -> Option<Vec<u8>>
fn read_printable_cstring( &self, addr: u64, max_len: Option<usize>, ) -> Option<Vec<u8>>
Read a null-terminated C string at virtual address addr, requiring
every byte before the null terminator to be printable ASCII.
Printable bytes are in the inclusive range 0x20..=0x7e. Returns
None if the address is out of range, no null terminator is found
within the optional search window, or a non-printable byte appears
before the terminator.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".