mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-09-22 06:45:03 +00:00
Fix import table parsing
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user