diff --git a/Il2CppInspector/FileFormatReaders/FormatLayouts/PE.cs b/Il2CppInspector/FileFormatReaders/FormatLayouts/PE.cs index 06adcc5..3992bd3 100644 --- a/Il2CppInspector/FileFormatReaders/FormatLayouts/PE.cs +++ b/Il2CppInspector/FileFormatReaders/FormatLayouts/PE.cs @@ -1,5 +1,5 @@ /* - Copyright 2017 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com + Copyright 2017-2019 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com All rights reserved. */ @@ -8,7 +8,10 @@ using NoisyCowStudios.Bin2Object; namespace Il2CppInspector { + // Source: https://github.com/dotnet/llilc/blob/master/include/clr/ntimage.h #pragma warning disable CS0649 + + // _IMAGE_FILE_HEADER internal class COFFHeader { public ushort Machine; @@ -20,9 +23,10 @@ namespace Il2CppInspector public ushort Characteristics; } - internal class PEOptHeader + // _IMAGE_OPTIONAL_HEADER + internal class PEOptHeader32 { - public ushort signature; + public ushort Magic; public byte MajorLinkerVersion; public byte MinorLinkerVersion; public uint SizeOfCode; @@ -56,23 +60,62 @@ namespace Il2CppInspector public RvaEntry[] DataDirectory; } + // _IMAGE_OPTIONAL_HEADER64 + internal class PEOptHeader64 + { + public ushort Magic; + public byte MajorLinkerVersion; + public byte MinorLinkerVersion; + public uint SizeOfCode; + public uint SizeOfInitializedData; + public uint SizeOfUninitializedData; + public uint AddressOfEntryPoint; + public uint BaseOfCode; + public ulong ImageBase; + public uint SectionAlignment; + public uint FileAlignment; + public ushort MajorOSVersion; + public ushort MinorOSVersion; + public ushort MajorImageVersion; + public ushort MinorImageVersion; + public ushort MajorSubsystemVersion; + public ushort MinorSubsystemVersion; + public uint Win32VersionValue; + public uint SizeOfImage; + public uint SizeOfHeaders; + public uint Checksum; + public ushort Subsystem; + public ushort DLLCharacteristics; + public ulong SizeOfStackReserve; + public ulong SizeOfStackCommit; + public ulong SizeOfHeapReserve; + public ulong SizeOfHeapCommit; + public uint LoaderFlags; + public uint NumberOfRvaAndSizes; + [ArrayLength(FieldName = "NumberOfRvaAndSizes")] + public RvaEntry[] DataDirectory; + } + internal class RvaEntry { public uint VirtualAddress; public uint Size; } + // _IMAGE_SECTION_HEADER internal class PESection { [String(FixedSize=8)] public string Name; - public uint SizeMemory; - public uint BaseMemory; // RVA - public uint SizeImage; // Size in file - public uint BaseImage; // Base address in file - [ArrayLength(FixedSize=12)] - public byte[] Reserved; - public uint Flags; + public uint VirtualSize; // Size in memory + public uint VirtualAddress; // Base address in memory (RVA) + public uint SizeOfRawData; // Size in file + public uint PointerToRawData; // Base address in file + public uint PointerToRelocations; + public uint PointerToLinenumbers; + public ushort NumberOfRelocations; + public ushort NumberOfLinenumbers; + public uint Characteristics; } #pragma warning restore CS0649 } diff --git a/Il2CppInspector/FileFormatReaders/PEReader.cs b/Il2CppInspector/FileFormatReaders/PEReader.cs index ace35b2..d886e32 100644 --- a/Il2CppInspector/FileFormatReaders/PEReader.cs +++ b/Il2CppInspector/FileFormatReaders/PEReader.cs @@ -13,7 +13,7 @@ namespace Il2CppInspector internal class PEReader : FileFormatReader { private COFFHeader coff; - private PEOptHeader pe; + private PEOptHeader32 pe; private PESection[] sections; private uint pFuncTable; @@ -34,7 +34,7 @@ namespace Il2CppInspector // IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20B // IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10B // Could also use coff.Characteristics (IMAGE_FILE_32BIT_MACHINE) or coff.Machine - public override int Bits => pe.signature == 0x20B ? 64 : 32; + public override int Bits => pe.Magic == 0x20B ? 64 : 32; protected override bool Init() { // Check for MZ signature "MZ" @@ -42,8 +42,7 @@ namespace Il2CppInspector return false; // Get offset to PE header from DOS header - Position = 0x3C; - Position = ReadUInt32(); + Position = ReadUInt32(0x3C); // Check PE signature "PE\0\0" if (ReadUInt32() != 0x00004550) @@ -58,10 +57,10 @@ namespace Il2CppInspector return false; // Read PE optional header - pe = ReadObject(); + pe = ReadObject(); // Ensure IMAGE_NT_OPTIONAL_HDR32_MAGIC (32-bit) - if (pe.signature != 0x10B) + if (pe.Magic != 0x10B) return false; // Get IAT @@ -73,11 +72,11 @@ namespace Il2CppInspector // Confirm that .rdata section begins at same place as IAT var rData = sections.First(x => x.Name == ".rdata"); - if (rData.BaseMemory != IATStart) + if (rData.VirtualAddress != IATStart) return false; // Calculate start of function pointer table - pFuncTable = rData.BaseImage + IATSize + 8; + pFuncTable = rData.PointerToRawData + IATSize + 8; GlobalOffset = pe.ImageBase; return true; } @@ -95,9 +94,9 @@ namespace Il2CppInspector if (uiAddr == 0) return 0; - var section = sections.First(x => uiAddr - GlobalOffset >= x.BaseMemory && - uiAddr - GlobalOffset < x.BaseMemory + x.SizeImage); - return (uint) (uiAddr - section.BaseMemory - GlobalOffset + section.BaseImage); + var section = sections.First(x => uiAddr - GlobalOffset >= x.VirtualAddress && + uiAddr - GlobalOffset < x.VirtualAddress + x.SizeOfRawData); + return (uint) (uiAddr - section.VirtualAddress - GlobalOffset + section.PointerToRawData); } } }