diff --git a/LibCpp2IL/PE/PE.cs b/LibCpp2IL/PE/PE.cs index 48d6bbd1..4fd0a8a6 100644 --- a/LibCpp2IL/PE/PE.cs +++ b/LibCpp2IL/PE/PE.cs @@ -10,7 +10,9 @@ namespace LibCpp2IL.PE; public sealed class PE : Il2CppBinary { //Initialized in constructor + public readonly uint LastAddress; internal readonly byte[] raw; //Internal for PlusSearch + private readonly bool _isLoadedLayout; //PE-Specific Stuff internal readonly SectionHeader[] peSectionHeaders; //Internal for the one use in PlusSearch @@ -30,8 +32,9 @@ public sealed class PE : Il2CppBinary //Pointers - public PE(MemoryStream input) : base(input) + public PE(MemoryStream input, bool isLoadedLayout = false) : base(input) { + _isLoadedLayout = isLoadedLayout; raw = input.GetBuffer(); LibLogger.Verbose("\tReading PE File Header..."); var start = DateTime.Now; @@ -64,6 +67,9 @@ public PE(MemoryStream input) : base(input) peSectionHeaders = ReadReadableArrayAtRawAddr(-1, fileHeader.NumberOfSections); + var last = peSectionHeaders[^1]; + LastAddress = last.VirtualAddress + last.VirtualSize; + LibLogger.VerboseNewline($"OK ({(DateTime.Now - start).TotalMilliseconds} ms)"); LibLogger.VerboseNewline($"\t\tImage Base at 0x{peImageBase:X}"); LibLogger.VerboseNewline($"\t\tDLL is {(is32Bit ? "32" : "64")}-bit"); @@ -88,15 +94,17 @@ public override long MapVirtualAddressToRaw(ulong uiAddr, bool throwOnError = tr return VirtToRawInvalidNoMatch; } - var last = peSectionHeaders[peSectionHeaders.Length - 1]; - if (addr > last.VirtualAddress + last.VirtualSize) + if (addr > LastAddress) { if (throwOnError) - throw new ArgumentOutOfRangeException(nameof(uiAddr), $"Provided address maps to image offset 0x{addr:X} which is outside the range of the file (last section ends at 0x{last.VirtualAddress + last.VirtualSize:X})"); + throw new ArgumentOutOfRangeException(nameof(uiAddr), $"Provided address maps to image offset 0x{addr:X} which is outside the range of the file (last section ends at 0x{LastAddress:X})"); return VirtToRawInvalidOutOfBounds; } + if (_isLoadedLayout) + return addr; + var section = peSectionHeaders.FirstOrDefault(x => addr >= x.VirtualAddress && addr < x.VirtualAddress + x.VirtualSize); if (section == null) @@ -112,6 +120,9 @@ public override long MapVirtualAddressToRaw(ulong uiAddr, bool throwOnError = tr public override ulong MapRawAddressToVirtual(uint offset, bool throwOnError = true) { + if (_isLoadedLayout) + return peImageBase + offset; + var section = peSectionHeaders.FirstOrDefault(x => offset >= x.PointerToRawData && offset < x.PointerToRawData + x.SizeOfRawData); if (section == null) if (throwOnError) @@ -253,7 +264,10 @@ public override byte[] GetEntirePrimaryExecutableSection() if (primarySection == null) return []; - return GetRawBinaryContent().SubArray((int)primarySection.PointerToRawData, (int)primarySection.SizeOfRawData); + if (_isLoadedLayout) + return raw.SubArray((int)primarySection.VirtualAddress, (int)primarySection.VirtualSize); + + return raw.SubArray((int)primarySection.PointerToRawData, (int)primarySection.SizeOfRawData); } public override ulong GetVirtualAddressOfPrimaryExecutableSection() => peSectionHeaders.FirstOrDefault(s => s.Name == ".text")?.VirtualAddress + peImageBase ?? 0;