t8y2/dbx · error · PeFormatError
unterminated PE string
Error message
unterminated PE string
What it means
PeFormatError raised by _read_c_string when data.find(b"\0", offset) returns -1, meaning there is no NUL terminator between the given offset and end-of-file. The library throws it because an import DLL name is required to be a NUL-terminated ASCII string; running off the end indicates a corrupt import table or a bad RVA-to-offset mapping.
Source
Thrown at agents/scripts/validate_windows_pe_dependencies.py:29
def _read_u16(data: bytes, offset: int) -> int:
if offset < 0 or offset + 2 > len(data):
raise PeFormatError("unexpected end of PE file")
return struct.unpack_from("<H", data, offset)[0]
def _read_u32(data: bytes, offset: int) -> int:
if offset < 0 or offset + 4 > len(data):
raise PeFormatError("unexpected end of PE file")
return struct.unpack_from("<I", data, offset)[0]
def _read_c_string(data: bytes, offset: int) -> str:
if offset < 0 or offset >= len(data):
raise PeFormatError("PE string offset is outside the file")
end = data.find(b"\0", offset)
if end < 0:
raise PeFormatError("unterminated PE string")
try:
return data[offset:end].decode("ascii")
except UnicodeDecodeError as error:
raise PeFormatError("PE import name is not ASCII") from error
def imported_dlls(path: Path) -> list[str]:
data = path.read_bytes()
if len(data) < 64 or data[:2] != b"MZ":
raise PeFormatError("missing DOS header")
pe_offset = _read_u32(data, 0x3C)
if data[pe_offset : pe_offset + 4] != b"PE\0\0":
raise PeFormatError("missing PE signature")
section_count = _read_u16(data, pe_offset + 6)
optional_header_size = _read_u16(data, pe_offset + 20)
optional_header_offset = pe_offset + 24View on GitHub (pinned to c0390bff16)
Solutions
- Re-download / rebuild the binary; a missing terminator usually means the file is truncated at the end.
- Check the file size against the size implied by the last section's PointerToRawData + SizeOfRawData; if smaller, the copy is incomplete.
- Catch PeFormatError and skip/fail the file in batch-validation pipelines instead of crashing.
- If you produce PE files yourself, ensure every import-name string is NUL-terminated and covered by a mapped section.
Example fix
// before
for path in paths:
imports[path] = imported_dlls(path) # aborts whole batch
// after
for path in paths:
try:
imports[path] = imported_dlls(path)
except PeFormatError as error:
print(f"skipping {path}: {error}") Defensive patterns
Strategy: try-catch
Validate before calling
data = path.read_bytes()
if len(data) < 64 or data[:2] != b"MZ":
raise SystemExit("not a PE")
if data.rstrip(b"\0")[-1:] not in (b"\0", b"") and len(data) < 0x400:
print("warning: file looks truncated") Type guard
def looks_truncated(path: Path, expected_min: int) -> bool:
return path.stat().st_size < expected_min Try / catch
try:
imports = imported_dlls(path)
except PeFormatError as error:
if "unterminated" in str(error) or "outside the file" in str(error):
print(f"{path}: corrupt/truncated PE: {error}")
else:
raise Prevention
- Verify download integrity (hash/size) before validating binaries
- Ensure build pipelines fully flush and close output files
- Reject files smaller than their last section's raw extent
- In batch jobs, catch PeFormatError per file instead of aborting the run
When it happens
Trigger: imported_dlls() calls _read_c_string(data, rva_to_offset(name_rva)) and the resolved offset points at bytes that continue to EOF without a \0 — e.g. name_rva maps into the very tail of the file, or the last section's raw data was truncated mid-string.
Common situations: Parsing truncated downloads or incomplete writes of PE files, files whose final section was cut during packing/unpacking, deliberately corrupted malware samples, or concatenation errors where a PE was appended to another file and the tail is missing.
Related errors
- PE string offset is outside the file
- PE import name is not ASCII
- unexpected end of PE file
- missing DOS header
- missing PE signature
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/f85726da409d58ac.
Report an issue: GitHub.