{"record":{"id":"b11425cedcc44834","repo":"t8y2/dbx","slug":"missing-pe-signature","errorCode":null,"errorMessage":"missing PE signature","messagePattern":"missing PE signature","errorType":"exception","errorClass":"PeFormatError","httpStatus":null,"severity":"error","filePath":"agents/scripts/validate_windows_pe_dependencies.py","lineNumber":43,"sourceCode":"    if offset < 0 or offset >= len(data):\n        raise PeFormatError(\"PE string offset is outside the file\")\n    end = data.find(b\"\\0\", offset)\n    if end < 0:\n        raise PeFormatError(\"unterminated PE string\")\n    try:\n        return data[offset:end].decode(\"ascii\")\n    except UnicodeDecodeError as error:\n        raise PeFormatError(\"PE import name is not ASCII\") from error\n\n\ndef imported_dlls(path: Path) -> list[str]:\n    data = path.read_bytes()\n    if len(data) < 64 or data[:2] != b\"MZ\":\n        raise PeFormatError(\"missing DOS header\")\n\n    pe_offset = _read_u32(data, 0x3C)\n    if data[pe_offset : pe_offset + 4] != b\"PE\\0\\0\":\n        raise PeFormatError(\"missing PE signature\")\n\n    section_count = _read_u16(data, pe_offset + 6)\n    optional_header_size = _read_u16(data, pe_offset + 20)\n    optional_header_offset = pe_offset + 24\n    optional_magic = _read_u16(data, optional_header_offset)\n    if optional_magic == 0x20B:\n        data_directories_offset = optional_header_offset + 112\n    elif optional_magic == 0x10B:\n        data_directories_offset = optional_header_offset + 96\n    else:\n        raise PeFormatError(f\"unsupported PE optional header magic: 0x{optional_magic:04x}\")\n\n    import_directory_rva = _read_u32(data, data_directories_offset + 8)\n    import_directory_size = _read_u32(data, data_directories_offset + 12)\n    if import_directory_rva == 0 or import_directory_size == 0:\n        return []\n\n    size_of_headers = _read_u32(data, optional_header_offset + 60)","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/scripts/validate_windows_pe_dependencies.py#L25-L61","documentation":"PeFormatError raised by imported_dlls when the 4-byte signature at the offset stored in the DOS header (epe_offset, read from 0x3C) is not b\"PE\\0\\0\". The file has a valid MZ stub but the DOS-header e_lfanew pointer does not lead to a PE signature, so it is not a parseable Windows PE (it may be an old DOS executable or a corrupted/patched file).","triggerScenarios":"imported_dlls(path) reads _read_u32(data, 0x3C) and slices data[pe_offset:pe_offset+4] on a classic MS-DOS executable, a file whose e_lfanew was overwritten, a PE whose stub was modified by packers/protectors, or a text file that merely starts with 'MZ'.","commonSituations":"Validating genuine DOS-era .exe/.com files that lack a PE header, binaries mangled by a hex edit or bad patch, files processed by tools that rewrote e_lfanew incorrectly, or scripts that fabricate an MZ header without updating the PE pointer.","solutions":["Confirm the file is a real PE with `file binary.exe` — output should say 'PE32'/'PE32+', not 'MS-DOS executable'.","Rebuild or re-obtain the binary; a broken e_lfanew usually means corruption or an incomplete build/pack step.","If the file is intentionally DOS-only, exclude it from Windows PE dependency validation.","Catch PeFormatError and fail gracefully in CI with a clear 'missing PE signature' message."],"exampleFix":"// before\nresult = subprocess.run([\"python\", \"validate_windows_pe_dependencies.py\", binary])\n// after\nresult = subprocess.run([\"python\", \"validate_windows_pe_dependencies.py\", binary])\nif \"missing PE signature\" in result.stderr:\n    raise SystemExit(f\"{binary} is not a valid Windows PE (bad e_lfanew)\")","handlingStrategy":"validation","validationCode":"import struct\ndata = path.read_bytes()\nif len(data) >= 64 and data[:2] == b\"MZ\":\n    pe_offset = struct.unpack_from(\"<I\", data, 0x3C)[0]\n    if data[pe_offset:pe_offset + 4] != b\"PE\\0\\0\":\n        raise SystemExit(f\"{path}: DOS header present but no PE signature (e_lfanew=0x{pe_offset:x})\")","typeGuard":"def has_pe_signature(data: bytes) -> bool:\n    if len(data) < 64 or data[:2] != b\"MZ\":\n        return False\n    pe_offset = int.from_bytes(data[0x3C:0x40], \"little\")\n    return pe_offset + 4 <= len(data) and data[pe_offset:pe_offset + 4] == b\"PE\\0\\0\"","tryCatchPattern":"try:\n    imports = imported_dlls(path)\nexcept PeFormatError as error:\n    if \"missing PE signature\" in str(error):\n        print(f\"{path} is a DOS executable or corrupt PE; skipping\")\n    else:\n        raise","preventionTips":["Run `file` on artifacts and require PE32/PE32+ output in CI gating","Never hand-patch e_lfanew; regenerate the binary instead","Exclude genuine DOS-era executables from PE import validation by design","Use pefile.PE() as a pre-flight parser to catch header corruption with better diagnostics"],"tags":["pe","file-format","dos-header","corrupt-file"],"backgroundTag":"not-a-pe-file","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}