Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions LibCpp2IL/PE/PE.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -64,6 +67,9 @@ public PE(MemoryStream input) : base(input)

peSectionHeaders = ReadReadableArrayAtRawAddr<SectionHeader>(-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");
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
Loading