diff --git a/BurnOutSharp.Builder/PortableExecutable.cs b/BurnOutSharp.Builder/PortableExecutable.cs
index c8061071..c78d1f9c 100644
--- a/BurnOutSharp.Builder/PortableExecutable.cs
+++ b/BurnOutSharp.Builder/PortableExecutable.cs
@@ -109,14 +109,27 @@ namespace BurnOutSharp.Builder
if (coffSymbolTable == null)
return null;
+ // If the offset for the COFF string table doesn't exist
+ tableAddress = initialOffset
+ + (int)coffFileHeader.PointerToSymbolTable.ConvertVirtualAddress(executable.SectionTable)
+ + (coffSymbolTable.Length * 18 /* sizeof(COFFSymbolTableEntry) */);
+ if (tableAddress >= data.Length)
+ return executable;
+
// Set the COFF symbol table
executable.COFFSymbolTable = coffSymbolTable;
+
+ // Try to parse the COFF string table
+ var coffStringTable = ParseCOFFStringTable(data, tableAddress);
+ if (coffStringTable == null)
+ return null;
+
+ // Set the COFF string table
+ executable.COFFStringTable = coffStringTable;
}
#endregion
- // TODO: COFFStringTable (Only if COFFSymbolTable?)
-
#region Attribute Certificate Table
if (optionalHeader.CertificateTable != null && optionalHeader.CertificateTable.VirtualAddress != 0)
@@ -583,6 +596,37 @@ namespace BurnOutSharp.Builder
return attributeCertificateTable.ToArray();
}
+ ///
+ /// Parse a Stream into a COFF string table
+ ///
+ /// Byte array to parse
+ /// Offset into the byte array
+ /// Filled COFF string table on success, null on error
+ private static COFFStringTable ParseCOFFStringTable(byte[] data, int offset)
+ {
+ // TODO: Use marshalling here instead of building
+ var coffStringTable = new COFFStringTable();
+
+ coffStringTable.TotalSize = data.ReadUInt32(ref offset);
+
+ var strings = new List();
+ if (coffStringTable.TotalSize > 4)
+ {
+ uint totalSize = coffStringTable.TotalSize;
+ while (totalSize > 0)
+ {
+ int initialPosition = offset;
+ string str = data.ReadString(ref offset);
+ strings.Add(str);
+ totalSize -= (uint)(offset - initialPosition);
+ }
+ }
+
+ coffStringTable.Strings = strings.ToArray();
+
+ return coffStringTable;
+ }
+
///
/// Parse a byte array into a resource directory table
///
@@ -828,12 +872,18 @@ namespace BurnOutSharp.Builder
// Set the COFF symbol table
executable.COFFSymbolTable = coffSymbolTable;
+
+ // Try to parse the COFF string table
+ var coffStringTable = ParseCOFFStringTable(data);
+ if (coffStringTable == null)
+ return null;
+
+ // Set the COFF string table
+ executable.COFFStringTable = coffStringTable;
}
#endregion
- // TODO: COFFStringTable (Only if COFFSymbolTable?)
-
#region Attribute Certificate Table
if (optionalHeader.CertificateTable != null && optionalHeader.CertificateTable.VirtualAddress != 0)
@@ -1271,6 +1321,36 @@ namespace BurnOutSharp.Builder
return coffSymbolTable;
}
+ ///
+ /// Parse a Stream into a COFF string table
+ ///
+ /// Stream to parse
+ /// Filled COFF string table on success, null on error
+ private static COFFStringTable ParseCOFFStringTable(Stream data)
+ {
+ // TODO: Use marshalling here instead of building
+ var coffStringTable = new COFFStringTable();
+
+ coffStringTable.TotalSize = data.ReadUInt32();
+
+ var strings = new List();
+ if (coffStringTable.TotalSize > 4)
+ {
+ uint totalSize = coffStringTable.TotalSize;
+ while (totalSize > 0)
+ {
+ long initialPosition = data.Position;
+ string str = data.ReadString();
+ strings.Add(str);
+ totalSize -= (uint)(data.Position - initialPosition);
+ }
+ }
+
+ coffStringTable.Strings = strings.ToArray();
+
+ return coffStringTable;
+ }
+
///
/// Parse a Stream into an attribute certificate table
///
diff --git a/BurnOutSharp.Models/PortableExecutable/COFFSymbolTableEntry.cs b/BurnOutSharp.Models/PortableExecutable/COFFSymbolTableEntry.cs
index de1a61c1..0ee83017 100644
--- a/BurnOutSharp.Models/PortableExecutable/COFFSymbolTableEntry.cs
+++ b/BurnOutSharp.Models/PortableExecutable/COFFSymbolTableEntry.cs
@@ -1,7 +1,4 @@
-using System.Diagnostics;
-using System;
-using System.Drawing;
-using System.Runtime.InteropServices;
+using System.Runtime.InteropServices;
namespace BurnOutSharp.Models.PortableExecutable
{