mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-07-08 18:06:34 +00:00
Fix hidden resource parsing
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -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",
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Linq;
|
||||
|
||||
namespace BurnOutSharp.Wrappers
|
||||
{
|
||||
public class MicrosoftCabinet : WrapperBase
|
||||
public partial class MicrosoftCabinet : WrapperBase
|
||||
{
|
||||
#region Pass-Through Properties
|
||||
|
||||
|
||||
1017
BurnOutSharp.Wrappers/MicrosoftCabinet.fdi.cs
Normal file
1017
BurnOutSharp.Wrappers/MicrosoftCabinet.fdi.cs
Normal file
File diff suppressed because it is too large
Load Diff
107
BurnOutSharp/PackerType/EmbeddedExecutable.cs
Normal file
107
BurnOutSharp/PackerType/EmbeddedExecutable.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
README.md
51
README.md
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user