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; }
|
ulong GlobalOffset { get; }
|
||||||
Dictionary<string, ulong> GetSymbolTable();
|
Dictionary<string, ulong> GetSymbolTable();
|
||||||
uint[] GetFunctionTable();
|
uint[] GetFunctionTable();
|
||||||
|
IEnumerable<Export> GetExports();
|
||||||
U ReadMappedObject<U>(ulong uiAddr) where U : new();
|
U ReadMappedObject<U>(ulong uiAddr) where U : new();
|
||||||
U[] ReadMappedArray<U>(ulong uiAddr, int count) where U : new();
|
U[] ReadMappedArray<U>(ulong uiAddr, int count) where U : new();
|
||||||
long[] ReadMappedWordArray(ulong uiAddr, int count);
|
long[] ReadMappedWordArray(ulong uiAddr, int count);
|
||||||
@@ -136,6 +137,9 @@ namespace Il2CppInspector
|
|||||||
// Find search locations in the machine code for Il2Cpp data
|
// Find search locations in the machine code for Il2Cpp data
|
||||||
public virtual uint[] GetFunctionTable() => throw new NotImplementedException();
|
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
|
// Map an RVA to an offset into the file image
|
||||||
// No mapping by default
|
// No mapping by default
|
||||||
public virtual uint MapVATR(ulong uiAddr) => (uint) uiAddr;
|
public virtual uint MapVATR(ulong uiAddr) => (uint) uiAddr;
|
||||||
|
|||||||
@@ -144,5 +144,21 @@ namespace Il2CppInspector
|
|||||||
public ushort NumberOfLinenumbers;
|
public ushort NumberOfLinenumbers;
|
||||||
public uint Characteristics;
|
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
|
#pragma warning restore CS0649
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -113,6 +114,32 @@ namespace Il2CppInspector
|
|||||||
return addrs.ToArray();
|
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) {
|
public override uint MapVATR(ulong uiAddr) {
|
||||||
if (uiAddr == 0)
|
if (uiAddr == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user