PE: Add ability to fetch exports with GetExports()
This commit is contained in:
15
Il2CppInspector.Common/FileFormatReaders/Export.cs
Normal file
15
Il2CppInspector.Common/FileFormatReaders/Export.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
Copyright 2020 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
namespace Il2CppInspector
|
||||
{
|
||||
public class Export
|
||||
{
|
||||
public int Ordinal;
|
||||
public string Name;
|
||||
public ulong VirtualAddress;
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ namespace Il2CppInspector
|
||||
ulong GlobalOffset { get; }
|
||||
Dictionary<string, ulong> GetSymbolTable();
|
||||
uint[] GetFunctionTable();
|
||||
IEnumerable<Export> GetExports();
|
||||
U ReadMappedObject<U>(ulong uiAddr) where U : new();
|
||||
U[] ReadMappedArray<U>(ulong uiAddr, int count) where U : new();
|
||||
long[] ReadMappedWordArray(ulong uiAddr, int count);
|
||||
@@ -136,6 +137,9 @@ namespace Il2CppInspector
|
||||
// Find search locations in the machine code for Il2Cpp data
|
||||
public virtual uint[] GetFunctionTable() => throw new NotImplementedException();
|
||||
|
||||
// Find all symbol exports for the image
|
||||
public virtual IEnumerable<Export> GetExports() => null;
|
||||
|
||||
// Map an RVA to an offset into the file image
|
||||
// No mapping by default
|
||||
public virtual uint MapVATR(ulong uiAddr) => (uint) uiAddr;
|
||||
|
||||
@@ -144,5 +144,21 @@ namespace Il2CppInspector
|
||||
public ushort NumberOfLinenumbers;
|
||||
public uint Characteristics;
|
||||
}
|
||||
|
||||
// _IMAGE_EXPORT_DIRECTORY
|
||||
internal class PEExportDirectory
|
||||
{
|
||||
public uint Characteristics;
|
||||
public uint TimeDateStamp;
|
||||
public ushort MajorVersion;
|
||||
public ushort MinorVersion;
|
||||
public uint Name;
|
||||
public uint Base;
|
||||
public uint NumberOfFunctions;
|
||||
public uint NumberOfNames;
|
||||
public uint AddressOfFunctions;
|
||||
public uint AddressOfNames;
|
||||
public uint AddressOfNameOrdinals;
|
||||
}
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -113,6 +114,32 @@ namespace Il2CppInspector
|
||||
return addrs.ToArray();
|
||||
}
|
||||
|
||||
public override IEnumerable<Export> GetExports() {
|
||||
// Get exports table
|
||||
var ETStart = pe.DataDirectory[0].VirtualAddress + pe.ImageBase;
|
||||
|
||||
// Get export RVAs
|
||||
var exportDirectoryTable = ReadObject<PEExportDirectory>(MapVATR(ETStart));
|
||||
var exportCount = (int) exportDirectoryTable.NumberOfFunctions;
|
||||
var exportAddresses = ReadArray<uint>(MapVATR(exportDirectoryTable.AddressOfFunctions + pe.ImageBase), exportCount);
|
||||
var exports = exportAddresses.Select((a, i) => new Export {
|
||||
Ordinal = (int) (exportDirectoryTable.Base + i),
|
||||
VirtualAddress = pe.ImageBase + a
|
||||
}).ToDictionary(x => x.Ordinal, x => x);
|
||||
|
||||
// Get export names
|
||||
var nameCount = (int) exportDirectoryTable.NumberOfNames;
|
||||
var namePointers = ReadArray<uint>(MapVATR(exportDirectoryTable.AddressOfNames + pe.ImageBase), nameCount);
|
||||
var ordinals = ReadArray<ushort>(MapVATR(exportDirectoryTable.AddressOfNameOrdinals + pe.ImageBase), nameCount);
|
||||
for (int i = 0; i < nameCount; i++) {
|
||||
var name = ReadNullTerminatedString(MapVATR(namePointers[i] + pe.ImageBase));
|
||||
var ordinal = (int) exportDirectoryTable.Base + ordinals[i];
|
||||
exports[ordinal].Name = name;
|
||||
}
|
||||
|
||||
return exports.Values;
|
||||
}
|
||||
|
||||
public override uint MapVATR(ulong uiAddr) {
|
||||
if (uiAddr == 0)
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user