Fix import table parsing

This commit is contained in:
Matt Nadareski
2022-12-05 13:52:15 -08:00
parent 7293d55239
commit 9411f5044a
3 changed files with 109 additions and 41 deletions

View File

@@ -1067,46 +1067,73 @@ namespace BurnOutSharp.Builder
continue;
int tableAddress = (int)importDirectoryTableEntry.ImportAddressTableRVA.ConvertVirtualAddress(sections);
var entryAddressTable = new List<ImportAddressTableEntry>();
var addressLookupTable = new List<ImportAddressTableEntry>();
while (true)
{
var entryLookupTableEntry = new ImportAddressTableEntry();
var addressLookupTableEntry = new ImportAddressTableEntry();
if (magic == OptionalHeaderMagicNumber.PE32)
{
uint entryValue = data.ReadUInt32(ref tableAddress);
entryLookupTableEntry.Address_PE32 = entryValue;
addressLookupTableEntry.OrdinalNameFlag = (entryValue & 0x80000000) != 0;
if (addressLookupTableEntry.OrdinalNameFlag)
addressLookupTableEntry.OrdinalNumber = (ushort)(entryValue & ~0x80000000);
else
addressLookupTableEntry.HintNameTableRVA = (uint)(entryValue & ~0x80000000);
}
else if (magic == OptionalHeaderMagicNumber.PE32Plus)
{
ulong entryValue = data.ReadUInt64(ref tableAddress);
entryLookupTableEntry.Address_PE32Plus = entryValue;
addressLookupTableEntry.OrdinalNameFlag = (entryValue & 0x8000000000000000) != 0;
if (addressLookupTableEntry.OrdinalNameFlag)
addressLookupTableEntry.OrdinalNumber = (ushort)(entryValue & ~0x8000000000000000);
else
addressLookupTableEntry.HintNameTableRVA = (uint)(entryValue & ~0x8000000000000000);
}
entryAddressTable.Add(entryLookupTableEntry);
addressLookupTable.Add(addressLookupTableEntry);
// All zero values means the last entry
if (entryLookupTableEntry.Address_PE32 == 0
&& entryLookupTableEntry.Address_PE32Plus == 0)
if (addressLookupTableEntry.OrdinalNameFlag == false
&& addressLookupTableEntry.OrdinalNumber == 0
&& addressLookupTableEntry.HintNameTableRVA == 0)
break;
}
importAddressTables[i] = entryAddressTable.ToArray();
importAddressTables[i] = addressLookupTable.ToArray();
}
importTable.ImportAddressTables = importAddressTables;
// Hint/Name table
var importHintNameTable = new List<HintNameTableEntry>();
if (importTable.ImportLookupTables != null && importTable.ImportLookupTables.Count > 0)
{
var importHintNameTable = new List<HintNameTableEntry>();
// Get the addresses of the hint/name table entries
List<int> hintNameTableEntryAddresses = importTable.ImportLookupTables
.SelectMany(kvp => kvp.Value)
.Select(ilte => (int)ilte.HintNameTableRVA.ConvertVirtualAddress(sections))
.Where(addr => addr != 0)
List<int> hintNameTableEntryAddresses = new List<int>();
// If we have import lookup tables
if (importTable.ImportLookupTables != null && importLookupTables.Count > 0)
{
var addresses = importTable.ImportLookupTables
.SelectMany(kvp => kvp.Value)
.Select(ilte => (int)ilte.HintNameTableRVA.ConvertVirtualAddress(sections));
hintNameTableEntryAddresses.AddRange(addresses);
}
// If we have import address tables
if (importTable.ImportAddressTables != null && importTable.ImportAddressTables.Count > 0)
{
var addresses = importTable.ImportAddressTables
.SelectMany(kvp => kvp.Value)
.Select(iate => (int)iate.HintNameTableRVA.ConvertVirtualAddress(sections));
hintNameTableEntryAddresses.AddRange(addresses);
}
// Sanitize the addresses
hintNameTableEntryAddresses = hintNameTableEntryAddresses.Where(addr => addr != 0)
.Distinct()
.OrderBy(a => a)
.ToList();
@@ -1125,10 +1152,10 @@ namespace BurnOutSharp.Builder
importHintNameTable.Add(hintNameTableEntry);
}
}
importTable.HintNameTable = importHintNameTable.ToArray();
}
importTable.HintNameTable = importHintNameTable.ToArray();
return importTable;
}
@@ -2295,46 +2322,74 @@ namespace BurnOutSharp.Builder
uint tableAddress = importDirectoryTableEntry.ImportAddressTableRVA.ConvertVirtualAddress(sections);
data.Seek(tableAddress, SeekOrigin.Begin);
var entryAddressTable = new List<ImportAddressTableEntry>();
var addressLookupTable = new List<ImportAddressTableEntry>();
while (true)
{
var entryLookupTableEntry = new ImportAddressTableEntry();
var addressLookupTableEntry = new ImportAddressTableEntry();
if (magic == OptionalHeaderMagicNumber.PE32)
{
uint entryValue = data.ReadUInt32();
entryLookupTableEntry.Address_PE32 = entryValue;
addressLookupTableEntry.OrdinalNameFlag = (entryValue & 0x80000000) != 0;
if (addressLookupTableEntry.OrdinalNameFlag)
addressLookupTableEntry.OrdinalNumber = (ushort)(entryValue & ~0x80000000);
else
addressLookupTableEntry.HintNameTableRVA = (uint)(entryValue & ~0x80000000);
}
else if (magic == OptionalHeaderMagicNumber.PE32Plus)
{
ulong entryValue = data.ReadUInt64();
entryLookupTableEntry.Address_PE32Plus = entryValue;
addressLookupTableEntry.OrdinalNameFlag = (entryValue & 0x8000000000000000) != 0;
if (addressLookupTableEntry.OrdinalNameFlag)
addressLookupTableEntry.OrdinalNumber = (ushort)(entryValue & ~0x8000000000000000);
else
addressLookupTableEntry.HintNameTableRVA = (uint)(entryValue & ~0x8000000000000000);
}
entryAddressTable.Add(entryLookupTableEntry);
addressLookupTable.Add(addressLookupTableEntry);
// All zero values means the last entry
if (entryLookupTableEntry.Address_PE32 == 0
&& entryLookupTableEntry.Address_PE32Plus == 0)
if (addressLookupTableEntry.OrdinalNameFlag == false
&& addressLookupTableEntry.OrdinalNumber == 0
&& addressLookupTableEntry.HintNameTableRVA == 0)
break;
}
importAddressTables[i] = entryAddressTable.ToArray();
importAddressTables[i] = addressLookupTable.ToArray();
}
importTable.ImportAddressTables = importAddressTables;
// Hint/Name table
if (importTable.ImportLookupTables != null && importTable.ImportLookupTables.Count > 0)
{
var importHintNameTable = new List<HintNameTableEntry>();
var importHintNameTable = new List<HintNameTableEntry>();
if ((importTable.ImportLookupTables != null && importTable.ImportLookupTables.Count > 0)
|| importTable.ImportAddressTables != null && importTable.ImportAddressTables.Count > 0)
{
// Get the addresses of the hint/name table entries
List<int> hintNameTableEntryAddresses = importTable.ImportLookupTables
.SelectMany(kvp => kvp.Value)
.Select(ilte => (int)ilte.HintNameTableRVA.ConvertVirtualAddress(sections))
.Where(addr => addr != 0)
List<int> hintNameTableEntryAddresses = new List<int>();
// If we have import lookup tables
if (importTable.ImportLookupTables != null && importLookupTables.Count > 0)
{
var addresses = importTable.ImportLookupTables
.SelectMany(kvp => kvp.Value)
.Select(ilte => (int)ilte.HintNameTableRVA.ConvertVirtualAddress(sections));
hintNameTableEntryAddresses.AddRange(addresses);
}
// If we have import address tables
if (importTable.ImportAddressTables != null && importTable.ImportAddressTables.Count > 0)
{
var addresses = importTable.ImportAddressTables
.SelectMany(kvp => kvp.Value)
.Select(iate => (int)iate.HintNameTableRVA.ConvertVirtualAddress(sections));
hintNameTableEntryAddresses.AddRange(addresses);
}
// Sanitize the addresses
hintNameTableEntryAddresses = hintNameTableEntryAddresses.Where(addr => addr != 0)
.Distinct()
.OrderBy(a => a)
.ToList();
@@ -2355,10 +2410,10 @@ namespace BurnOutSharp.Builder
importHintNameTable.Add(hintNameTableEntry);
}
}
importTable.HintNameTable = importHintNameTable.ToArray();
}
importTable.HintNameTable = importHintNameTable.ToArray();
return importTable;
}

