Perfare/Il2CppDumper · error · NotSupportedException

Invalid Optional header magic

Error message

Invalid Optional header magic {magic}

What it means

Thrown during PE header parsing after the PE signature and COFF FileHeader have been read. The first UInt16 of the Optional Header (the magic) determines whether the image is PE32 (0x10b, 32-bit, parsed with OptionalHeader) or PE32+ (0x20b, 64-bit, parsed with OptionalHeader64). Any other value means the file is not a valid PE executable — it may be corrupted, truncated, or an entirely different format misidentified as PE — so the parser cannot determine the image bitness or locate the ImageBase and aborts by raising this NotSupportedException at Il2CppDumper/ExecutableFormats/PE.cs:41. The faulting input is the Optional Header magic field of the loaded file.

Solutions

  1. Confirm the binary is a standard PE32 (magic 0x10b) or PE32+ (magic 0x20b) using a tool like CFF Explorer or pestudio.
  2. Re-obtain the original GameAssembly.dll without post-processing/packing that alters headers.
  3. If the file is a console/custom PE variant, this dumper does not support it; use a platform-specific extraction tool first.
  4. Verify the file hash against the original build output to rule out corruption.

Example fix

// before
// magic read as 0x020C (ROM image) -> NotSupportedException
// after
// supply a standard PE: check bytes at PE offset + 24 == 0x0B01 or 0x0B02 (LE)
Defensive patterns

Strategy: validation

Validate before calling

byte[] b = File.ReadAllBytes(path);
uint off = BitConverter.ToUInt32(b, 0x3C);
ushort magic = BitConverter.ToUInt16(b, (int)off + 24);
bool ok = magic == 0x10b || magic == 0x20b; // PE32 or PE32+

Type guard

static bool IsStandardPeOptionalHeader(byte[] b) { uint o = BitConverter.ToUInt32(b, 0x3C); ushort m = BitConverter.ToUInt16(b, (int)o + 24); return m is 0x10b or 0x20b; }

Try / catch

try { var pe = new PE(stream); }
catch (NotSupportedException ex) when (ex.Message.StartsWith("Invalid Optional header magic")) { /* unsupported PE variant */ }

Prevention

When it happens

Trigger: Calling new PE(stream) on a PE whose optional header magic read at FileHeader end is not 0x10b or 0x20b — e.g. ROM images, unknown/corrupt optional headers, or files where SizeOfOptionalHeader/magic got mangled.

Common situations: Dumping non-standard PE derivatives (Xbox/UWP custom headers), files hand-edited or corrupted in transit, or obfuscated/packed binaries that scrambled the optional header.

Related errors


AI-assisted analysis of Perfare/Il2CppDumper@4741d46ba9 (2026-09-11). Data as JSON: /api/errors/fabd444ecb860f60. Report an issue: GitHub.

Appendix: source

Thrown at Il2CppDumper/ExecutableFormats/PE.cs:41

            }
            var fileHeader = ReadClass<FileHeader>();
            var pos = Position;
            var magic = ReadUInt16();
            Position -= 2;
            if (magic == 0x10b)
            {
                Is32Bit = true;
                var optionalHeader = ReadClass<OptionalHeader>();
                ImageBase = optionalHeader.ImageBase;
            }
            else if (magic == 0x20b)
            {
                var optionalHeader = ReadClass<OptionalHeader64>();
                ImageBase = optionalHeader.ImageBase;
            }
            else
            {
                throw new NotSupportedException($"Invalid Optional header magic {magic}");
            }
            Position = pos + fileHeader.SizeOfOptionalHeader;
            sections = ReadClassArray<SectionHeader>(fileHeader.NumberOfSections);
        }

        public void LoadFromMemory(ulong addr)
        {
            ImageBase = addr;
            foreach (var section in sections)
            {
                section.PointerToRawData = section.VirtualAddress;
                section.SizeOfRawData = section.VirtualSize;
            }
        }

        public override ulong MapVATR(ulong absAddr)
        {
            var addr = absAddr - ImageBase;

View on GitHub (pinned to 4741d46ba9)