{"record":{"id":"95e0f4b657fa1b86","repo":"QL-Win/QuickLook","slug":"coff-header-not-found","errorCode":null,"errorMessage":"COFF header not found.","messagePattern":"COFF header not found\\.","errorType":"exception","errorClass":"PEImageParseException","httpStatus":null,"severity":"error","filePath":"QuickLook.Plugin/QuickLook.Plugin.PEViewer/PEImageParser/PEImage.cs","lineNumber":97,"sourceCode":"            Reserved6 = reader.ReadUInt16(),\n            Reserved7 = reader.ReadUInt16(),\n            Reserved8 = reader.ReadUInt16(),\n            Reserved9 = reader.ReadUInt16(),\n            Reserved10 = reader.ReadUInt16(),\n            Reserved11 = reader.ReadUInt16(),\n            Reserved12 = reader.ReadUInt16(),\n            Reserved13 = reader.ReadUInt16(),\n            Reserved14 = reader.ReadUInt16(),\n            PEHeaderOffset = reader.ReadUInt32()\n        };\n\n        // DOS Stub\n        if (reader.BaseStream.Length < DosHeader.PEHeaderOffset) throw new PEImageParseException((int)reader.BaseStream.Position, \"DOS stub incomplete.\");\n\n        DosStub = reader.ReadBytes((int)(DosHeader.PEHeaderOffset - reader.BaseStream.Position));\n\n        // COFF Header\n        if (reader.ReadUInt32() != 0x4550) throw new PEImageParseException((int)reader.BaseStream.Position - 4, \"COFF header not found.\");\n        if (reader.BaseStream.Length - reader.BaseStream.Position < 20) throw new PEImageParseException((int)reader.BaseStream.Position, \"COFF header incomplete.\");\n\n        CoffHeader = new()\n        {\n            Machine = (ImageMachineType)reader.ReadUInt16(),\n            NumberOfSections = reader.ReadUInt16(),\n            TimeDateStamp = reader.ReadUInt32(),\n            PointerToSymbolTable = reader.ReadUInt32(),\n            NumberOfSymbols = reader.ReadUInt32(),\n            SizeOfOptionalHeader = reader.ReadUInt16(),\n            Characteristics = (ImageCharacteristics)reader.ReadUInt16()\n        };\n\n        // Optional Header\n        if (reader.BaseStream.Length - reader.BaseStream.Position < 2) throw new PEImageParseException((int)reader.BaseStream.Position, \"Optional header not found.\");\n        ushort magic = reader.ReadUInt16();\n\n        if (magic == 0x10b)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/QL-Win/QuickLook/blob/cb5d9c429c81d9796fac469da2a68efb5626946d/QuickLook.Plugin/QuickLook.Plugin.PEViewer/PEImageParser/PEImage.cs#L79-L115","documentation":"The parser reads the 4-byte PE signature at the file offset stored in the DOS header's PEHeaderOffset field (e_lfanew). Per the PE/COFF specification this signature must be 0x4550 (ASCII \"PE\\0\\0\"). If the 4 bytes at that offset do not match, the file is not a valid Win32 PE image and parsing aborts. The Offset property of the exception points 4 bytes before the current read position (the start of the signature).","triggerScenarios":"Calling PEImage.FromFile(path) or PEImage.FromBinary(bytes) on a file whose first two bytes are \"MZ\" (0x5A4D) and whose e_lfanew field correctly points to a location, but the 4 bytes at that location are not 0x4550. Common with legacy 16-bit DOS executables that have no PE header, or with files that only coincidentally start with \"MZ\".","commonSituations":"Passing an old DOS .exe that predates the PE format; passing a non-executable file that happens to start with \"MZ\"; a partially downloaded or corrupted binary where the e_lfanew pointer or the bytes at that offset were damaged; feeding an object file (.obj) or archive that has no PE signature.","solutions":["Confirm the file is a genuine 32-bit or 64-bit Windows PE image using dumpbin /headers or a PE viewer like PE-bear","Verify the file was fully downloaded or copied by comparing its size or hash against the source","If parsing user-selected or untrusted files, pre-validate the MZ + PE signature before calling PEImage.FromFile and skip non-PE files gracefully","Wrap the parse call in a try-catch for PEImageParseException and surface a user-friendly message for non-PE inputs"],"exampleFix":"// before\nvar image = PEImage.FromFile(path); // throws on old DOS EXE\n\n// after\nstatic bool IsValidPE(string path)\n{\n    byte[] b = File.ReadAllBytes(path);\n    if (b.Length < 0x40 || b[0] != 0x4D || b[1] != 0x5A) return false;\n    int peOff = BitConverter.ToInt32(b, 0x3C);\n    return peOff >= 0 && peOff + 4 <= b.Length\n        && b[peOff] == 0x50 && b[peOff + 1] == 0x45\n        && b[peOff + 2] == 0x00 && b[peOff + 3] == 0x00;\n}\n\nif (!IsValidPE(path)) return;\nvar image = PEImage.FromFile(path);","handlingStrategy":"try-catch","validationCode":"// Pre-validate MZ + PE signature before full parse\nstatic bool IsValidPESignature(string path)\n{\n    byte[] b = File.ReadAllBytes(path);\n    if (b.Length < 0x40) return false;\n    if (b[0] != 0x4D || b[1] != 0x5A) return false; // \"MZ\"\n    int peOff = BitConverter.ToInt32(b, 0x3C);      // e_lfanew\n    if (peOff < 0 || peOff + 4 > b.Length) return false;\n    return b[peOff] == 0x50 && b[peOff + 1] == 0x45  // \"PE\"\n        && b[peOff + 2] == 0x00 && b[peOff + 3] == 0x00;\n}\n\n// Usage\nif (!IsValidPESignature(path)) { /* not a PE file, skip */ return; }","typeGuard":null,"tryCatchPattern":"try\n{\n    var image = PEImage.FromFile(path);\n    // use image.DosHeader, image.CoffHeader, etc.\n}\ncatch (PEImageParseException ex)\n{\n    // ex.Offset = byte position where parsing failed\n    // ex.Message = description of what was expected\n    logger.Warn($\"Not a valid PE image: {ex.Message} at offset {ex.Offset}\");\n}","preventionTips":["Always validate the MZ and PE signatures before calling PEImage.FromFile on untrusted input","When building a file-preview feature, filter file extensions or signatures so only genuine PE images reach the parser","Never assume a file with an .exe extension is a valid PE — verify the binary signature"],"tags":["pe-format","binary-parsing","file-validation","corrupted-file"],"backgroundTag":null,"analyzedSha":"cb5d9c429c81d9796fac469da2a68efb5626946d","analyzedAt":"2026-08-13T11:51:01.370Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}