View File

@@ -12,13 +12,25 @@
public class ImportAddressTableEntry
{
/// <summary>
/// 32-bit address of the symbol being imported
/// If this bit is set, import by ordinal. Otherwise, import by name. Bit is
/// masked as 0x80000000 for PE32, 0x8000000000000000 for PE32+.
/// </summary>
public uint Address_PE32;
/// <remarks>Bit 31/63</remarks>
public bool OrdinalNameFlag;
/// <summary>
/// 64-bit address of the symbol being imported
/// A 16-bit ordinal number. This field is used only if the Ordinal/Name Flag
/// bit field is 1 (import by ordinal). Bits 30-15 or 62-15 must be 0.
/// </summary>
public ulong Address_PE32Plus;
/// <remarks>Bits 15-0</remarks>
public ushort OrdinalNumber;
/// <summary>
/// A 31-bit RVA of a hint/name table entry. This field is used only if the
/// Ordinal/Name Flag bit field is 0 (import by name). For PE32+ bits 62-31
/// must be zero.
/// </summary>
/// <remarks>Bits 30-0</remarks>
public uint HintNameTableRVA;
}
}

View File

@@ -1579,12 +1579,13 @@ namespace BurnOutSharp.Wrappers
{
for (int i = 0; i < importAddressTable.Length; i++)
{
var importLookupTableEntry = importAddressTable[i];
var importAddressTableEntry = importAddressTable[i];
Console.WriteLine($" Import Address Table {index} Entry {i}");
if (OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32)
Console.WriteLine($" Address: {importLookupTableEntry.Address_PE32}");
Console.WriteLine($" Ordinal/Name flag: {importAddressTableEntry.OrdinalNameFlag}");
if (importAddressTableEntry.OrdinalNameFlag)
Console.WriteLine($" Ordinal number: {importAddressTableEntry.OrdinalNumber}");
else
Console.WriteLine($" Address: {importLookupTableEntry.Address_PE32Plus}");
Console.WriteLine($" Hint/Name table RVA: {importAddressTableEntry.HintNameTableRVA}");
}
}
}