t8y2/dbx · error · PeFormatError

PE RVA 0x{rva:x} is not backed by file data

Error message

PE RVA 0x{rva:x} is not backed by file data

What it means

The parser converts a relative virtual address (RVA) from the PE headers to a file offset using the section table. This error means the requested RVA (here the import directory RVA, or a DLL-name RVA via the nested rva_to_offset) does not fall inside any section's mapped range, or falls past a section's raw data on disk. The library throws it because the bytes the RVA points to are simply not present in the file, so the import table cannot be read safely.

Source

Thrown at agents/scripts/validate_windows_pe_dependencies.py:85

            (
                _read_u32(data, section_offset + 12),
                _read_u32(data, section_offset + 8),
                _read_u32(data, section_offset + 20),
                _read_u32(data, section_offset + 16),
            )
        )

    def rva_to_offset(rva: int) -> int:
        if rva < size_of_headers:
            return rva
        for virtual_address, virtual_size, raw_offset, raw_size in sections:
            span = max(virtual_size, raw_size)
            if virtual_address <= rva < virtual_address + span:
                delta = rva - virtual_address
                if delta >= raw_size:
                    break
                return raw_offset + delta
        raise PeFormatError(f"PE RVA 0x{rva:x} is not backed by file data")

    descriptor_offset = rva_to_offset(import_directory_rva)
    imports = []
    for _ in range(4096):
        if descriptor_offset + 20 > len(data):
            raise PeFormatError("truncated PE import descriptor")
        descriptor = data[descriptor_offset : descriptor_offset + 20]
        if descriptor == b"\0" * 20:
            return sorted(set(imports), key=str.casefold)
        name_rva = _read_u32(data, descriptor_offset + 12)
        if name_rva == 0:
            raise PeFormatError("PE import descriptor has no DLL name")
        imports.append(_read_c_string(data, rva_to_offset(name_rva)))
        descriptor_offset += 20

    raise PeFormatError("PE import descriptor table is not terminated")

View on GitHub (pinned to c0390bff16)

Solutions

  1. Inspect the PE's section table (e.g. with pefile or dumpbin /headers) and confirm the import directory RVA lies within a mapped section with raw data present.
  2. Rebuild or re-download the binary; an RVA not backed by file data usually indicates corruption or a deliberately malformed file.
  3. If the binary is packed and its import directory legitimately points into unpacked-in-memory regions, analyze the unpacked image instead.
  4. Catch PeFormatError around imported_dlls and treat the file as 'unverifiable' rather than letting the validator crash.

Example fix

// before
imports = imported_dlls(Path(binary_path))
// after
try:
    imports = imported_dlls(Path(binary_path))
except PeFormatError as err:
    raise RuntimeError(f"{binary_path}: cannot resolve PE RVAs: {err}") from err
Defensive patterns

Strategy: try-catch

Validate before calling

import pefile

def rvas_are_backed(path) -> bool:
    pe = pefile.PE(path)
    rva = pe.OPTIONAL_HEADER.DATA_DIRECTORY[1].VirtualAddress
    if rva == 0:
        return True
    return pe.get_offset_from_rva(rva) is not None

Type guard

def rva_in_section(rva: int, sections: list[tuple[int, int, int, int]], size_of_headers: int) -> bool:
    return rva < size_of_headers or any(
        va <= rva < va + max(vs, rs) for va, vs, _, rs in sections
    )

Try / catch

try:
    imports = imported_dlls(path)
except PeFormatError as err:
    if "not backed by file data" in str(err):
        handle_unverifiable(path, err)
    else:
        raise

Prevention

When it happens

Trigger: imported_dlls(path) on a PE whose import directory RVA (data directory index 1) points outside all sections; a DLL-name RVA inside a section's virtual span but beyond its raw size; headers whose SizeOfHeaders/section VirtualAddress or PointerToRawData fields were corrupted or zeroed.

Common situations: Analyzing packed/obfuscated binaries that fake their section table; malformed PE samples from malware corpora or fuzzers; binaries damaged by incomplete download or bad packaging; using the tool on non-image PE variants (object files) where RVAs are meaningless.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/d45b803f3518c605. Report an issue: GitHub.