diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDataEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDataEntry.cs
new file mode 100644
index 00000000..6f48d750
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDataEntry.cs
@@ -0,0 +1,59 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using BurnOutSharp.Tools;
+
+namespace BurnOutSharp.ExecutableType.Microsoft.Entries
+{
+ ///
+ /// Each Resource Data entry describes an actual unit of raw data in the Resource Data area.
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ internal class ResourceDataEntry
+ {
+ ///
+ /// The address of a unit of resource data in the Resource Data area.
+ ///
+ public uint OffsetToData;
+
+ ///
+ /// The size, in bytes, of the resource data that is pointed to by the Data RVA field.
+ ///
+ public uint Size;
+
+ ///
+ /// The code page that is used to decode code point values within the resource data.
+ /// Typically, the code page would be the Unicode code page.
+ ///
+ public uint CodePage;
+
+ ///
+ /// Reserved, must be 0.
+ ///
+ public uint Reserved;
+
+ public static ResourceDataEntry Deserialize(Stream stream)
+ {
+ var rde = new ResourceDataEntry();
+
+ rde.OffsetToData = stream.ReadUInt32();
+ rde.Size = stream.ReadUInt32();
+ rde.CodePage = stream.ReadUInt32();
+ rde.Reserved = stream.ReadUInt32();
+
+ return rde;
+ }
+
+ public static ResourceDataEntry Deserialize(byte[] content, int offset)
+ {
+ var rde = new ResourceDataEntry();
+
+ rde.OffsetToData = BitConverter.ToUInt32(content, offset); offset += 4;
+ rde.Size = BitConverter.ToUInt32(content, offset); offset += 4;
+ rde.CodePage = BitConverter.ToUInt32(content, offset); offset += 4;
+ rde.Reserved = BitConverter.ToUInt32(content, offset); offset += 4;
+
+ return rde;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs
index 92971263..d850f70f 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using BurnOutSharp.ExecutableType.Microsoft.Headers;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Entries
@@ -18,8 +19,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
/// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#resource-directory-entries
internal class ResourceDirectoryTableEntry
{
- #region Name Entry
-
///
/// The offset of a string that gives the Type, Name, or Language ID entry, depending on level of table.
///
@@ -40,31 +39,70 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
///
public uint SubdirectoryOffset => DataEntryOffset;
- #endregion
+ ///
+ /// Resource Data entry (a leaf).
+ ///
+ public ResourceDataEntry DataEntry;
///
/// Determine if an entry represents a leaf or another directory table
///
public bool IsResourceDataEntry() => (DataEntryOffset & (1 << 31)) == 0;
- public static ResourceDirectoryTableEntry Deserialize(Stream stream)
+ public static ResourceDirectoryTableEntry Deserialize(Stream stream, SectionHeader[] sections)
{
- var idte = new ResourceDirectoryTableEntry();
+ var rdte = new ResourceDirectoryTableEntry();
- idte.NameOffset = stream.ReadUInt32();
- idte.DataEntryOffset = stream.ReadUInt32();
+ rdte.NameOffset = stream.ReadUInt32();
+ rdte.DataEntryOffset = stream.ReadUInt32();
- return idte;
+ // Read in the data if we have a leaf
+ if (rdte.IsResourceDataEntry())
+ {
+ long lastPosition = stream.Position;
+ try
+ {
+ int dataEntryAddress = (int)EVORE.ConvertVirtualAddress(rdte.DataEntryOffset, sections);
+ if (dataEntryAddress > 0)
+ {
+ stream.Seek(dataEntryAddress, SeekOrigin.Begin);
+ rdte.DataEntry = ResourceDataEntry.Deserialize(stream);
+ }
+ }
+ catch { }
+ finally
+ {
+ stream.Seek(lastPosition, SeekOrigin.Begin);
+ }
+ }
+
+ // TODO: Add parsing for further directory table entries in the tree
+
+ return rdte;
}
- public static ResourceDirectoryTableEntry Deserialize(byte[] content, int offset)
+ public static ResourceDirectoryTableEntry Deserialize(byte[] content, int offset, SectionHeader[] sections)
{
- var idte = new ResourceDirectoryTableEntry();
+ var rdte = new ResourceDirectoryTableEntry();
- idte.NameOffset = BitConverter.ToUInt32(content, offset); offset += 4;
- idte.DataEntryOffset = BitConverter.ToUInt32(content, offset); offset += 4;
+ rdte.NameOffset = BitConverter.ToUInt32(content, offset); offset += 4;
+ rdte.DataEntryOffset = BitConverter.ToUInt32(content, offset); offset += 4;
- return idte;
+ // Read in the data if we have a leaf
+ if (rdte.IsResourceDataEntry())
+ {
+ try
+ {
+ int dataEntryAddress = (int)EVORE.ConvertVirtualAddress(rdte.DataEntryOffset, sections);
+ if (dataEntryAddress > 0)
+ rdte.DataEntry = ResourceDataEntry.Deserialize(content, dataEntryAddress);
+ }
+ catch { }
+ }
+
+ // TODO: Add parsing for further directory table entries in the tree
+
+ return rdte;
}
}
}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/IMAGE_RESOURCE_DATA_ENTRY.cs b/BurnOutSharp/ExecutableType/Microsoft/IMAGE_RESOURCE_DATA_ENTRY.cs
deleted file mode 100644
index 5f17f779..00000000
--- a/BurnOutSharp/ExecutableType/Microsoft/IMAGE_RESOURCE_DATA_ENTRY.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * NEWEXE.H (C) Copyright Microsoft Corp 1984-1987
- *
- * Data structure definitions for the OS/2 & Windows
- * executable file format.
- *
- * Modified by IVS on 24-Jan-1991 for Resource DeCompiler
- * (C) Copyright IVS 1991
- *
- * http://csn.ul.ie/~caolan/pub/winresdump/winresdump/newexe.h
- */
-
-using System.IO;
-using System.Runtime.InteropServices;
-using BurnOutSharp.Tools;
-
-namespace BurnOutSharp.ExecutableType.Microsoft
-{
- [StructLayout(LayoutKind.Sequential)]
- internal class IMAGE_RESOURCE_DATA_ENTRY
- {
- public uint OffsetToData;
- public uint Size;
- public uint CodePage;
- public uint Reserved;
-
- public static IMAGE_RESOURCE_DATA_ENTRY Deserialize(Stream stream)
- {
- var irde = new IMAGE_RESOURCE_DATA_ENTRY();
-
- irde.OffsetToData = stream.ReadUInt32();
- irde.Size = stream.ReadUInt32();
- irde.CodePage = stream.ReadUInt32();
- irde.Reserved = stream.ReadUInt32();
-
- return irde;
- }
- }
-}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/IMAGE_RESOURCE_DIRECTORY_ENTRY.cs b/BurnOutSharp/ExecutableType/Microsoft/IMAGE_RESOURCE_DIRECTORY_ENTRY.cs
deleted file mode 100644
index 37b20382..00000000
--- a/BurnOutSharp/ExecutableType/Microsoft/IMAGE_RESOURCE_DIRECTORY_ENTRY.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * NEWEXE.H (C) Copyright Microsoft Corp 1984-1987
- *
- * Data structure definitions for the OS/2 & Windows
- * executable file format.
- *
- * Modified by IVS on 24-Jan-1991 for Resource DeCompiler
- * (C) Copyright IVS 1991
- *
- * http://csn.ul.ie/~caolan/pub/winresdump/winresdump/newexe.h
- */
-
-using System.IO;
-using System.Runtime.InteropServices;
-using BurnOutSharp.Tools;
-
-namespace BurnOutSharp.ExecutableType.Microsoft
-{
- [StructLayout(LayoutKind.Sequential)]
- internal class IMAGE_RESOURCE_DIRECTORY_ENTRY
- {
- public uint Name;
- public uint OffsetToData;
-
- public static IMAGE_RESOURCE_DIRECTORY_ENTRY Deserialize(Stream stream)
- {
- var irde = new IMAGE_RESOURCE_DIRECTORY_ENTRY();
-
- irde.Name = stream.ReadUInt32();
- irde.OffsetToData = stream.ReadUInt32();
-
- return irde;
- }
- }
-}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs b/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs
index b73b3aa1..b1beaf31 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs
@@ -2,6 +2,7 @@ using System.IO;
using System.Runtime.InteropServices;
using BurnOutSharp.ExecutableType.Microsoft.Headers;
using BurnOutSharp.ExecutableType.Microsoft.Sections;
+using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft
{
@@ -92,7 +93,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft
pex.SectionTable[i] = SectionHeader.Deserialize(stream);
}
- // TODO: Uncomment these when all directories are understod and implemented
+ // TODO: Uncomment these as the directories are understod and implemented
// // Export Table
// var table = pex.SectionTable[(byte)ImageDirectory.IMAGE_DIRECTORY_ENTRY_EXPORT];
// if (table.VirtualSize > 0)
@@ -103,16 +104,26 @@ namespace BurnOutSharp.ExecutableType.Microsoft
// }
// // Import Table
- // table = pex.SectionHeaders[(byte)ImageDirectory.IMAGE_DIRECTORY_ENTRY_IMPORT];
+ // table = pex.SectionTable[(byte)ImageDirectory.IMAGE_DIRECTORY_ENTRY_IMPORT];
// if (table.VirtualSize > 0)
// {
- // int tableAddress = (int)EVORE.ConvertVirtualAddress(table.VirtualAddress, pex.SectionHeaders);
+ // int tableAddress = (int)EVORE.ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
// stream.Seek(tableAddress, SeekOrigin.Begin);
// pex.ImportTable = ImportDataSection.Deserialize(stream, pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus, hintCount: 0); // TODO: Figure out where this count comes from
// }
+
+ // // Resource Table
+ // var table = pex.SectionTable[(byte)ImageDirectory.IMAGE_DIRECTORY_ENTRY_RESOURCE];
+ // if (table.VirtualSize > 0)
+ // {
+ // int tableAddress = (int)EVORE.ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
+ // stream.Seek(tableAddress, SeekOrigin.Begin);
+ // pex.ResourceSection = ResourceSection.Deserialize(stream, pex.SectionTable);
+ // }
}
- catch
+ catch (System.Exception ex)
{
+ System.Console.WriteLine($"Errored out on a file: {ex}");
return null;
}
@@ -140,7 +151,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft
pex.SectionTable[i] = SectionHeader.Deserialize(content, offset); offset += 40;
}
- // TODO: Uncomment these when all directories are understod and implemented
+ // TODO: Uncomment these as the directories are understod and implemented
// // Export Table
// var table = pex.SectionTable[(byte)ImageDirectory.IMAGE_DIRECTORY_ENTRY_EXPORT];
// if (table.VirtualSize > 0)
@@ -150,16 +161,25 @@ namespace BurnOutSharp.ExecutableType.Microsoft
// }
// // Import Table
- // table = pex.SectionHeaders[(byte)ImageDirectory.IMAGE_DIRECTORY_ENTRY_IMPORT];
+ // table = pex.SectionTable[(byte)ImageDirectory.IMAGE_DIRECTORY_ENTRY_IMPORT];
// if (table.VirtualSize > 0)
// {
- // int tableAddress = (int)EVORE.ConvertVirtualAddress(table.VirtualAddress, pex.SectionHeaders);
- // pex.ImportTable = ImportDataSection.Deserialize(content, tableAddress, pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus, hintCount: 0); offset += Marshal.SizeOf(pex.ImportTable); // TODO: Figure out where this count comes from
+ // int tableAddress = (int)EVORE.ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
+ // pex.ImportTable = ImportDataSection.Deserialize(content, tableAddress, pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus, hintCount: 0);
+ // }
+
+ // // Resource Table
+ // var table = pex.SectionTable[(byte)ImageDirectory.IMAGE_DIRECTORY_ENTRY_RESOURCE];
+ // if (table.VirtualSize > 0)
+ // {
+ // int tableAddress = (int)EVORE.ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
+ // pex.ResourceSection = ResourceSection.Deserialize(content, tableAddress, pex.SectionTable);
// }
}
}
- catch
+ catch (System.Exception ex)
{
+ System.Console.WriteLine($"Errored out on a file: {ex}");
return null;
}
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Sections/ResourceSection.cs b/BurnOutSharp/ExecutableType/Microsoft/Sections/ResourceSection.cs
index 95744587..134bada8 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Sections/ResourceSection.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Sections/ResourceSection.cs
@@ -1,5 +1,6 @@
using System.IO;
using System.Runtime.InteropServices;
+using BurnOutSharp.ExecutableType.Microsoft.Headers;
using BurnOutSharp.ExecutableType.Microsoft.Tables;
namespace BurnOutSharp.ExecutableType.Microsoft.Sections
@@ -21,22 +22,22 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Sections
///
public ResourceDirectoryTable ResourceDirectoryTable;
- public static ResourceSection Deserialize(Stream stream)
+ public static ResourceSection Deserialize(Stream stream, SectionHeader[] sections)
{
var rs = new ResourceSection();
- rs.ResourceDirectoryTable = ResourceDirectoryTable.Deserialize(stream);
+ rs.ResourceDirectoryTable = ResourceDirectoryTable.Deserialize(stream, sections);
return rs;
}
- public static ResourceSection Deserialize(byte[] content, int offset)
+ public static ResourceSection Deserialize(byte[] content, int offset, SectionHeader[] sections)
{
var rs = new ResourceSection();
unsafe
{
- rs.ResourceDirectoryTable = ResourceDirectoryTable.Deserialize(content, offset); offset += Marshal.SizeOf(rs.ResourceDirectoryTable);
+ rs.ResourceDirectoryTable = ResourceDirectoryTable.Deserialize(content, offset, sections); offset += Marshal.SizeOf(rs.ResourceDirectoryTable);
}
return rs;
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/ResourceDirectoryTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/ResourceDirectoryTable.cs
index 2ff99503..411e261b 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/ResourceDirectoryTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/ResourceDirectoryTable.cs
@@ -2,6 +2,7 @@ using System;
using System.IO;
using System.Runtime.InteropServices;
using BurnOutSharp.ExecutableType.Microsoft.Entries;
+using BurnOutSharp.ExecutableType.Microsoft.Headers;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Tables
@@ -67,7 +68,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
// TODO: Determine how to store or reference the resource directory strings
// that immediately follow the last directory entry but before the data
- public static ResourceDirectoryTable Deserialize(Stream stream)
+ public static ResourceDirectoryTable Deserialize(Stream stream, SectionHeader[] sections)
{
var rdt = new ResourceDirectoryTable();
@@ -81,19 +82,19 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
rdt.NamedEntries = new ResourceDirectoryTableEntry[rdt.NumberOfNamedEntries];
for (int i = 0; i < rdt.NumberOfNamedEntries; i++)
{
- rdt.NamedEntries[i] = ResourceDirectoryTableEntry.Deserialize(stream);
+ rdt.NamedEntries[i] = ResourceDirectoryTableEntry.Deserialize(stream, sections);
}
rdt.IdEntries = new ResourceDirectoryTableEntry[rdt.NumberOfIdEntries];
for (int i = 0; i < rdt.NumberOfIdEntries; i++)
{
- rdt.IdEntries[i] = ResourceDirectoryTableEntry.Deserialize(stream);
+ rdt.IdEntries[i] = ResourceDirectoryTableEntry.Deserialize(stream, sections);
}
return rdt;
}
- public static ResourceDirectoryTable Deserialize(byte[] content, int offset)
+ public static ResourceDirectoryTable Deserialize(byte[] content, int offset, SectionHeader[] sections)
{
var rdt = new ResourceDirectoryTable();
@@ -107,13 +108,13 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
rdt.NamedEntries = new ResourceDirectoryTableEntry[rdt.NumberOfNamedEntries];
for (int i = 0; i < rdt.NumberOfNamedEntries; i++)
{
- rdt.NamedEntries[i] = ResourceDirectoryTableEntry.Deserialize(content, offset); offset += 8;
+ rdt.NamedEntries[i] = ResourceDirectoryTableEntry.Deserialize(content, offset, sections); offset += 8;
}
rdt.IdEntries = new ResourceDirectoryTableEntry[rdt.NumberOfIdEntries];
for (int i = 0; i < rdt.NumberOfIdEntries; i++)
{
- rdt.IdEntries[i] = ResourceDirectoryTableEntry.Deserialize(content, offset); offset += 8;
+ rdt.IdEntries[i] = ResourceDirectoryTableEntry.Deserialize(content, offset, sections); offset += 8;
}
return rdt;