Perfare/Il2CppDumper · error · InvalidDataException

ERROR: Invalid PE file

Error message

ERROR: Invalid PE file

What it means

Thrown by PELoader.Load when the file's DOS header magic is not 0x5A4D ('MZ'). PELoader resolves native exports for script generation (il2cpp bridge DLLs), and this check rejects files that are not Windows PE images before any loading occurs.

Solutions

  1. Open the file in a hex editor and confirm it starts with 4D 5A ('MZ').
  2. Re-download the DLL from the correct source; HTML error pages indicate a failed download.
  3. Check the path passed to Load resolves to the actual native DLL, not a text/config file.
  4. If the target library is Linux-only (.so), use the ELF loading path instead of PELoader.

Example fix

// before
PELoader.Load("il2cpp_bridge.txt"); // not a PE
// after
PELoader.Load("GameAssembly.dll"); // starts with MZ
Defensive patterns

Strategy: validation

Validate before calling

byte[] b = File.ReadAllBytes(dllPath);
bool isPe = b.Length >= 2 && b[0] == 0x4D && b[1] == 0x5A;

Type guard

static bool IsLoadablePe(string path) => File.ReadAllBytes(path) is { Length: > 1 } b && b[0] == 0x4D && b[1] == 0x5A;

Try / catch

try { PELoader.Load(file); }
catch (InvalidDataException ex) when (ex.Message == "ERROR: Invalid PE file") { /* re-fetch or correct the DLL path */ }

Prevention

When it happens

Trigger: Calling PELoader.Load(fileName) on a file that does not start with 'MZ' — e.g. a placeholder, a script, an ELF library, or a download that saved an HTML error page instead of the DLL.

Common situations: A required native DLL failed to download and the file is an HTML error page, the path in config points at the wrong file, or someone substituted an .so (ELF) where a .dll was expected.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at Il2CppDumper/Utils/PELoader.cs:21

using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace Il2CppDumper
{
    public class PELoader
    {
        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private extern static IntPtr LoadLibrary(string path);

        public static PE Load(string fileName)
        {
            var buff = File.ReadAllBytes(fileName);
            using var reader = new BinaryStream(new MemoryStream(buff));
            var dosHeader = reader.ReadClass<DosHeader>();
            if (dosHeader.Magic != 0x5A4D)
            {
                throw new InvalidDataException("ERROR: Invalid PE file");
            }
            reader.Position = dosHeader.Lfanew;
            if (reader.ReadUInt32() != 0x4550u) //Signature
            {
                throw new InvalidDataException("ERROR: Invalid PE file");
            }
            var fileHeader = reader.ReadClass<FileHeader>();
            if (fileHeader.Machine == 0x14c && Environment.Is64BitProcess) //64bit process can't load 32bit dll
            {
                throw new InvalidOperationException("The file is a 32-bit file, please try to load it with Il2CppDumper-x86.exe");
            }
            if (fileHeader.Machine == 0x8664 && !Environment.Is64BitProcess) //32bit process can't load 64bit dll
            {
                throw new InvalidOperationException("The file is a 64-bit file, please try to load it with Il2CppDumper.exe");
            }
            var pos = reader.Position;
            reader.Position = pos + fileHeader.SizeOfOptionalHeader;
            var sections = reader.ReadClassArray<SectionHeader>(fileHeader.NumberOfSections);

View on GitHub (pinned to 4741d46ba9)