From a376041be4dabbbc451e4b83c2c65124c18ef4e3 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 4 Jan 2023 22:43:11 -0800 Subject: [PATCH] Separate out Wise PE extraction --- BurnOutSharp/PackerType/WiseInstaller.cs | 235 +++++++++++++---------- 1 file changed, 131 insertions(+), 104 deletions(-) diff --git a/BurnOutSharp/PackerType/WiseInstaller.cs b/BurnOutSharp/PackerType/WiseInstaller.cs index bd9c2a0f..89056755 100644 --- a/BurnOutSharp/PackerType/WiseInstaller.cs +++ b/BurnOutSharp/PackerType/WiseInstaller.cs @@ -96,10 +96,138 @@ namespace BurnOutSharp.PackerType string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(tempPath); - // Parse into an executable again for easier extraction + // TODO: Include NE parsing + + // Try to parse as a Portable Executable PortableExecutable pex = PortableExecutable.Create(stream); - if (pex == null) - return null; + if (pex != null) + return ScanPortableExecutable(scanner, pex, file); + + return null; + } + catch (Exception ex) + { + if (scanner.IncludeDebug) Console.WriteLine(ex); + } + + return null; + } + + /// + /// Checks an NE header to see if it matches a known signature + /// + /// New executable to check + /// True if it matches a known version, false otherwise + private bool MatchesNEVersion(NewExecutable nex) + { + // TODO: Offset is _not_ the EXE header address, rather where the data starts. Fix this. + switch (nex.Stub_NewExeHeaderAddr) + { + // Dll = false, ArchiveStart = 0x11, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = true + case 0x84b0: return true; + + // Dll = false, ArchiveStart = 0x1e, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false + case 0x3e10: return true; + + // Dll = false, ArchiveStart = 0x1e, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false + case 0x3e50: return true; + + // Dll = false, ArchiveStart = 0x1e, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false + case 0x3c20: return true; + + // Dll = false, ArchiveStart = 0x22, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false + case 0x3c30: return true; + + // Dll = false, ArchiveStart = 0x40, ArchiveEnd = 0x3c, InitText = false, FilenamePosition = 0x04, NoCrc = false + case 0x3660: return true; + + // Dll = false, ArchiveStart = 0x48, ArchiveEnd = 0x44, InitText = false, FilenamePosition = 0x1c, NoCrc = false + case 0x36f0: return true; + + // Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false + case 0x3770: return true; + + // Dll = true, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false + case 0x3780: return true; + + // Dll = true, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false + case 0x37b0: return true; + + // Dll = true, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false + case 0x37d0: return true; + + // Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false + case 0x3c80: return true; + + // Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false + case 0x3bd0: return true; + + // Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false + case 0x3c10: return true; + + default: return false; + } + } + + /// + /// Checks a PE header to see if it matches a known signature + /// + /// Portable executable to check + /// True if it matches a known version, false otherwise + private FormatProperty GetPEFormat(PortableExecutable pex) + { + if (pex.OverlayAddress == 0x6e00 + && pex.GetFirstSection(".text")?.VirtualSize == 0x3cf4 + && pex.GetFirstSection(".data")?.VirtualSize == 0x1528) + return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; + + else if (pex.OverlayAddress == 0x6e00 + && pex.GetFirstSection(".text")?.VirtualSize == 0x3cf4 + && pex.GetFirstSection(".data")?.VirtualSize == 0x1568) + return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; + + else if (pex.OverlayAddress == 0x6e00 + && pex.GetFirstSection(".text")?.VirtualSize == 0x3d54) + return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; + + else if (pex.OverlayAddress == 0x6e00 + && pex.GetFirstSection(".text")?.VirtualSize == 0x3d44) + return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; + + else if (pex.OverlayAddress == 0x6e00 + && pex.GetFirstSection(".text")?.VirtualSize == 0x3d04) + return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; + + // Found in Binary.WiseCustomCalla + else if (pex.OverlayAddress == 0x6200) + return new FormatProperty { Dll = true, ArchiveStart = 0x62, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false }; + + else if (pex.OverlayAddress == 0x3000) + return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; + + else if (pex.OverlayAddress == 0x3800) + return new FormatProperty { Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false }; + + else if (pex.OverlayAddress == 0x3a00) + return new FormatProperty { Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false }; + + return null; + } + + /// + /// Attempt to extract Wise data from a Portable Executable + /// + /// Scanner object for state tracking + /// Portable executable to check + /// Path to the input file + /// True if it matches a known version, false otherwise + private ConcurrentDictionary> ScanPortableExecutable(Scanner scanner, PortableExecutable pex, string file) + { + // If the installer file itself fails + try + { + string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + Directory.CreateDirectory(tempPath); // Get the matching PE format var format = GetPEFormat(pex); @@ -234,107 +362,6 @@ namespace BurnOutSharp.PackerType return null; } - /// - /// Checks an NE header to see if it matches a known signature - /// - /// New executable to check - /// True if it matches a known version, false otherwise - private bool MatchesNEVersion(NewExecutable nex) - { - // TODO: Offset is _not_ the EXE header address, rather where the data starts. Fix this. - switch (nex.Stub_NewExeHeaderAddr) - { - // Dll = false, ArchiveStart = 0x11, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = true - case 0x84b0: return true; - - // Dll = false, ArchiveStart = 0x1e, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false - case 0x3e10: return true; - - // Dll = false, ArchiveStart = 0x1e, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false - case 0x3e50: return true; - - // Dll = false, ArchiveStart = 0x1e, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false - case 0x3c20: return true; - - // Dll = false, ArchiveStart = 0x22, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false - case 0x3c30: return true; - - // Dll = false, ArchiveStart = 0x40, ArchiveEnd = 0x3c, InitText = false, FilenamePosition = 0x04, NoCrc = false - case 0x3660: return true; - - // Dll = false, ArchiveStart = 0x48, ArchiveEnd = 0x44, InitText = false, FilenamePosition = 0x1c, NoCrc = false - case 0x36f0: return true; - - // Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false - case 0x3770: return true; - - // Dll = true, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false - case 0x3780: return true; - - // Dll = true, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false - case 0x37b0: return true; - - // Dll = true, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false - case 0x37d0: return true; - - // Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false - case 0x3c80: return true; - - // Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false - case 0x3bd0: return true; - - // Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false - case 0x3c10: return true; - - default: return false; - } - } - - /// - /// Checks a PE header to see if it matches a known signature - /// - /// Portable executable to check - /// True if it matches a known version, false otherwise - private FormatProperty GetPEFormat(PortableExecutable pex) - { - if (pex.OverlayAddress == 0x6e00 - && pex.GetFirstSection(".text")?.VirtualSize == 0x3cf4 - && pex.GetFirstSection(".data")?.VirtualSize == 0x1528) - return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; - - else if (pex.OverlayAddress == 0x6e00 - && pex.GetFirstSection(".text")?.VirtualSize == 0x3cf4 - && pex.GetFirstSection(".data")?.VirtualSize == 0x1568) - return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; - - else if (pex.OverlayAddress == 0x6e00 - && pex.GetFirstSection(".text")?.VirtualSize == 0x3d54) - return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; - - else if (pex.OverlayAddress == 0x6e00 - && pex.GetFirstSection(".text")?.VirtualSize == 0x3d44) - return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; - - else if (pex.OverlayAddress == 0x6e00 - && pex.GetFirstSection(".text")?.VirtualSize == 0x3d04) - return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; - - // Found in Binary.WiseCustomCalla - else if (pex.OverlayAddress == 0x6200) - return new FormatProperty { Dll = true, ArchiveStart = 0x62, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false }; - - else if (pex.OverlayAddress == 0x3000) - return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false }; - - else if (pex.OverlayAddress == 0x3800) - return new FormatProperty { Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false }; - - else if (pex.OverlayAddress == 0x3a00) - return new FormatProperty { Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false }; - - return null; - } - /// /// Class representing the properties of each recognized Wise installer format ///