diff --git a/BurnOutSharp.Builders/PortableExecutable.cs b/BurnOutSharp.Builders/PortableExecutable.cs index a5489546..2908b4fc 100644 --- a/BurnOutSharp.Builders/PortableExecutable.cs +++ b/BurnOutSharp.Builders/PortableExecutable.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using BurnOutSharp.Models.PortableExecutable; using BurnOutSharp.Utilities; +using static BurnOutSharp.Models.PortableExecutable.Constants; namespace BurnOutSharp.Builders { @@ -73,12 +74,9 @@ namespace BurnOutSharp.Builders #region Signature data.Seek(initialOffset + stub.Header.NewExeHeaderAddr, SeekOrigin.Begin); - executable.Signature = new byte[4]; - for (int i = 0; i < executable.Signature.Length; i++) - { - executable.Signature[i] = data.ReadByteValue(); - } - if (executable.Signature[0] != 'P' || executable.Signature[1] != 'E' || executable.Signature[2] != '\0' || executable.Signature[3] != '\0') + byte[] signature = data.ReadBytes(4); + executable.Signature = Encoding.ASCII.GetString(signature); + if (executable.Signature != SignatureString) return null; #endregion diff --git a/BurnOutSharp.Matching/Extensions.cs b/BurnOutSharp.Matching/Extensions.cs index 7a3f8511..bff2dbb9 100644 --- a/BurnOutSharp.Matching/Extensions.cs +++ b/BurnOutSharp.Matching/Extensions.cs @@ -61,6 +61,14 @@ namespace BurnOutSharp.Matching 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 starts with another /// @@ -69,6 +77,14 @@ namespace BurnOutSharp.Matching 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); + } + /// /// See if a byte array ends with another /// diff --git a/BurnOutSharp.Models/PortableExecutable/Constants.cs b/BurnOutSharp.Models/PortableExecutable/Constants.cs new file mode 100644 index 00000000..03a39655 --- /dev/null +++ b/BurnOutSharp.Models/PortableExecutable/Constants.cs @@ -0,0 +1,11 @@ +namespace BurnOutSharp.Models.PortableExecutable +{ + public static class Constants + { + public static readonly byte[] SignatureBytes = new byte[] { 0x50, 0x45, 0x00, 0x00 }; + + public const string SignatureString = "PE\0\0"; + + public const uint SignatureUInt32 = 0x00004550; + } +} \ No newline at end of file diff --git a/BurnOutSharp.Models/PortableExecutable/Executable.cs b/BurnOutSharp.Models/PortableExecutable/Executable.cs index bcfaa41b..32a455f3 100644 --- a/BurnOutSharp.Models/PortableExecutable/Executable.cs +++ b/BurnOutSharp.Models/PortableExecutable/Executable.cs @@ -19,7 +19,7 @@ namespace BurnOutSharp.Models.PortableExecutable /// signature that identifies the file as a PE format image file. This signature is "PE\0\0" /// (the letters "P" and "E" followed by two null bytes). /// - public byte[] Signature { get; set; } + public string Signature { get; set; } /// /// COFF file header diff --git a/BurnOutSharp.Wrappers/PortableExecutable.cs b/BurnOutSharp.Wrappers/PortableExecutable.cs index c826b6af..15d2fbff 100644 --- a/BurnOutSharp.Wrappers/PortableExecutable.cs +++ b/BurnOutSharp.Wrappers/PortableExecutable.cs @@ -84,7 +84,7 @@ namespace BurnOutSharp.Wrappers #endregion /// - public byte[] Signature => _executable.Signature; + public string Signature => _executable.Signature; #region COFF File Header @@ -1098,7 +1098,7 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" COFF File Header Information:"); Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {BitConverter.ToString(Signature).Replace("-", string.Empty)}"); + Console.WriteLine($" Signature: {Signature}"); Console.WriteLine($" Machine: {Machine}"); Console.WriteLine($" Number of sections: {NumberOfSections}"); Console.WriteLine($" Time/Date stamp: {TimeDateStamp}"); diff --git a/Test/Program.cs b/Test/Program.cs index e11a2957..b2a14088 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Text; using BurnOutSharp; +using BurnOutSharp.Matching; using BurnOutSharp.Utilities; using BurnOutSharp.Wrappers; @@ -249,7 +250,7 @@ namespace Test magic = stream.ReadBytes(4); // New Executable - if (IsNE(magic)) + if (magic.StartsWith(BurnOutSharp.Models.NewExecutable.Constants.SignatureBytes)) { stream.Seek(0, SeekOrigin.Begin); var newExecutable = NewExecutable.Create(stream); @@ -265,7 +266,8 @@ namespace Test } // Linear Executable - else if (IsLE(magic)) + if (magic.StartsWith(BurnOutSharp.Models.LinearExecutable.Constants.LESignatureBytes) + || magic.StartsWith(BurnOutSharp.Models.LinearExecutable.Constants.LXSignatureBytes)) { Console.WriteLine($"Linear executable found. No parsing currently available."); Console.WriteLine(); @@ -273,7 +275,7 @@ namespace Test } // Portable Executable - else if (IsPE(magic)) + if (magic.StartsWith(BurnOutSharp.Models.PortableExecutable.Constants.SignatureBytes)) { stream.Seek(0, SeekOrigin.Begin); var portableExecutable = PortableExecutable.Create(stream); @@ -354,24 +356,18 @@ namespace Test gcf.Print(); } - // // IS-CAB archive - // else if (ft == SupportedFileType.InstallShieldCAB) - // { - // // Build the cabinet information - // Console.WriteLine("Creating IS-CAB deserializer"); - // Console.WriteLine(); + // IS-CAB archive + else if (ft == SupportedFileType.InstallShieldCAB) + { + // Build the archive information + Console.WriteLine("Creating IS-CAB deserializer"); + Console.WriteLine(); - // var cabinet = BurnOutSharp.Builders.InstallShieldCabinet.ParseCabinet(stream); - // if (cabinet == null) - // { - // Console.WriteLine("Something went wrong parsing IS-CAB archive"); - // Console.WriteLine(); - // return; - // } - - // // Print the cabinet info to screen - // cabinet.Print(); - // } + // TODO: Write and use printing methods + Console.WriteLine("IS-CAB archive printing not currently enabled"); + Console.WriteLine(); + return; + } // MoPaQ (MPQ) archive else if (ft == SupportedFileType.MPQ) @@ -548,39 +544,6 @@ namespace Test } } - /// - /// Determine if the magic bytes indicate a New Executable - /// - private static bool IsNE(byte[] magic) - { - if (magic == null || magic.Length < 2) - return false; - - return magic[0] == 'N' && magic[1] == 'E'; - } - - /// - /// Determine if the magic bytes indicate a Linear Executable - /// - private static bool IsLE(byte[] magic) - { - if (magic == null || magic.Length < 2) - return false; - - return magic[0] == 'L' && (magic[1] == 'E' || magic[1] == 'X'); - } - - /// - /// Determine if the magic bytes indicate a Portable Executable - /// - private static bool IsPE(byte[] magic) - { - if (magic == null || magic.Length < 4) - return false; - - return magic[0] == 'P' && magic[1] == 'E' && magic[2] == '\0' && magic[3] == '\0'; - } - #endregion } } diff --git a/Test/Test.csproj b/Test/Test.csproj index 2148eb3a..21f8a8a2 100644 --- a/Test/Test.csproj +++ b/Test/Test.csproj @@ -9,6 +9,7 @@ +