Fix hidden resource parsing

This commit is contained in:
Matt Nadareski
2022-12-30 09:35:35 -08:00
parent 1027956892
commit 6e22bd4c8d
6 changed files with 1162 additions and 31 deletions

2
.vscode/launch.json vendored
View File

@@ -11,7 +11,7 @@
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/Test/bin/Debug/net6.0/Test.dll",
"args": [],
"args": ["R:\\BurnOutSharp Testing Files\\PackerType\\Wise Installer\\_Undetected\\InstallCollapseII.exe"],
"cwd": "${workspaceFolder}/Test",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",

View File

@@ -300,7 +300,7 @@ namespace BurnOutSharp.Builders
// Try to parse the resource directory table
data.Seek(resourceTableAddress, SeekOrigin.Begin);
var resourceDirectoryTable = ParseResourceDirectoryTable(data, data.Position, executable.SectionTable, optionalHeader.ResourceTable.Size, true);
var resourceDirectoryTable = ParseResourceDirectoryTable(data, data.Position, executable.SectionTable, true);
if (resourceDirectoryTable == null)
return null;
@@ -1195,10 +1195,9 @@ namespace BurnOutSharp.Builders
/// <param name="data">Stream to parse</param>
/// <param name="initialOffset">Initial offset to use in address comparisons</param>
/// <param name="sections">Section table to use for virtual address translation</param>
/// <param name="size">Indicates the size of the section, only used for top-level</param>
/// <param name="topLevel">Indicates if this is the top level or not</param>
/// <returns>Filled resource directory table on success, null on error</returns>
private static ResourceDirectoryTable ParseResourceDirectoryTable(Stream data, long initialOffset, SectionHeader[] sections, uint size = 0, bool topLevel = false)
private static ResourceDirectoryTable ParseResourceDirectoryTable(Stream data, long initialOffset, SectionHeader[] sections, bool topLevel = false)
{
// TODO: Use marshalling here instead of building
var resourceDirectoryTable = new ResourceDirectoryTable();
@@ -1293,6 +1292,13 @@ namespace BurnOutSharp.Builders
if (!topLevel)
return resourceDirectoryTable;
// If we're not aligned to a section
if (!sections.Any(s => s.PointerToRawData == initialOffset))
return resourceDirectoryTable;
// Get the section size
int size = (int)sections.First(s => s.PointerToRawData == initialOffset).SizeOfRawData;
// Align to the 1024-byte boundary
while (data.Position - initialOffset < size && data.Position % 1024 != 0)
_ = data.ReadByteValue();
@@ -1301,7 +1307,7 @@ namespace BurnOutSharp.Builders
if (data.Position - initialOffset < size)
{
Array.Resize(ref resourceDirectoryTable.Entries, totalEntryCount + 1);
int length = (int)(data.Position - initialOffset);
int length = (int)(size - data.Position - initialOffset);
resourceDirectoryTable.Entries[totalEntryCount] = new ResourceDirectoryEntry
{

View File

@@ -5,7 +5,7 @@ using System.Linq;
namespace BurnOutSharp.Wrappers
{
public class MicrosoftCabinet : WrapperBase
public partial class MicrosoftCabinet : WrapperBase
{
#region Pass-Through Properties

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using BurnOutSharp.Interfaces;
using BurnOutSharp.Matching;
using BurnOutSharp.Wrappers;
namespace BurnOutSharp.PackerType
{
/// <summary>
/// Though not technically a packer, this detection is for any executables that include
/// others in their resources in some uncompressed manner to be used at runtime.
/// </summary>
public class EmbeddedExecutable : IPortableExecutableCheck, IScannable
{
/// <inheritdoc/>
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
{
// Get the sections from the executable, if possible
var sections = pex?.SectionTable;
if (sections == null)
return null;
// Get the resources that have an executable signature
if (pex.ResourceData?.Any(kvp => kvp.Value is byte[] ba && ba.StartsWith(Models.MSDOS.Constants.SignatureBytes)) == true)
return "Embedded Executable";
return null;
}
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
}
}
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
{
// Parse into an executable again for easier extraction
PortableExecutable pex = PortableExecutable.Create(stream);
if (pex?.ResourceData == null)
return null;
// Get the resources that have an executable signature
var resources = pex.ResourceData
.Where(kvp => kvp.Value != null && kvp.Value is byte[])
.Where(kvp => (kvp.Value as byte[]).StartsWith(Models.MSDOS.Constants.SignatureBytes))
.ToList();
// If any of the individual extractions fail
try
{
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
for (int i = 0; i < resources.Count; i++)
{
// Get the resource data
var resource = resources[i];
byte[] data = resource.Value as byte[];
// Create the temp filename
string tempFile = $"embedded_resource_{i}.bin";
tempFile = Path.Combine(tempPath, tempFile);
// Write the resource data to a temp file
using (Stream tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
tempStream.Write(data, 0, data.Length);
}
}
// Collect and format all found protections
var protections = scanner.GetProtections(tempPath);
// If temp directory cleanup fails
try
{
Directory.Delete(tempPath, true);
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
}
// Remove temporary path references
Utilities.Dictionary.StripFromKeys(protections, tempPath);
return protections;
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
}
return null;
}
}
}

View File

@@ -115,31 +115,32 @@ Below is a list of protections detected by BurnOutSharp. The two columns explain
Below is a list of executable packers detected by BurnOutSharp. The three columns explain what sort of checks are performed to determine how the protection is detected as well as if the contents can be extracted.
| Protection Name | Content Check | Path Check | Extractable |
| --------------- | ------------- | ---------- | ----------- |
| 7-zip SFX | Yes | No | No |
| Advanced Installer / Caphyon Advanced Installer | Yes | No | No |
| Armadillo | Yes | No | No |
| ASPack | Yes | No | No |
| AutoPlay Media Studio | Yes | No | No |
| CExe | Yes | No | Yes |
| dotFuscator | Yes | No | No |
| EXE Stealth | Yes | No | No |
| Gentee Installer | Yes | No | No |
| Inno Setup | Yes | No | No |
| InstallAnywhere | Yes | No | No |
| Installer VISE | Yes | No | No |
| Intel Installation Framework | Yes | No | No |
| Microsoft CAB SFX | Yes | No | No |
| NSIS | Yes | No | No |
| PECompact | Yes | No | No |
| PEtite | Yes | No | No |
| Setup Factory | Yes | No | No |
| Shrinker | Yes | No | No |
| UPX and UPX (NOS Variant) | Yes | No | No |
| WinRAR SFX | Yes | No | Yes |
| WinZip SFX | Yes | No | Yes |
| WISE Installer | Yes | No | Yes |
| Protection Name | Content Check | Path Check | Extractable | Notes |
| --------------- | ------------- | ---------- | ----------- | ----- |
| 7-zip SFX | Yes | No | No | |
| Advanced Installer / Caphyon Advanced Installer | Yes | No | No | |
| Armadillo | Yes | No | No | |
| ASPack | Yes | No | No | |
| AutoPlay Media Studio | Yes | No | No | |
| CExe | Yes | No | Yes | |
| dotFuscator | Yes | No | No | |
| Embedded Executable | Yes | No | Yes | Not technically a packer |
| EXE Stealth | Yes | No | No | |
| Gentee Installer | Yes | No | No | |
| Inno Setup | Yes | No | No | |
| InstallAnywhere | Yes | No | No | |
| Installer VISE | Yes | No | No | |
| Intel Installation Framework | Yes | No | No | |
| Microsoft CAB SFX | Yes | No | No | |
| NSIS | Yes | No | No | |
| PECompact | Yes | No | No | |
| PEtite | Yes | No | No | |
| Setup Factory | Yes | No | No | |
| Shrinker | Yes | No | No | |
| UPX and UPX (NOS Variant) | Yes | No | No | |
| WinRAR SFX | Yes | No | Yes | |
| WinZip SFX | Yes | No | Yes | |
| WISE Installer | Yes | No | Yes | |
## Container Formats