From 690c49ae1f830f854917eaf49ed79c90d2fb18b6 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 10 Nov 2022 11:58:46 -0800 Subject: [PATCH] Fix PE import table parsing --- BurnOutSharp.Builder/PortableExecutable.cs | 105 ++++++++++++++---- .../PortableExecutable/HintNameTableEntry.cs | 2 +- 2 files changed, 84 insertions(+), 23 deletions(-) diff --git a/BurnOutSharp.Builder/PortableExecutable.cs b/BurnOutSharp.Builder/PortableExecutable.cs index 9e3d67c7..9b0ccb69 100644 --- a/BurnOutSharp.Builder/PortableExecutable.cs +++ b/BurnOutSharp.Builder/PortableExecutable.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using BurnOutSharp.Models.PortableExecutable; namespace BurnOutSharp.Builder @@ -873,10 +874,10 @@ namespace BurnOutSharp.Builder } // Lookup tables + var importLookupTables = new Dictionary(); + for (int i = 0; i < importTable.ImportDirectoryTable.Length; i++) { - var importLookupTable = new Dictionary(); - var importDirectoryTableEntry = importTable.ImportDirectoryTable[i]; if (importDirectoryTableEntry.ImportLookupTableRVA != 0) { @@ -915,17 +916,17 @@ namespace BurnOutSharp.Builder break; } - importLookupTable[i] = entryLookupTable.ToArray(); + importLookupTables[i] = entryLookupTable.ToArray(); } - - importTable.ImportLookupTables = importLookupTable; } + importTable.ImportLookupTables = importLookupTables; + // Address tables + var importAddressTables = new Dictionary(); + for (int i = 0; i < importTable.ImportDirectoryTable.Length; i++) { - var importLookupTable = new Dictionary(); - var importDirectoryTableEntry = importTable.ImportDirectoryTable[i]; if (importDirectoryTableEntry.ImportAddressTableRVA != 0) { @@ -955,13 +956,42 @@ namespace BurnOutSharp.Builder break; } - importLookupTable[i] = entryAddressTable.ToArray(); + importAddressTables[i] = entryAddressTable.ToArray(); } - - importTable.ImportAddressTables = importLookupTable; } - // TODO: Figure out how to find the hint/name table + importTable.ImportAddressTables = importAddressTables; + + // Hint/Name table + if (importTable.ImportLookupTables != null && importTable.ImportLookupTables.Count > 0) + { + var importHintNameTable = new List(); + + // Get the addresses of the hint/name table entries + List hintNameTableEntryAddresses = importTable.ImportLookupTables + .SelectMany(kvp => kvp.Value) + .Select(ilte => (int)ilte.HintNameTableRVA.ConvertVirtualAddress(sections)) + .Distinct() + .OrderBy(a => a) + .ToList(); + + // If we have any addresses, add them to the table + if (hintNameTableEntryAddresses.Any()) + { + for (int i = 0; i < hintNameTableEntryAddresses.Count; i++) + { + int hintNameTableEntryAddress = hintNameTableEntryAddresses[i]; + var hintNameTableEntry = new HintNameTableEntry(); + + hintNameTableEntry.Hint = data.ReadUInt16(ref hintNameTableEntryAddress); + hintNameTableEntry.Name = data.ReadString(ref hintNameTableEntryAddress, System.Text.Encoding.ASCII); + + importHintNameTable.Add(hintNameTableEntry); + } + } + + importTable.HintNameTable = importHintNameTable.ToArray(); + } return importTable; } @@ -1974,10 +2004,10 @@ namespace BurnOutSharp.Builder } // Lookup tables + var importLookupTables = new Dictionary(); + for (int i = 0; i < importTable.ImportDirectoryTable.Length; i++) { - var importLookupTable = new Dictionary(); - var importDirectoryTableEntry = importTable.ImportDirectoryTable[i]; if (importDirectoryTableEntry.ImportLookupTableRVA != 0) { @@ -2018,17 +2048,17 @@ namespace BurnOutSharp.Builder break; } - importLookupTable[i] = entryLookupTable.ToArray(); + importLookupTables[i] = entryLookupTable.ToArray(); } - - importTable.ImportLookupTables = importLookupTable; } + importTable.ImportLookupTables = importLookupTables; + // Address tables + var importAddressTables = new Dictionary(); + for (int i = 0; i < importTable.ImportDirectoryTable.Length; i++) { - var importLookupTable = new Dictionary(); - var importDirectoryTableEntry = importTable.ImportDirectoryTable[i]; if (importDirectoryTableEntry.ImportAddressTableRVA != 0) { @@ -2060,13 +2090,44 @@ namespace BurnOutSharp.Builder break; } - importLookupTable[i] = entryAddressTable.ToArray(); + importAddressTables[i] = entryAddressTable.ToArray(); } - - importTable.ImportAddressTables = importLookupTable; } - // TODO: Figure out how to find the hint/name table + importTable.ImportAddressTables = importAddressTables; + + // Hint/Name table + if (importTable.ImportLookupTables != null && importTable.ImportLookupTables.Count > 0) + { + var importHintNameTable = new List(); + + // Get the addresses of the hint/name table entries + List hintNameTableEntryAddresses = importTable.ImportLookupTables + .SelectMany(kvp => kvp.Value) + .Select(ilte => (int)ilte.HintNameTableRVA.ConvertVirtualAddress(sections)) + .Distinct() + .OrderBy(a => a) + .ToList(); + + // If we have any addresses, add them to the table + if (hintNameTableEntryAddresses.Any()) + { + for (int i = 0; i < hintNameTableEntryAddresses.Count; i++) + { + int hintNameTableEntryAddress = hintNameTableEntryAddresses[i]; + data.Seek(hintNameTableEntryAddress, SeekOrigin.Begin); + + var hintNameTableEntry = new HintNameTableEntry(); + + hintNameTableEntry.Hint = data.ReadUInt16(); + hintNameTableEntry.Name = data.ReadString(System.Text.Encoding.ASCII); + + importHintNameTable.Add(hintNameTableEntry); + } + } + + importTable.HintNameTable = importHintNameTable.ToArray(); + } return importTable; } diff --git a/BurnOutSharp.Models/PortableExecutable/HintNameTableEntry.cs b/BurnOutSharp.Models/PortableExecutable/HintNameTableEntry.cs index d6b46eda..d486c433 100644 --- a/BurnOutSharp.Models/PortableExecutable/HintNameTableEntry.cs +++ b/BurnOutSharp.Models/PortableExecutable/HintNameTableEntry.cs @@ -18,6 +18,6 @@ /// must be matched to the public name in the DLL. This string is case sensitive /// and terminated by a null byte. /// - public byte[] Name; + public string Name; } }