diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/ExportAddressTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/ExportAddressTableEntry.cs
index 427de590..19752858 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/ExportAddressTableEntry.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/ExportAddressTableEntry.cs
@@ -35,7 +35,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return eate;
}
- public static ExportAddressTableEntry Deserialize(byte[] content, int offset)
+ public static ExportAddressTableEntry Deserialize(byte[] content, ref int offset)
{
var eate = new ExportAddressTableEntry();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/HintNameTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/HintNameTableEntry.cs
index 9500e18e..375bffc0 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/HintNameTableEntry.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/HintNameTableEntry.cs
@@ -58,7 +58,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return hnte;
}
- public static HintNameTableEntry Deserialize(byte[] content, int offset)
+ public static HintNameTableEntry Deserialize(byte[] content, ref int offset)
{
var hnte = new HintNameTableEntry();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/ImportAddressTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/ImportAddressTableEntry.cs
index c493a2ba..10c6c9a6 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/ImportAddressTableEntry.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/ImportAddressTableEntry.cs
@@ -66,7 +66,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return iate;
}
- public static ImportAddressTableEntry Deserialize(byte[] content, int offset)
+ public static ImportAddressTableEntry Deserialize(byte[] content, ref int offset)
{
var iate = new ImportAddressTableEntry();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/ImportDirectoryTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/ImportDirectoryTableEntry.cs
index 78c3bfa6..5016afb4 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/ImportDirectoryTableEntry.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/ImportDirectoryTableEntry.cs
@@ -66,7 +66,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return idte;
}
- public static ImportDirectoryTableEntry Deserialize(byte[] content, int offset)
+ public static ImportDirectoryTableEntry Deserialize(byte[] content, ref int offset)
{
var idte = new ImportDirectoryTableEntry();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/NEResourceNameString.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/NEResourceNameString.cs
index f0d3a047..05543491 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/NEResourceNameString.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/NEResourceNameString.cs
@@ -1,5 +1,4 @@
using System.IO;
-using System.Runtime.InteropServices;
using System.Text;
using BurnOutSharp.Tools;
@@ -8,7 +7,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
///
/// Resource type and name strings
///
- [StructLayout(LayoutKind.Sequential)]
internal class NEResourceNameString
{
///
@@ -33,12 +31,12 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return rds;
}
- public static NEResourceNameString Deserialize(byte[] contents, int offset)
+ public static NEResourceNameString Deserialize(byte[] content, ref int offset)
{
var rds = new NEResourceNameString();
- rds.Length = contents[offset++];
- rds.Value = Encoding.ASCII.GetChars(contents, offset, rds.Length);
+ rds.Length = content[offset++];
+ rds.Value = Encoding.ASCII.GetChars(content, offset, rds.Length); offset += rds.Length;
return rds;
}
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/NEResourceTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/NEResourceTableEntry.cs
index aa903042..de19d2aa 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/NEResourceTableEntry.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/NEResourceTableEntry.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Entries
@@ -8,7 +7,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
///
/// A table of resources for this type
///
- [StructLayout(LayoutKind.Sequential)]
internal class NEResourceTableEntry
{
///
@@ -61,16 +59,16 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return ni;
}
- public static NEResourceTableEntry Deserialize(byte[] contents, int offset)
+ public static NEResourceTableEntry Deserialize(byte[] content, ref int offset)
{
var ni = new NEResourceTableEntry();
- ni.Offset = BitConverter.ToUInt16(contents, offset); offset += 2;
- ni.Length = BitConverter.ToUInt16(contents, offset); offset += 2;
- ni.Flags = (ResourceTableEntryFlags)BitConverter.ToUInt16(contents, offset); offset += 2;
- ni.ResourceID = BitConverter.ToUInt16(contents, offset); offset += 2;
- ni.Handle = BitConverter.ToUInt16(contents, offset); offset += 2;
- ni.Usage = BitConverter.ToUInt16(contents, offset); offset += 2;
+ ni.Offset = BitConverter.ToUInt16(content, offset); offset += 2;
+ ni.Length = BitConverter.ToUInt16(content, offset); offset += 2;
+ ni.Flags = (ResourceTableEntryFlags)BitConverter.ToUInt16(content, offset); offset += 2;
+ ni.ResourceID = BitConverter.ToUInt16(content, offset); offset += 2;
+ ni.Handle = BitConverter.ToUInt16(content, offset); offset += 2;
+ ni.Usage = BitConverter.ToUInt16(content, offset); offset += 2;
return ni;
}
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/NESegmentTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/NESegmentTableEntry.cs
index 60659630..e11f6dae 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/NESegmentTableEntry.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/NESegmentTableEntry.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Entries
@@ -11,7 +10,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
/// EXE header. The first entry in the segment table is segment number 1.
/// The following is the structure of a segment table entry.
///
- [StructLayout(LayoutKind.Sequential)]
internal class NESegmentTableEntry
{
///
@@ -49,7 +47,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return nste;
}
- public static NESegmentTableEntry Deserialize(byte[] content, int offset)
+ public static NESegmentTableEntry Deserialize(byte[] content, ref int offset)
{
var nste = new NESegmentTableEntry();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDataEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDataEntry.cs
index 67d395db..d0700794 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDataEntry.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDataEntry.cs
@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Linq;
-using System.Runtime.InteropServices;
using System.Text;
using BurnOutSharp.ExecutableType.Microsoft.Headers;
using BurnOutSharp.Tools;
@@ -11,7 +10,6 @@ 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
{
///
@@ -27,7 +25,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
///
/// A unit of resource data in the Resource Data area.
///
- public string EncodedData
+ public string DataAsUTF8String
{
get
{
@@ -38,7 +36,9 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
try
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
- return Encoding.GetEncoding(codePage).GetString(Data);
+ var originalEncoding = Encoding.GetEncoding(codePage);
+ byte[] convertedData = Encoding.Convert(originalEncoding, Encoding.UTF8, Data);
+ return Encoding.UTF8.GetString(convertedData);
}
catch (Exception ex)
{
@@ -85,7 +85,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return rde;
}
- public static ResourceDataEntry Deserialize(byte[] content, int offset, SectionHeader[] sections)
+ public static ResourceDataEntry Deserialize(byte[] content, ref int offset, SectionHeader[] sections)
{
var rde = new ResourceDataEntry();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryString.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryString.cs
index 31544743..33e150d9 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryString.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryString.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using System.Text;
using BurnOutSharp.Tools;
@@ -11,7 +10,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
/// These strings are stored together after the last Resource Directory entry and before the first Resource Data entry.
/// This minimizes the impact of these variable-length strings on the alignment of the fixed-size directory entries.
///
- [StructLayout(LayoutKind.Sequential)]
internal class ResourceDirectoryString
{
///
@@ -34,12 +32,12 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return rds;
}
- public static ResourceDirectoryString Deserialize(byte[] content, int offset)
+ public static ResourceDirectoryString Deserialize(byte[] content, ref int offset)
{
var rds = new ResourceDirectoryString();
rds.Length = BitConverter.ToUInt16(content, offset); offset += 2;
- rds.UnicodeString = Encoding.Unicode.GetString(content, offset, rds.Length);
+ rds.UnicodeString = Encoding.Unicode.GetString(content, offset, rds.Length); offset += rds.Length;
return rds;
}
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs
index af450330..fac05895 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs
@@ -111,7 +111,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return rdte;
}
- public static ResourceDirectoryTableEntry Deserialize(byte[] content, int offset, long sectionStart, SectionHeader[] sections)
+ public static ResourceDirectoryTableEntry Deserialize(byte[] content, ref int offset, long sectionStart, SectionHeader[] sections)
{
var rdte = new ResourceDirectoryTableEntry();
@@ -120,7 +120,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
{
int nameAddress = (int)(rdte.NameOffset + sectionStart);
if (nameAddress >= 0 && nameAddress < content.Length)
- rdte.Name = ResourceDirectoryString.Deserialize(content, nameAddress);
+ rdte.Name = ResourceDirectoryString.Deserialize(content, ref nameAddress);
}
rdte.DataEntryOffset = BitConverter.ToUInt32(content, offset); offset += 4;
@@ -128,13 +128,13 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
{
int dataEntryAddress = (int)(rdte.DataEntryOffset + sectionStart);
if (dataEntryAddress > 0 && dataEntryAddress < content.Length)
- rdte.DataEntry = ResourceDataEntry.Deserialize(content, dataEntryAddress, sections);
+ rdte.DataEntry = ResourceDataEntry.Deserialize(content, ref dataEntryAddress, sections);
}
else
{
int subdirectoryAddress = (int)(rdte.SubdirectoryOffset + sectionStart);
if (subdirectoryAddress > 0 && subdirectoryAddress < content.Length)
- rdte.Subdirectory = ResourceDirectoryTable.Deserialize(content, subdirectoryAddress, sectionStart, sections);
+ rdte.Subdirectory = ResourceDirectoryTable.Deserialize(content, ref subdirectoryAddress, sectionStart, sections);
}
// TODO: Add parsing for further directory table entries in the tree
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceTypeInformationBlock.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceTypeInformationBlock.cs
index 3a078632..1af0ffa1 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceTypeInformationBlock.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceTypeInformationBlock.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Entries
@@ -8,7 +7,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
///
/// Resource type information block
///
- [StructLayout(LayoutKind.Sequential)]
internal class ResourceTypeInformationBlock
{
///
@@ -52,18 +50,18 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
return rtib;
}
- public static ResourceTypeInformationBlock Deserialize(byte[] contents, int offset)
+ public static ResourceTypeInformationBlock Deserialize(byte[] content, ref int offset)
{
var rtib = new ResourceTypeInformationBlock();
- rtib.TypeID = BitConverter.ToUInt16(contents, offset); offset += 2;
- rtib.ResourceCount = BitConverter.ToUInt16(contents, offset); offset += 2;
- rtib.Reserved = BitConverter.ToUInt32(contents, offset); offset += 4;
+ rtib.TypeID = BitConverter.ToUInt16(content, offset); offset += 2;
+ rtib.ResourceCount = BitConverter.ToUInt16(content, offset); offset += 2;
+ rtib.Reserved = BitConverter.ToUInt32(content, offset); offset += 4;
rtib.ResourceTable = new NEResourceTableEntry[rtib.ResourceCount];
for (int i = 0; i < rtib.ResourceCount; i++)
{
- rtib.ResourceTable[i] = NEResourceTableEntry.Deserialize(contents, offset); offset += 12;
+ rtib.ResourceTable[i] = NEResourceTableEntry.Deserialize(content, ref offset);
}
return rtib;
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Headers/CommonObjectFileFormatHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/Headers/CommonObjectFileFormatHeader.cs
index 9445e7fe..daffcacf 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Headers/CommonObjectFileFormatHeader.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Headers/CommonObjectFileFormatHeader.cs
@@ -1,11 +1,9 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Headers
{
- [StructLayout(LayoutKind.Sequential)]
internal class CommonObjectFileFormatHeader
{
///
@@ -71,7 +69,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
return ifh;
}
- public static CommonObjectFileFormatHeader Deserialize(byte[] content, int offset)
+ public static CommonObjectFileFormatHeader Deserialize(byte[] content, ref int offset)
{
var ifh = new CommonObjectFileFormatHeader();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Headers/DataDirectoryHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/Headers/DataDirectoryHeader.cs
index 2405fe2f..287bf67d 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Headers/DataDirectoryHeader.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Headers/DataDirectoryHeader.cs
@@ -1,11 +1,9 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Headers
{
- [StructLayout(LayoutKind.Sequential)]
internal class DataDirectoryHeader
{
///
@@ -29,7 +27,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
return ddh;
}
- public static DataDirectoryHeader Deserialize(byte[] content, int offset)
+ public static DataDirectoryHeader Deserialize(byte[] content, ref int offset)
{
var ddh = new DataDirectoryHeader();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Headers/MSDOSExecutableHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/Headers/MSDOSExecutableHeader.cs
index 058dae53..259b22db 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Headers/MSDOSExecutableHeader.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Headers/MSDOSExecutableHeader.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Headers
@@ -14,7 +13,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
/// and PE executables, usually as stubs so that when they are ran under DOS, they display a warning.
///
/// https://wiki.osdev.org/MZ
- [StructLayout(LayoutKind.Sequential)]
internal class MSDOSExecutableHeader
{
#region Standard Fields
@@ -102,7 +100,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
///
/// Reserved words [1C]
///
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.ERES1WDS)]
public ushort[] Reserved1;
///
@@ -118,7 +115,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
///
/// Reserved words [28]
///
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.ERES2WDS)]
public ushort[] Reserved2;
///
@@ -168,7 +164,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
return idh;
}
- public static MSDOSExecutableHeader Deserialize(byte[] content, int offset, bool asStub = true)
+ public static MSDOSExecutableHeader Deserialize(byte[] content, ref int offset, bool asStub = true)
{
MSDOSExecutableHeader idh = new MSDOSExecutableHeader();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Headers/NewExecutableHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/Headers/NewExecutableHeader.cs
index 581eca6f..53c38f62 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Headers/NewExecutableHeader.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Headers/NewExecutableHeader.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Headers
@@ -10,7 +9,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
/// Because of the age of the format some items are unclear in meaning.
///
/// http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm
- [StructLayout(LayoutKind.Sequential)]
internal class NewExecutableHeader
{
///
@@ -216,42 +214,42 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
return neh;
}
- public static NewExecutableHeader Deserialize(byte[] contents, int offset)
+ public static NewExecutableHeader Deserialize(byte[] content, ref int offset)
{
var neh = new NewExecutableHeader();
- neh.Magic = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.LinkerVersion = contents[offset++];
- neh.LinkerRevision = contents[offset++];
- neh.EntryTableOffset = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.EntryTableSize = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.CrcChecksum = BitConverter.ToUInt32(contents, offset); offset += 4;
- neh.ProgramFlags = contents[offset++];
- neh.ApplicationFlags = contents[offset++];
- neh.Autodata = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.InitialHeapAlloc = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.InitialStackAlloc = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.InitialCSIPSetting = BitConverter.ToUInt32(contents, offset); offset += 4;
- neh.InitialSSSPSetting = BitConverter.ToUInt32(contents, offset); offset += 4;
- neh.FileSegmentCount = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.ModuleReferenceTableSize = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.NonResidentNameTableSize = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.SegmentTableOffset = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.ResourceTableOffset = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.ResidentNameTableOffset = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.ModuleReferenceTableOffset = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.ImportedNamesTableOffset = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.NonResidentNamesTableOffset = BitConverter.ToUInt32(contents, offset); offset += 4;
- neh.MovableEntriesCount = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.SegmentAlignmentShiftCount = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.ResourceEntriesCount = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.TargetOperatingSystem = contents[offset++];
- neh.AdditionalFlags = contents[offset++];
- neh.ReturnThunkOffset = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.SegmentReferenceThunkOffset = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.MinCodeSwapAreaSize = BitConverter.ToUInt16(contents, offset); offset += 2;
- neh.WindowsSDKRevision = contents[offset++];
- neh.WindowsSDKVersion = contents[offset++];
+ neh.Magic = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.LinkerVersion = content[offset++];
+ neh.LinkerRevision = content[offset++];
+ neh.EntryTableOffset = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.EntryTableSize = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.CrcChecksum = BitConverter.ToUInt32(content, offset); offset += 4;
+ neh.ProgramFlags = content[offset++];
+ neh.ApplicationFlags = content[offset++];
+ neh.Autodata = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.InitialHeapAlloc = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.InitialStackAlloc = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.InitialCSIPSetting = BitConverter.ToUInt32(content, offset); offset += 4;
+ neh.InitialSSSPSetting = BitConverter.ToUInt32(content, offset); offset += 4;
+ neh.FileSegmentCount = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.ModuleReferenceTableSize = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.NonResidentNameTableSize = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.SegmentTableOffset = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.ResourceTableOffset = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.ResidentNameTableOffset = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.ModuleReferenceTableOffset = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.ImportedNamesTableOffset = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.NonResidentNamesTableOffset = BitConverter.ToUInt32(content, offset); offset += 4;
+ neh.MovableEntriesCount = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.SegmentAlignmentShiftCount = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.ResourceEntriesCount = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.TargetOperatingSystem = content[offset++];
+ neh.AdditionalFlags = content[offset++];
+ neh.ReturnThunkOffset = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.SegmentReferenceThunkOffset = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.MinCodeSwapAreaSize = BitConverter.ToUInt16(content, offset); offset += 2;
+ neh.WindowsSDKRevision = content[offset++];
+ neh.WindowsSDKVersion = content[offset++];
return neh;
}
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Headers/OptionalHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/Headers/OptionalHeader.cs
index beefb919..838e7a0d 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Headers/OptionalHeader.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Headers/OptionalHeader.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Headers
@@ -19,7 +18,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
/// a particular data directory entry goes beyond the optional header.
/// In addition, it is important to validate the optional header magic number for format compatibility.
///
- [StructLayout(LayoutKind.Sequential)]
internal class OptionalHeader
{
#region Standard Fields
@@ -231,7 +229,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
///
/// Data-directory entries following the optional header
///
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.IMAGE_NUMBEROF_DIRECTORY_ENTRIES)]
public DataDirectoryHeader[] DataDirectories;
#endregion
@@ -301,7 +298,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
return ioh;
}
- public static OptionalHeader Deserialize(byte[] content, int offset)
+ public static OptionalHeader Deserialize(byte[] content, ref int offset)
{
var ioh = new OptionalHeader();
@@ -364,7 +361,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
ioh.DataDirectories = new DataDirectoryHeader[Constants.IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
for (int i = 0; i < Constants.IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
{
- ioh.DataDirectories[i] = DataDirectoryHeader.Deserialize(content, offset); offset += 8;
+ ioh.DataDirectories[i] = DataDirectoryHeader.Deserialize(content, ref offset);
}
return ioh;
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Headers/SectionHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/Headers/SectionHeader.cs
index 18eb2f97..77d9e887 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Headers/SectionHeader.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Headers/SectionHeader.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Headers
@@ -12,7 +11,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
/// Instead, the location of the section table is determined by calculating the location of the first byte after the headers.
/// Make sure to use the size of the optional header as specified in the file header.
///
- [StructLayout(LayoutKind.Sequential)]
internal class SectionHeader
{
///
@@ -23,7 +21,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
/// Executable images do not use a string table and do not support section names longer than 8 characters.
/// Long names in object files are truncated if they are emitted to an executable file.
///
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.IMAGE_SIZEOF_SHORT_NAME)]
public byte[] Name;
///
@@ -110,7 +107,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Headers
return ish;
}
- public static SectionHeader Deserialize(byte[] content, int offset)
+ public static SectionHeader Deserialize(byte[] content, ref int offset)
{
var ish = new SectionHeader();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/NewExecutable.cs b/BurnOutSharp/ExecutableType/Microsoft/NewExecutable.cs
index 95d78865..daf75bbe 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/NewExecutable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/NewExecutable.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.ExecutableType.Microsoft.Headers;
namespace BurnOutSharp.ExecutableType.Microsoft
@@ -41,7 +40,8 @@ namespace BurnOutSharp.ExecutableType.Microsoft
try
{
// Attempt to read the DOS header first
- nex.DOSStubHeader = MSDOSExecutableHeader.Deserialize(stream); stream.Seek(nex.DOSStubHeader.NewExeHeaderAddr, SeekOrigin.Begin);
+ nex.DOSStubHeader = MSDOSExecutableHeader.Deserialize(stream);
+ stream.Seek(nex.DOSStubHeader.NewExeHeaderAddr, SeekOrigin.Begin);
if (nex.DOSStubHeader.Magic != Constants.IMAGE_DOS_SIGNATURE)
return null;
@@ -70,22 +70,20 @@ namespace BurnOutSharp.ExecutableType.Microsoft
try
{
- unsafe
- {
- // Attempt to read the DOS header first
- nex.DOSStubHeader = MSDOSExecutableHeader.Deserialize(content, offset); offset = nex.DOSStubHeader.NewExeHeaderAddr;
- if (nex.DOSStubHeader.Magic != Constants.IMAGE_DOS_SIGNATURE)
- return null;
+ // Attempt to read the DOS header first
+ nex.DOSStubHeader = MSDOSExecutableHeader.Deserialize(content, ref offset);
+ offset = nex.DOSStubHeader.NewExeHeaderAddr;
+ if (nex.DOSStubHeader.Magic != Constants.IMAGE_DOS_SIGNATURE)
+ return null;
- // If the new header address is invalid for the file, it's not a PE
- if (nex.DOSStubHeader.NewExeHeaderAddr >= content.Length)
- return null;
+ // If the new header address is invalid for the file, it's not a PE
+ if (nex.DOSStubHeader.NewExeHeaderAddr >= content.Length)
+ return null;
- // Then attempt to read the NE header
- nex.NewExecutableHeader = NewExecutableHeader.Deserialize(content, offset); offset += Marshal.SizeOf(nex.NewExecutableHeader);
- if (nex.NewExecutableHeader.Magic != Constants.IMAGE_OS2_SIGNATURE)
- return null;
- }
+ // Then attempt to read the NE header
+ nex.NewExecutableHeader = NewExecutableHeader.Deserialize(content, ref offset);
+ if (nex.NewExecutableHeader.Magic != Constants.IMAGE_OS2_SIGNATURE)
+ return null;
}
catch (Exception ex)
{
diff --git a/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs b/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs
index d6cee7da..e01b07ac 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs
@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Linq;
-using System.Runtime.InteropServices;
using System.Text;
using BurnOutSharp.ExecutableType.Microsoft.Headers;
using BurnOutSharp.ExecutableType.Microsoft.Sections;
@@ -234,59 +233,54 @@ namespace BurnOutSharp.ExecutableType.Microsoft
try
{
- unsafe
+ // Attempt to read the DOS header first
+ pex.DOSStubHeader = MSDOSExecutableHeader.Deserialize(content, ref offset);
+ offset = pex.DOSStubHeader.NewExeHeaderAddr;
+ if (pex.DOSStubHeader.Magic != Constants.IMAGE_DOS_SIGNATURE)
+ return null;
+
+ // If the new header address is invalid for the file, it's not a PE
+ if (pex.DOSStubHeader.NewExeHeaderAddr >= content.Length)
+ return null;
+
+ // Then attempt to read the PE header
+ pex.ImageFileHeader = CommonObjectFileFormatHeader.Deserialize(content, ref offset);
+ if (pex.ImageFileHeader.Signature != Constants.IMAGE_NT_SIGNATURE)
+ return null;
+
+ // If the optional header is supposed to exist, read that as well
+ if (pex.ImageFileHeader.SizeOfOptionalHeader > 0)
+ pex.OptionalHeader = OptionalHeader.Deserialize(content, ref offset);
+
+ // Then read in the section table
+ pex.SectionTable = new SectionHeader[pex.ImageFileHeader.NumberOfSections];
+ for (int i = 0; i < pex.ImageFileHeader.NumberOfSections; i++)
{
- // Attempt to read the DOS header first
- pex.DOSStubHeader = MSDOSExecutableHeader.Deserialize(content, offset); offset = pex.DOSStubHeader.NewExeHeaderAddr;
- if (pex.DOSStubHeader.Magic != Constants.IMAGE_DOS_SIGNATURE)
- return null;
+ pex.SectionTable[i] = SectionHeader.Deserialize(content, ref offset);
+ }
- // If the new header address is invalid for the file, it's not a PE
- if (pex.DOSStubHeader.NewExeHeaderAddr >= content.Length)
- return null;
+ // // Export Table
+ // var table = pex.GetSection(".edata", true);
+ // if (table != null && table.VirtualSize > 0)
+ // {
+ // int tableAddress = (int)ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
+ // pex.ExportTable = ExportDataSection.Deserialize(content, tableAddress);
+ // }
- // Then attempt to read the PE header
- pex.ImageFileHeader = CommonObjectFileFormatHeader.Deserialize(content, offset); offset += Marshal.SizeOf(pex.ImageFileHeader);
- if (pex.ImageFileHeader.Signature != Constants.IMAGE_NT_SIGNATURE)
- return null;
+ // // Import Table
+ // table = pex.GetSection(".idata", true);
+ // if (table != null && table.VirtualSize > 0)
+ // {
+ // int tableAddress = (int)ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
+ // pex.ImportTable = ImportDataSection.Deserialize(content, tableAddress, pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus, hintCount: 0);
+ // }
- // If the optional header is supposed to exist, read that as well
- if (pex.ImageFileHeader.SizeOfOptionalHeader > 0)
- {
- pex.OptionalHeader = OptionalHeader.Deserialize(content, offset);
- offset += pex.ImageFileHeader.SizeOfOptionalHeader;
- }
-
- // Then read in the section table
- pex.SectionTable = new SectionHeader[pex.ImageFileHeader.NumberOfSections];
- for (int i = 0; i < pex.ImageFileHeader.NumberOfSections; i++)
- {
- pex.SectionTable[i] = SectionHeader.Deserialize(content, offset); offset += 40;
- }
-
- // // Export Table
- // var table = pex.GetSection(".edata", true);
- // if (table != null && table.VirtualSize > 0)
- // {
- // int tableAddress = (int)ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
- // pex.ExportTable = ExportDataSection.Deserialize(content, tableAddress);
- // }
-
- // // Import Table
- // table = pex.GetSection(".idata", true);
- // if (table != null && table.VirtualSize > 0)
- // {
- // int tableAddress = (int)ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
- // pex.ImportTable = ImportDataSection.Deserialize(content, tableAddress, pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus, hintCount: 0);
- // }
-
- // Resource Table
- var table = pex.GetSection(".rsrc", true);
- if (table != null && table.VirtualSize > 0)
- {
- int tableAddress = (int)ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
- pex.ResourceSection = ResourceSection.Deserialize(content, tableAddress, pex.SectionTable);
- }
+ // Resource Table
+ var table = pex.GetSection(".rsrc", true);
+ if (table != null && table.VirtualSize > 0)
+ {
+ int tableAddress = (int)ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
+ pex.ResourceSection = ResourceSection.Deserialize(content, ref tableAddress, pex.SectionTable);
}
}
catch (Exception ex)
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/FixedFileInfo.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/FixedFileInfo.cs
new file mode 100644
index 00000000..026cd20d
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/Resources/FixedFileInfo.cs
@@ -0,0 +1,202 @@
+using System;
+using System.IO;
+using BurnOutSharp.Tools;
+
+namespace BurnOutSharp.ExecutableType.Microsoft.Resources
+{
+ internal class FixedFileInfo
+ {
+ ///
+ /// Contains the value 0xFEEF04BD.
+ /// This is used with the szKey member of the VS_VERSIONINFO structure when searching a file for the VS_FIXEDFILEINFO structure.
+ ///
+ public uint Signature;
+
+ ///
+ /// The binary version number of this structure.
+ /// The high-order word of this member contains the major version number, and the low-order word contains the minor version number.
+ ///
+ public uint StrucVersion;
+
+ ///
+ /// The most significant 32 bits of the file's binary version number.
+ /// This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons.
+ ///
+ public uint FileVersionMS;
+
+ ///
+ /// The least significant 32 bits of the file's binary version number.
+ /// This member is used with dwFileVersionMS to form a 64-bit value used for numeric comparisons.
+ ///
+ public uint FileVersionLS;
+
+ ///
+ /// The most significant 32 bits of the binary version number of the product with which this file was distributed.
+ /// This member is used with dwProductVersionLS to form a 64-bit value used for numeric comparisons.
+ ///
+ public uint ProductVersionMS;
+
+ ///
+ /// The least significant 32 bits of the binary version number of the product with which this file was distributed.
+ /// This member is used with dwProductVersionMS to form a 64-bit value used for numeric comparisons.
+ ///
+ public uint ProductVersionLS;
+
+ ///
+ /// Contains a bitmask that specifies the valid bits in dwFileFlags.
+ /// A bit is valid only if it was defined when the file was created.
+ ///
+ public uint FileFlagsMask;
+
+ ///
+ /// Contains a bitmask that specifies the Boolean attributes of the file. This member can include one or more of the following values.
+ ///
+ /// VS_FF_DEBUG (0x00000001L) The file contains debugging information or is compiled with debugging features enabled.
+ /// VS_FF_INFOINFERRED (0x00000010L) The file's version structure was created dynamically; therefore, some of the members in this structure may be empty or incorrect. This flag should never be set in a file's VS_VERSIONINFO data.
+ /// VS_FF_PATCHED (0x00000004L) The file has been modified and is not identical to the original shipping file of the same version number.
+ /// VS_FF_PRERELEASE (0x00000002L) The file is a development version, not a commercially released product.
+ /// VS_FF_PRIVATEBUILD (0x00000008L) The file was not built using standard release procedures. If this flag is set, the StringFileInfo structure should contain a PrivateBuild entry.
+ /// VS_FF_SPECIALBUILD (0x00000020L) The file was built by the original company using standard release procedures but is a variation of the normal file of the same version number. If this flag is set, the StringFileInfo structure should contain a SpecialBuild entry.
+ ///
+ /// TODO: Make an enum out of this
+ public uint FileFlags;
+
+ ///
+ /// The operating system for which this file was designed. This member can be one of the following values.
+ ///
+ /// VOS_DOS (0x00010000L) The file was designed for MS-DOS.
+ /// VOS_NT (0x00040000L) The file was designed for Windows NT.
+ /// VOS__WINDOWS16 (0x00000001L) The file was designed for 16-bit Windows.
+ /// VOS__WINDOWS32 (0x00000004L) The file was designed for 32-bit Windows.
+ /// VOS_OS216 (0x00020000L) The file was designed for 16-bit OS/2.
+ /// VOS_OS232 (0x00030000L) The file was designed for 32-bit OS/2.
+ /// VOS__PM16 (0x00000002L) The file was designed for 16-bit Presentation Manager.
+ /// VOS__PM32 (0x00000003L) The file was designed for 32-bit Presentation Manager.
+ /// VOS_UNKNOWN (0x00000000L) The operating system for which the file was designed is unknown to the system.
+ ///
+ /// An application can combine these values to indicate that the file was designed for one operating system running on another.
+ /// The following dwFileOS values are examples of this, but are not a complete list.
+ ///
+ /// VOS_DOS_WINDOWS16 (0x00010001L) The file was designed for 16-bit Windows running on MS-DOS.
+ /// VOS_DOS_WINDOWS32 (0x00010004L) The file was designed for 32-bit Windows running on MS-DOS.
+ /// VOS_NT_WINDOWS32 (0x00040004L) The file was designed for Windows NT.
+ /// VOS_OS216_PM16 (0x00020002L) The file was designed for 16-bit Presentation Manager running on 16-bit OS/2.
+ /// VOS_OS232_PM32 (0x00030003L) The file was designed for 32-bit Presentation Manager running on 32-bit OS/2.
+ ///
+ /// TODO: Make an enum out of this
+ public uint FileOS;
+
+ ///
+ /// The general type of file. This member can be one of the following values. All other values are reserved.
+ ///
+ /// VFT_APP (0x00000001L) The file contains an application.
+ /// VFT_DLL (0x00000002L) The file contains a DLL.
+ /// VFT_DRV (0x00000003L) The file contains a device driver. If dwFileType is VFT_DRV, dwFileSubtype contains a more specific description of the driver.
+ /// VFT_FONT (0x00000004L) The file contains a font. If dwFileType is VFT_FONT, dwFileSubtype contains a more specific description of the font file.
+ /// VFT_STATIC_LIB (0x00000007L) The file contains a static-link library.
+ /// VFT_UNKNOWN (0x00000000L) The file type is unknown to the system.
+ /// VFT_VXD (0x00000005L) The file contains a virtual device.
+ ///
+ /// TODO: Make an enum out of this
+ public uint FileType;
+
+ ///
+ /// The function of the file. The possible values depend on the value of dwFileType.
+ /// For all values of dwFileType not described in the following list, dwFileSubtype is zero.
+ ///
+ /// If dwFileType is VFT_DRV, dwFileSubtype can be one of the following values.
+ ///
+ /// VFT2_DRV_COMM (0x0000000AL) The file contains a communications driver.
+ /// VFT2_DRV_DISPLAY (0x00000004L) The file contains a display driver.
+ /// VFT2_DRV_INSTALLABLE (0x00000008L) The file contains an installable driver.
+ /// VFT2_DRV_KEYBOARD (0x00000002L) The file contains a keyboard driver.
+ /// VFT2_DRV_LANGUAGE (0x00000003L) The file contains a language driver.
+ /// VFT2_DRV_MOUSE (0x00000005L) The file contains a mouse driver.
+ /// VFT2_DRV_NETWORK (0x00000006L) The file contains a network driver.
+ /// VFT2_DRV_PRINTER (0x00000001L) The file contains a printer driver.
+ /// VFT2_DRV_SOUND (0x00000009L) The file contains a sound driver.
+ /// VFT2_DRV_SYSTEM (0x00000007L) The file contains a system driver.
+ /// VFT2_DRV_VERSIONED_PRINTER (0x0000000CL) The file contains a versioned printer driver.
+ /// VFT2_UNKNOWN (0x00000000L) The driver type is unknown by the system.
+ ///
+ /// If dwFileType is VFT_FONT, dwFileSubtype can be one of the following values.
+ ///
+ /// VFT2_FONT_RASTER (0x00000001L) The file contains a raster font.
+ /// VFT2_FONT_TRUETYPE (0x00000003L) The file contains a TrueType font.
+ /// VFT2_FONT_VECTOR (0x00000002L) The file contains a vector font.
+ /// VFT2_UNKNOWN (0x00000000L) The font type is unknown by the system.
+ ///
+ /// If dwFileType is VFT_VXD, dwFileSubtype contains the virtual device identifier included in the virtual device control block.
+ /// All dwFileSubtype values not listed here are reserved.
+ ///
+ /// TODO: Make an enum out of this
+ public uint FileSubtype;
+
+ ///
+ /// The most significant 32 bits of the file's 64-bit binary creation date and time stamp.
+ ///
+ public uint FileDateMS;
+
+ ///
+ /// The least significant 32 bits of the file's 64-bit binary creation date and time stamp.
+ ///
+ public uint FileDateLS;
+
+ public static FixedFileInfo Deserialize(Stream stream)
+ {
+ FixedFileInfo ffi = new FixedFileInfo();
+
+ ushort temp;
+ while ((temp = stream.ReadUInt16()) == 0x0000);
+ stream.Seek(-2, SeekOrigin.Current);
+
+ ffi.Signature = stream.ReadUInt32();
+ ffi.StrucVersion = stream.ReadUInt32();
+ ffi.FileVersionMS = stream.ReadUInt32();
+ ffi.FileVersionLS = stream.ReadUInt32();
+ ffi.ProductVersionMS = stream.ReadUInt32();
+ ffi.ProductVersionLS = stream.ReadUInt32();
+ ffi.FileFlagsMask = stream.ReadUInt32();
+ ffi.FileFlags = stream.ReadUInt32();
+ ffi.FileOS = stream.ReadUInt32();
+ ffi.FileType = stream.ReadUInt32();
+ ffi.FileSubtype = stream.ReadUInt32();
+ ffi.FileDateMS = stream.ReadUInt32();
+ ffi.FileDateLS = stream.ReadUInt32();
+
+ return ffi;
+ }
+
+ public static FixedFileInfo Deserialize(byte[] content, ref int offset)
+ {
+ FixedFileInfo ffi = new FixedFileInfo();
+
+ ushort temp;
+ bool padded = false;
+ while ((temp = BitConverter.ToUInt16(content, offset)) == 0x0000)
+ {
+ offset += 2;
+ padded = true;
+ }
+
+ if (padded)
+ offset -= 2;
+
+ ffi.Signature = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.StrucVersion = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.FileVersionMS = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.FileVersionLS = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.ProductVersionMS = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.ProductVersionLS = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.FileFlagsMask = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.FileFlags = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.FileOS = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.FileType = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.FileSubtype = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.FileDateMS = BitConverter.ToUInt32(content, offset); offset += 4;
+ ffi.FileDateLS = BitConverter.ToUInt32(content, offset); offset += 4;
+
+ return ffi;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/LanguageCodePage.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/LanguageCodePage.cs
new file mode 100644
index 00000000..5919937a
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/Resources/LanguageCodePage.cs
@@ -0,0 +1,46 @@
+using System;
+using System.IO;
+using BurnOutSharp.Tools;
+
+namespace BurnOutSharp.ExecutableType.Microsoft.Resources
+{
+ ///
+ /// If you use the Var structure to list the languages your application or DLL supports instead of using multiple version resources,
+ /// use the Value member to contain an array of DWORD values indicating the language and code page combinations supported by this file.
+ /// The low-order word of each DWORD must contain a Microsoft language identifier, and the high-order word must contain the IBM code page number.
+ /// Either high-order or low-order word can be zero, indicating that the file is language or code page independent.
+ /// If the Var structure is omitted, the file will be interpreted as both language and code page independent.
+ ///
+ internal class LanguageCodePage
+ {
+ ///
+ /// The low-order word of each DWORD must contain a Microsoft language identifier
+ ///
+ public ushort MicrosoftLanguageIdentifier;
+
+ ///
+ /// The high-order word must contain the IBM code page number
+ ///
+ public ushort IBMCodePageNumber;
+
+ public static LanguageCodePage Deserialize(Stream stream)
+ {
+ LanguageCodePage lcp = new LanguageCodePage();
+
+ lcp.MicrosoftLanguageIdentifier = stream.ReadUInt16();
+ lcp.IBMCodePageNumber = stream.ReadUInt16();
+
+ return lcp;
+ }
+
+ public static LanguageCodePage Deserialize(byte[] content, ref int offset)
+ {
+ LanguageCodePage lcp = new LanguageCodePage();
+
+ lcp.MicrosoftLanguageIdentifier = BitConverter.ToUInt16(content, offset); offset += 2;
+ lcp.IBMCodePageNumber = BitConverter.ToUInt16(content, offset); offset += 2;
+
+ return lcp;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/Resource.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/Resource.cs
new file mode 100644
index 00000000..fbd65b4e
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/Resources/Resource.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using BurnOutSharp.Tools;
+
+namespace BurnOutSharp.ExecutableType.Microsoft.Resources
+{
+ internal class Resource
+ {
+ ///
+ /// The length, in bytes, of the resource structure.
+ /// This length does not include any padding that aligns any subsequent version resource data on a 32-bit boundary.
+ ///
+ public ushort Length;
+
+ ///
+ /// The length, in bytes, of the Value member.
+ /// This value is zero if there is no Value member associated with the current version structure.
+ ///
+ public ushort ValueLength;
+
+ ///
+ /// The type of data in the version resource.
+ /// This member is 1 if the version resource contains text data and 0 if the version resource contains binary data.
+ ///
+ public ushort Type;
+
+ ///
+ /// A Unicode string representing the key
+ ///
+ public string Key;
+
+ public static Resource Deserialize(Stream stream)
+ {
+ Resource r = new Resource();
+
+ while ((r.Length = stream.ReadUInt16()) == 0x0000);
+
+ r.Length = stream.ReadUInt16();
+ r.ValueLength = stream.ReadUInt16();
+ r.Type = stream.ReadUInt16();
+ r.Key = stream.ReadString(Encoding.Unicode);
+
+ return r;
+ }
+
+ public static Resource Deserialize(byte[] content, ref int offset)
+ {
+ Resource r = new Resource();
+
+ while ((r.Length = BitConverter.ToUInt16(content, offset)) == 0x0000)
+ {
+ offset += 2;
+ }
+
+ offset += 2;
+ r.ValueLength = BitConverter.ToUInt16(content, offset); offset += 2;
+ r.Type = BitConverter.ToUInt16(content, offset); offset += 2;
+
+ List keyChars = new List();
+ while (BitConverter.ToUInt16(content, offset) != 0x0000)
+ {
+ keyChars.Add(Encoding.Unicode.GetChars(content, offset, 2)[0]); offset += 2;
+ }
+ offset += 2;
+
+ r.Key = new string(keyChars.ToArray());
+
+ return r;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/StringFileInfo.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/StringFileInfo.cs
new file mode 100644
index 00000000..b0f35128
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/Resources/StringFileInfo.cs
@@ -0,0 +1,49 @@
+using System;
+using System.IO;
+using BurnOutSharp.Tools;
+
+namespace BurnOutSharp.ExecutableType.Microsoft.Resources
+{
+ internal class StringFileInfo : Resource
+ {
+ ///
+ /// An array of one or more StringTable structures.
+ /// Each StringTable structure's szKey member indicates the appropriate language and code page for displaying the text in that StringTable structure.
+ ///
+ public StringTable Children;
+
+ public static new StringFileInfo Deserialize(Stream stream)
+ {
+ StringFileInfo sfi = new StringFileInfo();
+
+ Resource resource = Resource.Deserialize(stream);
+ if (resource.Key != "StringFileInfo")
+ return null;
+
+ sfi.Length = resource.Length;
+ sfi.ValueLength = resource.ValueLength;
+ sfi.Type = resource.Type;
+ sfi.Key = resource.Key;
+ sfi.Children = StringTable.Deserialize(stream);
+
+ return sfi;
+ }
+
+ public static new StringFileInfo Deserialize(byte[] content, ref int offset)
+ {
+ StringFileInfo sfi = new StringFileInfo();
+
+ Resource resource = Resource.Deserialize(content, ref offset);
+ if (resource.Key != "StringFileInfo")
+ return null;
+
+ sfi.Length = resource.Length;
+ sfi.ValueLength = resource.ValueLength;
+ sfi.Type = resource.Type;
+ sfi.Key = resource.Key;
+ sfi.Children = StringTable.Deserialize(content, ref offset);
+
+ return sfi;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/StringStruct.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/StringStruct.cs
new file mode 100644
index 00000000..1f1d4033
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/Resources/StringStruct.cs
@@ -0,0 +1,47 @@
+using System;
+using System.IO;
+using System.Text;
+using BurnOutSharp.Tools;
+
+namespace BurnOutSharp.ExecutableType.Microsoft.Resources
+{
+ internal class StringStruct : Resource
+ {
+ ///
+ /// Typically contains a list of languages that the application or DLL supports.
+ ///
+ public string Value;
+
+ public static new StringStruct Deserialize(Stream stream)
+ {
+ StringStruct s = new StringStruct();
+
+ Resource resource = Resource.Deserialize(stream);
+
+ s.Length = resource.Length;
+ s.ValueLength = resource.ValueLength;
+ s.Type = resource.Type;
+ s.Key = resource.Key;
+ stream.Seek(stream.Position % 4 == 0 ? 0 : 4 - (stream.Position % 4), SeekOrigin.Current);
+ s.Value = new string(stream.ReadChars(s.ValueLength));
+
+ return s;
+ }
+
+ public static new StringStruct Deserialize(byte[] content, ref int offset)
+ {
+ StringStruct s = new StringStruct();
+
+ Resource resource = Resource.Deserialize(content, ref offset);
+
+ s.Length = resource.Length;
+ s.ValueLength = resource.ValueLength;
+ s.Type = resource.Type;
+ s.Key = resource.Key;
+ offset += offset % 4 == 0 ? 0 : 4 - (offset % 4);
+ s.Value = Encoding.Unicode.GetString(content, offset, s.ValueLength * 2); offset += s.ValueLength * 2;
+
+ return s;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/StringTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/StringTable.cs
new file mode 100644
index 00000000..3ecdc06d
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/Resources/StringTable.cs
@@ -0,0 +1,57 @@
+using System.Collections.Generic;
+using System.IO;
+
+namespace BurnOutSharp.ExecutableType.Microsoft.Resources
+{
+ internal class StringTable : Resource
+ {
+ ///
+ /// An array of one or more String structures.
+ ///
+ public StringStruct[] Children;
+
+ public static new StringTable Deserialize(Stream stream)
+ {
+ StringTable st = new StringTable();
+
+ Resource resource = Resource.Deserialize(stream);
+ if (resource.Key.Length != 8)
+ return null;
+
+ st.Length = resource.Length;
+ st.ValueLength = resource.ValueLength;
+ st.Type = resource.Type;
+ st.Key = resource.Key;
+
+ // TODO: Deserialize the Value array
+ stream.Seek(st.Length - 6 - (st.Key.Length * 2), SeekOrigin.Begin);
+
+ return st;
+ }
+
+ public static new StringTable Deserialize(byte[] content, ref int offset)
+ {
+ int originalPosition = offset;
+ StringTable st = new StringTable();
+
+ Resource resource = Resource.Deserialize(content, ref offset);
+ if (resource.Key.Length != 8)
+ return null;
+
+ st.Length = resource.Length;
+ st.ValueLength = resource.ValueLength;
+ st.Type = resource.Type;
+ st.Key = resource.Key;
+
+ var tempValue = new List();
+ while (offset - originalPosition < st.Length)
+ {
+ tempValue.Add(StringStruct.Deserialize(content, ref offset));
+ }
+
+ st.Children = tempValue.ToArray();
+
+ return st;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/Var.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/Var.cs
new file mode 100644
index 00000000..51caea47
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/Resources/Var.cs
@@ -0,0 +1,56 @@
+using System;
+using System.IO;
+using BurnOutSharp.Tools;
+
+namespace BurnOutSharp.ExecutableType.Microsoft.Resources
+{
+ internal class Var : Resource
+ {
+ ///
+ /// An array of one or more values that are language and code page identifier pairs.
+ ///
+ /// If you use the Var structure to list the languages your application or DLL supports instead of using multiple version resources,
+ /// use the Value member to contain an array of DWORD values indicating the language and code page combinations supported by this file.
+ /// The low-order word of each DWORD must contain a Microsoft language identifier, and the high-order word must contain the IBM code page number.
+ /// Either high-order or low-order word can be zero, indicating that the file is language or code page independent.
+ /// If the Var structure is omitted, the file will be interpreted as both language and code page independent.
+ ///
+ public LanguageCodePage[] Value;
+
+ public static new Var Deserialize(Stream stream)
+ {
+ Var v = new Var();
+
+ Resource resource = Resource.Deserialize(stream);
+ if (resource.Key != "Translation")
+ return null;
+
+ v.Length = resource.Length;
+ v.ValueLength = resource.ValueLength;
+ v.Type = resource.Type;
+ v.Key = resource.Key;
+
+ // TODO: Deserialize the Value array
+
+ return v;
+ }
+
+ public static new Var Deserialize(byte[] content, ref int offset)
+ {
+ Var v = new Var();
+
+ Resource resource = Resource.Deserialize(content, ref offset);
+ if (resource.Key != "Translation")
+ return null;
+
+ v.Length = resource.Length;
+ v.ValueLength = resource.ValueLength;
+ v.Type = resource.Type;
+ v.Key = resource.Key;
+
+ // TODO: Deserialize the Value array
+
+ return v;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/VarFileInfo.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/VarFileInfo.cs
new file mode 100644
index 00000000..0952cae3
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/Resources/VarFileInfo.cs
@@ -0,0 +1,48 @@
+using System;
+using System.IO;
+using BurnOutSharp.Tools;
+
+namespace BurnOutSharp.ExecutableType.Microsoft.Resources
+{
+ internal class VarFileInfo : Resource
+ {
+ ///
+ /// Typically contains a list of languages that the application or DLL supports.
+ ///
+ public Var Children;
+
+ public static new VarFileInfo Deserialize(Stream stream)
+ {
+ VarFileInfo vfi = new VarFileInfo();
+
+ Resource resource = Resource.Deserialize(stream);
+ if (resource.Key != "VarFileInfo")
+ return null;
+
+ vfi.Length = resource.Length;
+ vfi.ValueLength = resource.ValueLength;
+ vfi.Type = resource.Type;
+ vfi.Key = resource.Key;
+ vfi.Children = Var.Deserialize(stream);
+
+ return vfi;
+ }
+
+ public static new VarFileInfo Deserialize(byte[] content, ref int offset)
+ {
+ VarFileInfo vfi = new VarFileInfo();
+
+ Resource resource = Resource.Deserialize(content, ref offset);
+ if (resource.Key != "VarFileInfo")
+ return null;
+
+ vfi.Length = resource.Length;
+ vfi.ValueLength = resource.ValueLength;
+ vfi.Type = resource.Type;
+ vfi.Key = resource.Key;
+ vfi.Children = Var.Deserialize(content, ref offset);
+
+ return vfi;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/VersionInfo.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/VersionInfo.cs
new file mode 100644
index 00000000..cc6466a7
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/Resources/VersionInfo.cs
@@ -0,0 +1,131 @@
+using System.IO;
+
+namespace BurnOutSharp.ExecutableType.Microsoft.Resources
+{
+ internal class VersionInfo : Resource
+ {
+ ///
+ /// Arbitrary data associated with this VS_VERSIONINFO structure.
+ /// The wValueLength member specifies the length of this member;
+ /// if wValueLength is zero, this member does not exist.
+ ///
+ public FixedFileInfo Value;
+
+ ///
+ /// An array of zero or one StringFileInfo structures, and zero or one VarFileInfo structures
+ /// that are children of the current VS_VERSIONINFO structure.
+ ///
+ public StringFileInfo ChildrenStringFileInfo;
+
+ ///
+ /// An array of zero or one StringFileInfo structures, and zero or one VarFileInfo structures
+ /// that are children of the current VS_VERSIONINFO structure.
+ ///
+ public VarFileInfo ChildrenVarFileInfo;
+
+ public static new VersionInfo Deserialize(Stream stream)
+ {
+ long originalPosition = stream.Position;
+
+ VersionInfo vi = new VersionInfo();
+ Resource resource = Resource.Deserialize(stream);
+ if (resource.Key != "VS_VERSION_INFO")
+ return null;
+
+ vi.Length = resource.Length;
+ vi.ValueLength = resource.ValueLength;
+ vi.Type = resource.Type;
+ vi.Key = resource.Key;
+
+ if (vi.ValueLength > 0)
+ vi.Value = FixedFileInfo.Deserialize(stream);
+
+ if (stream.Position - originalPosition > vi.Length)
+ return vi;
+
+ long preChildOffset = stream.Position;
+ Resource firstChild = Resource.Deserialize(stream);
+ if (firstChild.Key == "StringFileInfo")
+ {
+ stream.Seek(preChildOffset, SeekOrigin.Begin);
+ vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(stream);
+ }
+ else if (firstChild.Key == "VarFileInfo")
+ {
+ stream.Seek(preChildOffset, SeekOrigin.Begin);
+ vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(stream);
+ }
+
+ if (stream.Position - originalPosition > vi.Length)
+ return vi;
+
+ preChildOffset = stream.Position;
+ Resource secondChild = Resource.Deserialize(stream);
+ if (secondChild.Key == "StringFileInfo")
+ {
+ stream.Seek(preChildOffset, SeekOrigin.Begin);
+ vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(stream);
+ }
+ else if (secondChild.Key == "VarFileInfo")
+ {
+ stream.Seek(preChildOffset, SeekOrigin.Begin);
+ vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(stream);
+ }
+
+ return vi;
+ }
+
+ public static new VersionInfo Deserialize(byte[] content, ref int offset)
+ {
+ int originalOffset = offset;
+
+ VersionInfo vi = new VersionInfo();
+ Resource resource = Resource.Deserialize(content, ref offset);
+ if (resource.Key != "VS_VERSION_INFO")
+ return null;
+
+ vi.Length = resource.Length;
+ vi.ValueLength = resource.ValueLength;
+ vi.Type = resource.Type;
+ vi.Key = resource.Key;
+
+ if (vi.ValueLength > 0)
+ vi.Value = FixedFileInfo.Deserialize(content, ref offset);
+
+ if (offset - originalOffset > vi.Length)
+ return vi;
+
+ int preChildOffset = offset;
+ Resource firstChild = Resource.Deserialize(content, ref offset);
+ if (firstChild.Key == "StringFileInfo")
+ {
+ offset = preChildOffset;
+ vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(content, ref offset);
+ }
+ else if (firstChild.Key == "VarFileInfo")
+ {
+ offset = preChildOffset;
+ vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(content, ref offset);
+ }
+
+ if (offset - originalOffset > vi.Length)
+ return vi;
+
+
+ preChildOffset = offset;
+ Resource secondChild = Resource.Deserialize(content, ref offset);
+ if (secondChild.Key == "StringFileInfo")
+ {
+ offset = preChildOffset;
+ vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(content, ref offset);
+ }
+ else if (secondChild.Key == "VarFileInfo")
+ {
+ offset = preChildOffset;
+ vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(content, ref offset);
+ }
+
+ return vi;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Sections/ExportDataSection.cs b/BurnOutSharp/ExecutableType/Microsoft/Sections/ExportDataSection.cs
index 197b414f..17b49350 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Sections/ExportDataSection.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Sections/ExportDataSection.cs
@@ -1,5 +1,4 @@
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.ExecutableType.Microsoft.Tables;
namespace BurnOutSharp.ExecutableType.Microsoft.Sections
@@ -56,18 +55,15 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Sections
return eds;
}
- public static ExportDataSection Deserialize(byte[] content, int offset)
+ public static ExportDataSection Deserialize(byte[] content, ref int offset)
{
var eds = new ExportDataSection();
- unsafe
- {
- eds.ExportDirectoryTable = ExportDirectoryTable.Deserialize(content, offset); offset += Marshal.SizeOf(eds.ExportDirectoryTable);
- // eds.ExportAddressTable = ExportAddressTable.Deserialize(content, offset, count: 0); offset += Marshal.SizeOf(eds.ExportAddressTable); // TODO: Figure out where this count comes from
- // eds.NamePointerTable = ExportNamePointerTable.Deserialize(content, offset, count: 0); offset += Marshal.SizeOf(eds.NamePointerTable); // TODO: Figure out where this count comes from
- // eds.OrdinalTable = ExportOrdinalTable.Deserialize(content, offset, count: 0); offset += Marshal.SizeOf(eds.OrdinalTable); // TODO: Figure out where this count comes from
- // eds.ExportNameTable = ExportNameTable.Deserialize(stream); offset += Marshal.SizeOf(eds.ExportAddressTable); // TODO: set this table based on the NamePointerTable value
- }
+ eds.ExportDirectoryTable = ExportDirectoryTable.Deserialize(content, ref offset);
+ // eds.ExportAddressTable = ExportAddressTable.Deserialize(content, ref offset, count: 0); // TODO: Figure out where this count comes from
+ // eds.NamePointerTable = ExportNamePointerTable.Deserialize(content, ref offset, count: 0); // TODO: Figure out where this count comes from
+ // eds.OrdinalTable = ExportOrdinalTable.Deserialize(content, ref offset, count: 0); // TODO: Figure out where this count comes from
+ // eds.ExportNameTable = ExportNameTable.Deserialize(content, ref offset); // TODO: set this table based on the NamePointerTable value
return eds;
}
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Sections/ImportDataSection.cs b/BurnOutSharp/ExecutableType/Microsoft/Sections/ImportDataSection.cs
index 09fada0b..0fc65024 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Sections/ImportDataSection.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Sections/ImportDataSection.cs
@@ -57,28 +57,24 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Sections
return ids;
}
- public static ImportDataSection Deserialize(byte[] content, int offset, bool pe32plus, int hintCount)
+ public static ImportDataSection Deserialize(byte[] content, ref int offset, bool pe32plus, int hintCount)
{
var ids = new ImportDataSection();
- ids.ImportDirectoryTable = ImportDirectoryTable.Deserialize(content, offset); offset += 20 * ids.ImportDirectoryTable.Entries.Length;
+ ids.ImportDirectoryTable = ImportDirectoryTable.Deserialize(content, ref offset);
List tempLookupTables = new List();
while (true)
{
- var tempLookupTable = ImportLookupTable.Deserialize(content, offset, pe32plus);
- if (tempLookupTable.EntriesPE32 != null)
- offset += 4 * tempLookupTable.EntriesPE32.Length;
- else if (tempLookupTable.EntriesPE32Plus != null)
- offset += 8 * tempLookupTable.EntriesPE32Plus.Length;
- else
+ var tempLookupTable = ImportLookupTable.Deserialize(content, ref offset, pe32plus);
+ if (tempLookupTable.EntriesPE32 == null && tempLookupTable.EntriesPE32Plus == null)
break;
tempLookupTables.Add(tempLookupTable);
}
// TODO: Update the offset, if possible
- ids.HintNameTable = HintNameTable.Deserialize(content, offset, hintCount);
+ ids.HintNameTable = HintNameTable.Deserialize(content, ref offset, hintCount);
return ids;
}
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Sections/ResourceSection.cs b/BurnOutSharp/ExecutableType/Microsoft/Sections/ResourceSection.cs
index eee13b54..1a05deba 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Sections/ResourceSection.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Sections/ResourceSection.cs
@@ -1,5 +1,4 @@
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.ExecutableType.Microsoft.Headers;
using BurnOutSharp.ExecutableType.Microsoft.Tables;
@@ -32,15 +31,12 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Sections
return rs;
}
- public static ResourceSection Deserialize(byte[] content, int offset, SectionHeader[] sections)
+ public static ResourceSection Deserialize(byte[] content, ref int offset, SectionHeader[] sections)
{
var rs = new ResourceSection();
- unsafe
- {
- long sectionStart = offset;
- rs.ResourceDirectoryTable = ResourceDirectoryTable.Deserialize(content, offset, sectionStart, sections); offset += Marshal.SizeOf(rs.ResourceDirectoryTable);
- }
+ long sectionStart = offset;
+ rs.ResourceDirectoryTable = ResourceDirectoryTable.Deserialize(content, ref offset, sectionStart, sections);
return rs;
}
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportAddressTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportAddressTable.cs
index 42509524..15822d8e 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportAddressTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportAddressTable.cs
@@ -26,14 +26,14 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
return eat;
}
- public static ExportAddressTable Deserialize(byte[] content, int offset, int count)
+ public static ExportAddressTable Deserialize(byte[] content, ref int offset, int count)
{
var eat = new ExportAddressTable();
eat.Entries = new ExportAddressTableEntry[count];
for (int i = 0; i < count; i++)
{
- eat.Entries[i] = ExportAddressTableEntry.Deserialize(content, offset); offset += 4;
+ eat.Entries[i] = ExportAddressTableEntry.Deserialize(content, ref offset);
}
return eat;
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportDirectoryTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportDirectoryTable.cs
index 749dfd41..a0430e47 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportDirectoryTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportDirectoryTable.cs
@@ -90,7 +90,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
return edt;
}
- public static ExportDirectoryTable Deserialize(byte[] content, int offset)
+ public static ExportDirectoryTable Deserialize(byte[] content, ref int offset)
{
var edt = new ExportDirectoryTable();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportNamePointerTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportNamePointerTable.cs
index 72956fca..47b11a98 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportNamePointerTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportNamePointerTable.cs
@@ -28,7 +28,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
return enpt;
}
- public static ExportNamePointerTable Deserialize(byte[] content, int offset, int count)
+ public static ExportNamePointerTable Deserialize(byte[] content, ref int offset, int count)
{
var enpt = new ExportNamePointerTable();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportOrdinalTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportOrdinalTable.cs
index d33c5576..7ff9ac30 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportOrdinalTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/ExportOrdinalTable.cs
@@ -28,7 +28,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
return edt;
}
- public static ExportOrdinalTable Deserialize(byte[] content, int offset, int count)
+ public static ExportOrdinalTable Deserialize(byte[] content, ref int offset, int count)
{
var edt = new ExportOrdinalTable();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/HintNameTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/HintNameTable.cs
index c17f4941..6af73d39 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/HintNameTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/HintNameTable.cs
@@ -25,14 +25,14 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
return hnt;
}
- public static HintNameTable Deserialize(byte[] content, int offset, int count)
+ public static HintNameTable Deserialize(byte[] content, ref int offset, int count)
{
var hnt = new HintNameTable();
hnt.Entries = new HintNameTableEntry[count];
for (int i = 0; i < count; i++)
{
- hnt.Entries[i] = HintNameTableEntry.Deserialize(content, offset);
+ hnt.Entries[i] = HintNameTableEntry.Deserialize(content, ref offset);
offset += 2 + hnt.Entries[i].Name.Length + hnt.Entries[i].Pad;
}
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportAddressTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportAddressTable.cs
index 62d4dabd..cb3dbe8f 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportAddressTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportAddressTable.cs
@@ -33,14 +33,14 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
return iat;
}
- public static ImportAddressTable Deserialize(byte[] content, int offset)
+ public static ImportAddressTable Deserialize(byte[] content, ref int offset)
{
var iat = new ImportAddressTable();
List tempEntries = new List();
while (true)
{
- var entry = ImportAddressTableEntry.Deserialize(content, offset); offset += 20;
+ var entry = ImportAddressTableEntry.Deserialize(content, ref offset);
tempEntries.Add(entry);
if (entry.IsNull())
break;
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportDirectoryTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportDirectoryTable.cs
index 71f806e5..39e4844c 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportDirectoryTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportDirectoryTable.cs
@@ -33,14 +33,14 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
return idt;
}
- public static ImportDirectoryTable Deserialize(byte[] content, int offset)
+ public static ImportDirectoryTable Deserialize(byte[] content, ref int offset)
{
var idt = new ImportDirectoryTable();
List tempEntries = new List();
while (true)
{
- var entry = ImportDirectoryTableEntry.Deserialize(content, offset); offset += 20;
+ var entry = ImportDirectoryTableEntry.Deserialize(content, ref offset);
tempEntries.Add(entry);
if (entry.IsNull())
break;
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportLookupTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportLookupTable.cs
index ef13cead..9430f900 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportLookupTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/ImportLookupTable.cs
@@ -58,7 +58,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
return ilt;
}
- public static ImportLookupTable Deserialize(byte[] content, int offset, bool pe32plus)
+ public static ImportLookupTable Deserialize(byte[] content, ref int offset, bool pe32plus)
{
var ilt = new ImportLookupTable();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/NEResourceTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/NEResourceTable.cs
index d515794b..7138cae4 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/NEResourceTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/NEResourceTable.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.ExecutableType.Microsoft.Entries;
using BurnOutSharp.Tools;
@@ -17,7 +16,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
/// resource. It also defines the location and size of the resource.
///
/// http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm
- [StructLayout(LayoutKind.Sequential)]
internal class NEResourceTable
{
///
@@ -69,22 +67,19 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
return nrt;
}
- public static NEResourceTable Deserialize(byte[] contents, int offset)
+ public static NEResourceTable Deserialize(byte[] content, ref int offset)
{
var nrt = new NEResourceTable();
- nrt.AlignmentShiftCount = BitConverter.ToUInt16(contents, offset); offset += 2;
+ nrt.AlignmentShiftCount = BitConverter.ToUInt16(content, offset); offset += 2;
var typeInformationBlocks = new List();
while (true)
{
- unsafe
- {
- var block = ResourceTypeInformationBlock.Deserialize(contents, offset); offset += Marshal.SizeOf(block);
- if (block.TypeID == 0)
- break;
-
- typeInformationBlocks.Add(block);
- }
+ var block = ResourceTypeInformationBlock.Deserialize(content, ref offset);
+ if (block.TypeID == 0)
+ break;
+
+ typeInformationBlocks.Add(block);
}
nrt.TypeInformationBlocks = typeInformationBlocks.ToArray();
@@ -92,14 +87,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
var typeAndNameStrings = new List();
while (true)
{
- unsafe
- {
- var str = NEResourceNameString.Deserialize(contents, offset); offset += Marshal.SizeOf(str);
- if (str.Length == 0)
- break;
+ var str = NEResourceNameString.Deserialize(content, ref offset);
+ if (str.Length == 0)
+ break;
- typeAndNameStrings.Add(str);
- }
+ typeAndNameStrings.Add(str);
}
nrt.TypeAndNameStrings = typeAndNameStrings.ToArray();
diff --git a/BurnOutSharp/ExecutableType/Microsoft/Tables/ResourceDirectoryTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Tables/ResourceDirectoryTable.cs
index aa82fd0c..54a1d0f5 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/Tables/ResourceDirectoryTable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/Tables/ResourceDirectoryTable.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
using BurnOutSharp.ExecutableType.Microsoft.Entries;
using BurnOutSharp.ExecutableType.Microsoft.Headers;
using BurnOutSharp.Tools;
@@ -12,7 +11,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
/// This data structure should be considered the heading of a table
/// because the table actually consists of directory entries and this structure
///
- [StructLayout(LayoutKind.Sequential)]
internal class ResourceDirectoryTable
{
///
@@ -94,7 +92,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Tables
return rdt;
}
- public static ResourceDirectoryTable Deserialize(byte[] content, int offset, long sectionStart, SectionHeader[] sections)
+ public static ResourceDirectoryTable Deserialize(byte[] content, ref int offset, long sectionStart, SectionHeader[] sections)
{
var rdt = new ResourceDirectoryTable();
@@ -108,13 +106,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, sectionStart, sections); offset += 8;
+ rdt.NamedEntries[i] = ResourceDirectoryTableEntry.Deserialize(content, ref offset, sectionStart, sections);
}
rdt.IdEntries = new ResourceDirectoryTableEntry[rdt.NumberOfIdEntries];
for (int i = 0; i < rdt.NumberOfIdEntries; i++)
{
- rdt.IdEntries[i] = ResourceDirectoryTableEntry.Deserialize(content, offset, sectionStart, sections); offset += 8;
+ rdt.IdEntries[i] = ResourceDirectoryTableEntry.Deserialize(content, ref offset, sectionStart, sections);
}
return rdt;
diff --git a/BurnOutSharp/PackerType/IntelInstallationFramework.cs b/BurnOutSharp/PackerType/IntelInstallationFramework.cs
index f8b50e4d..bb3a9171 100644
--- a/BurnOutSharp/PackerType/IntelInstallationFramework.cs
+++ b/BurnOutSharp/PackerType/IntelInstallationFramework.cs
@@ -31,7 +31,7 @@ namespace BurnOutSharp.PackerType
&& (name.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase)
|| name.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase)))
{
- return $"Intel Installation Framework {Utilities.GetFileVersion(file)}";
+ return $"Intel Installation Framework {Utilities.GetFileVersion(fileContent)}";
}
name = fvinfo?.ProductName?.Trim();
@@ -39,7 +39,7 @@ namespace BurnOutSharp.PackerType
&& (name.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase)
|| name.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase)))
{
- return $"Intel Installation Framework {Utilities.GetFileVersion(file)}";
+ return $"Intel Installation Framework {Utilities.GetFileVersion(fileContent)}";
}
// Get the sections from the executable, if possible
diff --git a/BurnOutSharp/PackerType/MicrosoftCABSFX.cs b/BurnOutSharp/PackerType/MicrosoftCABSFX.cs
index da102c37..9d473b4b 100644
--- a/BurnOutSharp/PackerType/MicrosoftCABSFX.cs
+++ b/BurnOutSharp/PackerType/MicrosoftCABSFX.cs
@@ -36,7 +36,7 @@ namespace BurnOutSharp.PackerType
{
string version = GetVersion(file, fileContent, null);
if (!string.IsNullOrWhiteSpace(version))
- return $"Microsoft CAB SFX v{Utilities.GetFileVersion(file)}";
+ return $"Microsoft CAB SFX v{Utilities.GetFileVersion(fileContent)}";
return "Microsoft CAB SFX";
}
@@ -46,7 +46,7 @@ namespace BurnOutSharp.PackerType
{
string version = GetVersion(file, fileContent, null);
if (!string.IsNullOrWhiteSpace(version))
- return $"Microsoft CAB SFX v{Utilities.GetFileVersion(file)}";
+ return $"Microsoft CAB SFX v{Utilities.GetFileVersion(fileContent)}";
return "Microsoft CAB SFX";
}
@@ -158,7 +158,7 @@ namespace BurnOutSharp.PackerType
// This method of version detection is suboptimal because the version is sometimes the version of the included software, not the SFX itself.
public static string GetVersion(string file, byte[] fileContent, List positions)
{
- string version = Utilities.GetFileVersion(file);
+ string version = Utilities.GetFileVersion(fileContent);
if (!string.IsNullOrWhiteSpace(version))
return $"v{version}";
diff --git a/BurnOutSharp/PackerType/SetupFactory.cs b/BurnOutSharp/PackerType/SetupFactory.cs
index 3bed75c9..9e8334a5 100644
--- a/BurnOutSharp/PackerType/SetupFactory.cs
+++ b/BurnOutSharp/PackerType/SetupFactory.cs
@@ -122,7 +122,7 @@ namespace BurnOutSharp.PackerType
return version;
// Then check the file version
- version = Utilities.GetFileVersion(file);
+ version = Utilities.GetFileVersion(fileContent);
if (!string.IsNullOrEmpty(version))
return version;
diff --git a/BurnOutSharp/ProtectionType/ElectronicArts.cs b/BurnOutSharp/ProtectionType/ElectronicArts.cs
index 8b0d8a80..c6251bb4 100644
--- a/BurnOutSharp/ProtectionType/ElectronicArts.cs
+++ b/BurnOutSharp/ProtectionType/ElectronicArts.cs
@@ -47,13 +47,13 @@ namespace BurnOutSharp.ProtectionType
string name = fvinfo?.FileDescription?.Trim();
if (!string.IsNullOrWhiteSpace(name) && name.Contains("Registration code installer program"))
- return $"EA CdKey Registration Module {Utilities.GetFileVersion(file)}";
+ return $"EA CdKey Registration Module {Utilities.GetFileVersion(fileContent)}";
else if (!string.IsNullOrWhiteSpace(name) && name.Equals("EA DRM Helper", StringComparison.OrdinalIgnoreCase))
- return $"EA DRM Protection {Utilities.GetFileVersion(file)}";
+ return $"EA DRM Protection {Utilities.GetFileVersion(fileContent)}";
name = fvinfo?.InternalName?.Trim();
if (!string.IsNullOrWhiteSpace(name) && name.Equals("CDCode", StringComparison.Ordinal))
- return $"EA CdKey Registration Module {Utilities.GetFileVersion(file)}";
+ return $"EA CdKey Registration Module {Utilities.GetFileVersion(fileContent)}";
// Get the sections from the executable, if possible
PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0);
diff --git a/BurnOutSharp/ProtectionType/GFWL.cs b/BurnOutSharp/ProtectionType/GFWL.cs
index 2498452e..0e6655fc 100644
--- a/BurnOutSharp/ProtectionType/GFWL.cs
+++ b/BurnOutSharp/ProtectionType/GFWL.cs
@@ -28,9 +28,9 @@ namespace BurnOutSharp.ProtectionType
string name = fvinfo?.FileDescription?.Trim();
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Games for Windows - LIVE Zero Day Piracy Protection", StringComparison.OrdinalIgnoreCase))
- return $"Games for Windows LIVE - Zero Day Piracy Protection Module {Utilities.GetFileVersion(file)}";
+ return $"Games for Windows LIVE - Zero Day Piracy Protection Module {Utilities.GetFileVersion(fileContent)}";
else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Games for Windows", StringComparison.OrdinalIgnoreCase))
- return $"Games for Windows LIVE {Utilities.GetFileVersion(file)}";
+ return $"Games for Windows LIVE {Utilities.GetFileVersion(fileContent)}";
// Get the sections from the executable, if possible
PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0);
diff --git a/BurnOutSharp/ProtectionType/SolidShield.cs b/BurnOutSharp/ProtectionType/SolidShield.cs
index 017e2b2b..1b75b9e5 100644
--- a/BurnOutSharp/ProtectionType/SolidShield.cs
+++ b/BurnOutSharp/ProtectionType/SolidShield.cs
@@ -57,17 +57,17 @@ namespace BurnOutSharp.ProtectionType
string name = fvinfo?.FileDescription?.Trim();
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("DVM Library", StringComparison.OrdinalIgnoreCase))
- return $"SolidShield {Utilities.GetFileVersion(file)}";
+ return $"SolidShield {Utilities.GetFileVersion(fileContent)}";
else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Solidshield Activation Library", StringComparison.OrdinalIgnoreCase))
- return $"SolidShield Core.dll {Utilities.GetFileVersion(file)}";
+ return $"SolidShield Core.dll {Utilities.GetFileVersion(fileContent)}";
else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Activation Manager", StringComparison.OrdinalIgnoreCase))
return $"SolidShield Activation Manager Module {GetFileVersion(file, fileContent, null)}";
name = fvinfo?.ProductName?.Trim();
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Solidshield Activation Library", StringComparison.OrdinalIgnoreCase))
- return $"SolidShield Core.dll {Utilities.GetFileVersion(file)}";
+ return $"SolidShield Core.dll {Utilities.GetFileVersion(fileContent)}";
else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Solidshield Library", StringComparison.OrdinalIgnoreCase))
- return $"SolidShield Core.dll {Utilities.GetFileVersion(file)}";
+ return $"SolidShield Core.dll {Utilities.GetFileVersion(fileContent)}";
else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Activation Manager", StringComparison.OrdinalIgnoreCase))
return $"SolidShield Activation Manager Module {GetFileVersion(file, fileContent, null)}";
@@ -224,7 +224,7 @@ namespace BurnOutSharp.ProtectionType
{
string companyName = Utilities.GetFileVersionInfo(file)?.CompanyName.ToLowerInvariant();
if (!string.IsNullOrWhiteSpace(companyName) && (companyName.Contains("solidshield") || companyName.Contains("tages")))
- return Utilities.GetFileVersion(file);
+ return Utilities.GetFileVersion(fileContent);
return null;
}
diff --git a/BurnOutSharp/ProtectionType/StarForce.cs b/BurnOutSharp/ProtectionType/StarForce.cs
index 6dedb3c8..9464bdfb 100644
--- a/BurnOutSharp/ProtectionType/StarForce.cs
+++ b/BurnOutSharp/ProtectionType/StarForce.cs
@@ -28,7 +28,7 @@ namespace BurnOutSharp.ProtectionType
string name = fvinfo?.LegalCopyright?.Trim();
if (!string.IsNullOrWhiteSpace(name) && name.Contains("Protection Technology"))
- return $"StarForce {Utilities.GetFileVersion(file)}";
+ return $"StarForce {Utilities.GetFileVersion(fileContent)}";
// TODO: Find what fvinfo field actually maps to this
name = fvinfo?.FileDescription?.Trim();
@@ -155,7 +155,7 @@ namespace BurnOutSharp.ProtectionType
public static string GetVersion(string file, byte[] fileContent, List positions)
{
- return $"{Utilities.GetFileVersion(file)} ({fileContent.Skip(positions[1] + 22).TakeWhile(c => c != 0x00)})";
+ return $"{Utilities.GetFileVersion(fileContent)} ({fileContent.Skip(positions[1] + 22).TakeWhile(c => c != 0x00)})";
}
}
}
diff --git a/BurnOutSharp/Tools/Extensions.cs b/BurnOutSharp/Tools/Extensions.cs
index 1163e384..2b0d93fc 100644
--- a/BurnOutSharp/Tools/Extensions.cs
+++ b/BurnOutSharp/Tools/Extensions.cs
@@ -1,11 +1,84 @@
using System;
+using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Text;
+using BurnOutSharp.Matching;
namespace BurnOutSharp.Tools
{
- internal static class BufferExtensions
+ internal static class Extensions
{
+ // TODO: Add extensions for BitConverter.ToX(); offset += x;
+ #region Byte Arrays
+
+ ///
+ /// Find all positions of one array in another, if possible, if possible
+ ///
+ public static List FindAllPositions(this byte[] stack, byte?[] needle, int start = 0, int end = -1)
+ {
+ // Get the outgoing list
+ List positions = new List();
+
+ // Initialize the loop variables
+ bool found = true;
+ int lastPosition = start;
+ var matcher = new ContentMatch(needle, end: end);
+
+ // Loop over and get all positions
+ while (found)
+ {
+ matcher.Start = lastPosition;
+ (found, lastPosition) = matcher.Match(stack, false);
+ if (found)
+ positions.Add(lastPosition);
+ }
+
+ return positions;
+ }
+
+ ///
+ /// Find the first position of one array in another, if possible
+ ///
+ public static bool FirstPosition(this byte[] stack, byte?[] needle, out int position, int start = 0, int end = -1)
+ {
+ var matcher = new ContentMatch(needle, start, end);
+ (bool found, int foundPosition) = matcher.Match(stack, false);
+ position = foundPosition;
+ return found;
+ }
+
+ ///
+ /// Find the last position of one array in another, if possible
+ ///
+ public static bool LastPosition(this byte[] stack, byte?[] needle, out int position, int start = 0, int end = -1)
+ {
+ var matcher = new ContentMatch(needle, start, end);
+ (bool found, int foundPosition) = matcher.Match(stack, true);
+ position = foundPosition;
+ return found;
+ }
+
+ ///
+ /// See if a byte array starts with another
+ ///
+ public static bool StartsWith(this byte[] stack, byte?[] needle)
+ {
+ return stack.FirstPosition(needle, out int _, start: 0, end: 1);
+ }
+
+ ///
+ /// See if a byte array ends with another
+ ///
+ public static bool EndsWith(this byte[] stack, byte?[] needle)
+ {
+ return stack.FirstPosition(needle, out int _, start: stack.Length - needle.Length);
+ }
+
+ #endregion
+
+ #region Streams
+
///
/// Read a byte from the stream
///
@@ -109,6 +182,32 @@ namespace BurnOutSharp.Tools
byte[] buffer = new byte[8];
stream.Read(buffer, 0, 8);
return BitConverter.ToUInt64(buffer, 0);
- }
+ }
+
+ ///
+ /// Read a null-terminated string from the stream
+ ///
+ public static string ReadString(this Stream stream) => stream.ReadString(Encoding.Default);
+
+ ///
+ /// Read a null-terminated string from the stream
+ ///
+ public static string ReadString(this Stream stream, Encoding encoding)
+ {
+ byte[] nullTerminator = encoding.GetBytes(new char[] { '\0' });
+ int charWidth = nullTerminator.Length;
+
+ List tempBuffer = new List();
+
+ byte[] buffer = new byte[charWidth];
+ while (stream.Read(buffer, 0, charWidth) != 0 && buffer.SequenceEqual(nullTerminator))
+ {
+ tempBuffer.AddRange(buffer);
+ }
+
+ return encoding.GetString(tempBuffer.ToArray());
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/BurnOutSharp/Tools/Utilities.cs b/BurnOutSharp/Tools/Utilities.cs
index 109fb2ec..81516090 100644
--- a/BurnOutSharp/Tools/Utilities.cs
+++ b/BurnOutSharp/Tools/Utilities.cs
@@ -6,6 +6,8 @@ using System.IO;
using System.Linq;
using System.Xml;
using BurnOutSharp.ExecutableType.Microsoft;
+using BurnOutSharp.ExecutableType.Microsoft.Entries;
+using BurnOutSharp.ExecutableType.Microsoft.Resources;
using BurnOutSharp.ExecutableType.Microsoft.Sections;
using BurnOutSharp.ExecutableType.Microsoft.Tables;
using BurnOutSharp.Matching;
@@ -180,73 +182,6 @@ namespace BurnOutSharp.Tools
#endregion
- #region Byte Arrays
-
- ///
- /// Find all positions of one array in another, if possible, if possible
- ///
- public static List FindAllPositions(this byte[] stack, byte?[] needle, int start = 0, int end = -1)
- {
- // Get the outgoing list
- List positions = new List();
-
- // Initialize the loop variables
- bool found = true;
- int lastPosition = start;
- var matcher = new ContentMatch(needle, end: end);
-
- // Loop over and get all positions
- while (found)
- {
- matcher.Start = lastPosition;
- (found, lastPosition) = matcher.Match(stack, false);
- if (found)
- positions.Add(lastPosition);
- }
-
- return positions;
- }
-
- ///
- /// Find the first position of one array in another, if possible
- ///
- public static bool FirstPosition(this byte[] stack, byte?[] needle, out int position, int start = 0, int end = -1)
- {
- var matcher = new ContentMatch(needle, start, end);
- (bool found, int foundPosition) = matcher.Match(stack, false);
- position = foundPosition;
- return found;
- }
-
- ///
- /// Find the last position of one array in another, if possible
- ///
- public static bool LastPosition(this byte[] stack, byte?[] needle, out int position, int start = 0, int end = -1)
- {
- var matcher = new ContentMatch(needle, start, end);
- (bool found, int foundPosition) = matcher.Match(stack, true);
- position = foundPosition;
- return found;
- }
-
- ///
- /// See if a byte array starts with another
- ///
- public static bool StartsWith(this byte[] stack, byte?[] needle)
- {
- return stack.FirstPosition(needle, out int _, start: 0, end: 1);
- }
-
- ///
- /// See if a byte array ends with another
- ///
- public static bool EndsWith(this byte[] stack, byte?[] needle)
- {
- return stack.FirstPosition(needle, out int _, start: stack.Length - needle.Length);
- }
-
- #endregion
-
#region Protection
///
@@ -269,6 +204,36 @@ namespace BurnOutSharp.Tools
}
}
+ ///
+ /// Get the file version info object related to file contents, if possible
+ ///
+ /// Byte array representing the file contents
+ /// FileVersionInfo object on success, null on error
+ public static VersionInfo GetVersionInfo(byte[] fileContent)
+ {
+ if (fileContent == null || !fileContent.Any())
+ return null;
+
+ // If we don't have a PE executable, just return null
+ PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0);
+ var resourceSection = pex?.ResourceSection;
+ if (resourceSection == null)
+ return null;
+
+ var resource = FindResourceInSection(resourceSection, dataContains: "V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0");
+
+ try
+ {
+ int index = 0;
+ return VersionInfo.Deserialize(resource.Data, ref index);
+ }
+ catch (Exception ex)
+ {
+ // Console.WriteLine(ex);
+ return null;
+ }
+ }
+
///
/// Get the file version as reported by the filesystem
///
@@ -284,6 +249,29 @@ namespace BurnOutSharp.Tools
else
return fvinfo.ProductVersion.Replace(", ", ".");
}
+
+ ///
+ /// Get the file version as reported by the filesystem
+ ///
+ /// Byte array representing the file contents
+ /// Version string, null on error
+ /// TODO: Add override that takes an existing PE
+ public static string GetFileVersion(byte[] fileContent)
+ {
+ var resourceStrings = GetVersionInfo(fileContent)?.ChildrenStringFileInfo?.Children?.Children;
+ if (resourceStrings == null)
+ return null;
+
+ var fileVersion = resourceStrings.FirstOrDefault(s => s.Key == "FileVersion");
+ if (!string.IsNullOrWhiteSpace(fileVersion?.Value))
+ return fileVersion.Value.Replace(", ", ".");
+
+ var productVersion = resourceStrings.FirstOrDefault(s => s.Key == "ProductVersion");
+ if (!string.IsNullOrWhiteSpace(productVersion?.Value))
+ return productVersion.Value.Replace(", ", ".");
+
+ return null;
+ }
///
/// Wrapper for GetFileVersion for use in content matching
@@ -292,7 +280,7 @@ namespace BurnOutSharp.Tools
/// Byte array representing the file contents
/// Last matched positions in the contents
/// Version string, null on error
- public static string GetFileVersion(string file, byte[] fileContent, List positions) => GetFileVersion(file);
+ public static string GetFileVersion(string file, byte[] fileContent, List positions) => GetFileVersion(fileContent);
///
/// Wrapper for GetFileVersion for use in path matching
@@ -388,7 +376,7 @@ namespace BurnOutSharp.Tools
/// String to use if checking for data starting with a string
/// String to use if checking for data contains a string
/// Full encoded resource data, null on error
- private static string FindResourceInSection(ResourceSection rs, string dataStart = null, string dataContains = null)
+ private static ResourceDataEntry FindResourceInSection(ResourceSection rs, string dataStart = null, string dataContains = null)
{
if (rs == null)
return null;
@@ -403,7 +391,7 @@ namespace BurnOutSharp.Tools
/// String to use if checking for data starting with a string
/// String to use if checking for data contains a string
/// Full encoded resource data, null on error
- private static string FindResourceInTable(ResourceDirectoryTable rdt, string dataStart, string dataContains)
+ private static ResourceDataEntry FindResourceInTable(ResourceDirectoryTable rdt, string dataStart, string dataContains)
{
if (rdt == null)
return null;
@@ -412,15 +400,15 @@ namespace BurnOutSharp.Tools
{
if (rdte.IsResourceDataEntry() && rdte.DataEntry != null)
{
- if (dataStart != null && rdte.DataEntry.EncodedData.StartsWith(dataStart))
- return rdte.DataEntry.EncodedData;
- else if (dataContains != null && rdte.DataEntry.EncodedData.Contains(dataContains))
- return rdte.DataEntry.EncodedData;
+ if (dataStart != null && rdte.DataEntry.DataAsUTF8String.StartsWith(dataStart))
+ return rdte.DataEntry;
+ else if (dataContains != null && rdte.DataEntry.DataAsUTF8String.Contains(dataContains))
+ return rdte.DataEntry;
}
else
{
- string manifest = FindResourceInTable(rdte.Subdirectory, dataStart, dataContains);
- if (!string.IsNullOrWhiteSpace(manifest))
+ var manifest = FindResourceInTable(rdte.Subdirectory, dataStart, dataContains);
+ if (manifest != null)
return manifest;
}
}
@@ -429,15 +417,15 @@ namespace BurnOutSharp.Tools
{
if (rdte.IsResourceDataEntry() && rdte.DataEntry != null)
{
- if (dataStart != null && rdte.DataEntry.EncodedData.StartsWith(dataStart))
- return rdte.DataEntry.EncodedData;
- else if (dataContains != null && rdte.DataEntry.EncodedData.Contains(dataContains))
- return rdte.DataEntry.EncodedData;
+ if (dataStart != null && rdte.DataEntry.DataAsUTF8String.StartsWith(dataStart))
+ return rdte.DataEntry;
+ else if (dataContains != null && rdte.DataEntry.DataAsUTF8String.Contains(dataContains))
+ return rdte.DataEntry;
}
else
{
- string manifest = FindResourceInTable(rdte.Subdirectory, dataStart, dataContains);
- if (!string.IsNullOrWhiteSpace(manifest))
+ var manifest = FindResourceInTable(rdte.Subdirectory, dataStart, dataContains);
+ if (manifest != null)
return manifest;
}
}
@@ -450,7 +438,7 @@ namespace BurnOutSharp.Tools
///
/// ResourceSection from the executable
/// Full assembly manifest, null on error
- private static string FindAssemblyManifest(ResourceSection rs) => FindResourceInSection(rs, dataStart: " FindResourceInSection(rs, dataStart: "
/// Get the assembly identity node from an embedded manifest