pub struct PeFile {
pub kind: PeKind,
pub e_lfanew: u32,
pub dos: DosHeader,
pub dos_stub: Vec<u8>,
pub coff: CoffHeader,
pub optional: Option<OptionalHeader>,
pub image_base: u64,
pub address_of_entry_point: u32,
pub data_directories: Vec<DataDirectory>,
pub sections: Vec<SectionHeader>,
/* private fields */
}Expand description
A parsed PE file. The structured fields are read-only views; the
authoritative bytes live in the private raw buffer and are what
write_to_vec returns. Future iterations will replace this with
a re-derive-on-write path; for v0 the round-trip is guaranteed
trivially because we don’t mutate the buffer.
Fields§
§kind: PeKindOptional-header magic (PE32 vs PE32+).
e_lfanew: u32File offset of the PE signature (same value as
dos.e_lfanew, surfaced separately for convenience).
dos: DosHeaderParsed DOS header. The fields that don’t matter for modern PE files (the original 16-bit DOS descriptors) round through verbatim.
dos_stub: Vec<u8>The DOS stub program — bytes between the end of the DOS
header (offset 64) and e_lfanew. Treated as opaque;
the loader doesn’t execute this in 32/64-bit OS, but
most linkers ship the canonical “This program cannot be
run in DOS mode” stub. We preserve whatever bytes are
there.
coff: CoffHeaderCOFF header values.
optional: Option<OptionalHeader>Optional header values. None for object files (which
have no optional header — coff.size_of_optional_header
is 0).
image_base: u64ImageBase from the optional header — the run-time virtual
address the loader maps the file to. Section RVAs are added
to this to form full VAs at run time. Zero when the file has
no optional header (object files).
address_of_entry_point: u32AddressOfEntryPoint from the optional header — the RVA the
loader jumps to after mapping the image. For an executable
this is _start / mainCRTStartup; for a DLL this is
DllMain. Zero when the file has no optional header.
data_directories: Vec<DataDirectory>Data directories from the optional header. Index 0 is the
Export Table; index 1 the Import Table; etc. Standard PE
reserves 16 entries; we parse NumberOfRvaAndSizes of them.
sections: Vec<SectionHeader>Section header table, in declaration order.
Implementations§
Source§impl PeFile
impl PeFile
Sourcepub fn parse(bytes: &[u8]) -> Result<Self>
pub fn parse(bytes: &[u8]) -> Result<Self>
Parse a PE file. Validates the structural skeleton (DOS header, PE signature, COFF + optional + section headers) but leaves the rest as opaque bytes.
Sourcepub fn raw_bytes(&self) -> &[u8] ⓘ
pub fn raw_bytes(&self) -> &[u8] ⓘ
Raw bytes of the entire file. Stable as long as PeFile
hasn’t been mutated through a (currently nonexistent) edit
API.
Sourcepub fn section_data(&self, idx: usize) -> Option<&[u8]>
pub fn section_data(&self, idx: usize) -> Option<&[u8]>
Raw bytes of sections[idx]’s on-disk contents, or None
for an out-of-range index. Returns an empty slice when the
section’s SizeOfRawData is zero (uninitialised data, e.g.
.bss).
Sourcepub fn section_name(&self, idx: usize) -> Option<&str>
pub fn section_name(&self, idx: usize) -> Option<&str>
Resolve a section header’s “short” name as a UTF-8 string
trimmed to the first NUL. Long names (those starting with
'/' followed by a decimal offset) are returned verbatim;
the COFF string table that resolves them isn’t yet parsed.
Sourcepub fn coff_symbols(&self) -> Vec<CoffSymbol>
pub fn coff_symbols(&self) -> Vec<CoffSymbol>
Iterate the COFF symbol table, skipping aux records.
Returns an empty iterator when the file declares no symbol
table (pointer_to_symbol_table == 0 or
number_of_symbols == 0) or when the table runs past the
end of the file.
Sourcepub fn rva_to_file_offset(&self, rva: u32) -> Option<usize>
pub fn rva_to_file_offset(&self, rva: u32) -> Option<usize>
Translate an RVA to a file offset by finding the section that
contains it and computing pointer_to_raw_data + (rva - virtual_address). Returns None for RVAs outside every
section, or when the resulting offset would land past the
file’s bytes.
Sourcepub fn slice_at_rva(&self, rva: u32, len: usize) -> Option<&[u8]>
pub fn slice_at_rva(&self, rva: u32, len: usize) -> Option<&[u8]>
Read a slice of len bytes starting at the given RVA, or
None if it’s outside the file. Convenience over
rva_to_file_offset + slicing.
Sourcepub fn exports(&self) -> Vec<PeExport>
pub fn exports(&self) -> Vec<PeExport>
Parse the Export Directory (data directory 0) if it exists
and is populated, returning one PeExport per advertised
export. An empty result either means “no export table” or
“table present but lists zero functions”.
Sourcepub fn imports(&self) -> Vec<PeImport>
pub fn imports(&self) -> Vec<PeImport>
Parse the Import Directory (data directory 1) if it exists
and is populated, returning one PeImport per IAT slot
across every imported DLL. Each entry records the slot’s
run-time virtual address, the DLL the symbol comes from,
and either a name (for by-name imports) or an ordinal (for
by-ordinal imports).
Returns an empty vector when there’s no import table, or when the table is malformed (missing INT/IAT data).
Sourcepub fn from_parts(
kind: PeKind,
dos: DosHeader,
dos_stub: Vec<u8>,
coff: CoffHeader,
optional: Option<OptionalHeader>,
image_base: u64,
address_of_entry_point: u32,
data_directories: Vec<DataDirectory>,
sections: Vec<SectionHeader>,
extra_bytes: Vec<(u64, Vec<u8>)>,
file_size: u64,
) -> Self
pub fn from_parts( kind: PeKind, dos: DosHeader, dos_stub: Vec<u8>, coff: CoffHeader, optional: Option<OptionalHeader>, image_base: u64, address_of_entry_point: u32, data_directories: Vec<DataDirectory>, sections: Vec<SectionHeader>, extra_bytes: Vec<(u64, Vec<u8>)>, file_size: u64, ) -> Self
Build a PeFile from already-structured pieces, without
needing a pre-existing raw buffer. Used by the source
lower path (ud_compile::lower_to_pe) when reading the
PE skeleton from @module.build and reassembling the
bytes for round-trip. The DOS stub bytes, alignment
padding, and section content arrive via the extra_bytes
list — each (file_offset, bytes) tuple is copied into
the buffer at its offset, after the structured headers
are written.
Sourcepub fn write_to_vec(&self) -> Vec<u8> ⓘ
pub fn write_to_vec(&self) -> Vec<u8> ⓘ
Serialize back to bytes. Always byte-identical to the parsed input — the structured DOS/optional/section headers are encoded back into the buffer over a base copy of the original raw bytes, so any field not covered by a structured field (DOS stub bytes, alignment padding, section content) rides through verbatim. Useful for callers that edit a structured field (e.g. bump the optional header’s CheckSum) and want the rebuilt bytes.