Compare commits

...

95 Commits
2.7.0 ... 2.8.0

Author SHA1 Message Date
Matt Nadareski
aeb379f307 Bump version to 2.8 2023-07-14 11:37:17 -04:00
TheRogueArchivist
cae0edfb49 Add DRML links to Denuvo AC and PlayJ (#259) 2023-07-14 08:35:09 -07:00
TheRogueArchivist
e97558db1f Add new HexaLock check (#254) 2023-05-30 17:56:19 -07:00
Matt Nadareski
06ecc1a571 Temporarily disable MS-CAB extraction
This only affects the code for normal protection scans. This does not affect trying to run extract separately, mainly for the purposes of testing.
2023-05-30 13:43:35 -04:00
TheRogueArchivist
adcf9ee27e Add hash check for RipGuard (#252)
* Add hash check for RipGuard

* Make sure the file exists before trying to hash it

* It's the safety dance
2023-05-14 12:45:30 -07:00
TheRogueArchivist
a8c759be55 Add basic RipGuard detection (#251)
* Add basic RipGuard detection and notes.
2023-05-04 05:24:33 -07:00
Matt Nadareski
ecf97de439 Use larger output buffer for MSZIP 2023-04-28 15:14:28 -04:00
TheRogueArchivist
f134de6609 Minor SecDrv cleanup (#249)
Update comments and improve output.
2023-04-22 18:18:09 -07:00
TheRogueArchivist
d91ce3100b Overhaul Macrovision and related protections (#248)
* Improve several SafeCast checks

* Add new SafeCast versions.

* Add SafeCast NE checks.

* Move stxt* checks to Macrovision, and add SafeCast specific check.

* Confirm SafeCast file and add relevant executable checks.

* Add empty file detection for some SafeDisc drivers.

* Various Macrovision improvements

* Move and improve stxt* section checks.

* Add proper Redump entry number for Puyo Puyo Fever.

* Add directory separator to some SafeDisc checks to avoid false positives.

* Add SafeWrap skeleton with notes.

* Minor Macrovision fixes

* Fix stxt* section checks.

* Add product identification for one CDS-300 version.

* Further Macrovision improvements

* Add product detection via version for SafeDisc Lite and SafeCast ESD.

* Add improved SafeDisc LT/Lite checks.

* Add various notes about SafeCast/SafeDisc.

* Add new secdrv version detection.

* Herald the upcoming secdrv cataclysm.

* Move SecDrv checks into Macrovision

* Move SecDrv checks into Macrovision, as it's known to be present on multiple Macrovision products.

* Improve SafeCast checks

* Add new SafeCast executable and path checks.

* Change a C-Dilla output.

* ah sweet, man-made horrors beyond my comprehension

* Split new and old "BoG" string checks to make finding an expunged version easier.

* Confirm unconfirmed SafeCast version, add new unconfirmed version.

* Remove now unneeded result list cleaning.

* Improve SafeCast notes.

* Add new SafeCast file description and file name checks.

* Remove "GetSafeDisc320to4xVersion" and improve CLCD16 version report.

* Address PR comments

* Address further PR comments
2023-04-21 19:38:18 -07:00
Matt Nadareski
20de40014d Fix version info reading 2023-03-27 10:46:05 -04:00
TheRogueArchivist
a7f9a99d10 Overhaul SVKP (#246)
* Begin SVKP Overhaul

* Add several entry point checks for SVKP, as well as a section check.

* Add SVKP notes.

* Add unconfirmed message in various ActiveMARK checks.

* Add file detections for SVKP

* Add file detections for SVKP.
* Cleanup notes.
* Update README.
2023-03-24 07:35:37 -07:00
TheRogueArchivist
4bdfbabaab Add new SafeDisc DrvMgt detection (#247)
* Add new SafeDisc DrvMgt detection.
2023-03-24 06:03:56 -07:00
TheRogueArchivist
5465c57d96 Add NeoLite detection (#245)
* Add NeoLite detection.
* Update README.
2023-03-22 11:26:25 -07:00
TheRogueArchivist
5082c8f705 Add RenderWare detection (#244)
* Add RenderWare detection.
* Remove unneeded note from SafeDisc.
* Update README.
2023-03-22 10:20:22 -07:00
Matt Nadareski
509fff4684 Reset state.ll for dynamic 2023-03-21 14:14:17 -04:00
Matt Nadareski
9d2c14f809 Fix MSZIP signature check (nw) 2023-03-21 13:39:25 -04:00
Matt Nadareski
b023549b87 Add note for IExtractable 2023-03-21 13:14:42 -04:00
Matt Nadareski
0983073538 Add game engine detection skeleton 2023-03-21 10:42:14 -04:00
TheRogueArchivist
815acf2ce0 Add NEAC Protect detection (#241)
* Add NEAC Protect detection

* Add NEAC Protect detection.
* Update README.

* Address PR comments
2023-03-16 12:38:30 -07:00
Matt Nadareski
6b8596466b Add unused MS-DOS executable check interface 2023-03-15 16:12:12 -04:00
Matt Nadareski
1e5bb7df64 Simplify packer handling code 2023-03-15 15:58:19 -04:00
Matt Nadareski
e920bfc69c Executable is not inherently extractable 2023-03-15 15:53:24 -04:00
Matt Nadareski
a85c6f4028 Rearrange Executable-related things 2023-03-15 15:51:38 -04:00
Matt Nadareski
a75bc15f29 Update IPathCheck helper a bit 2023-03-15 14:21:02 -04:00
Matt Nadareski
659aa30fb3 Update names, access permissions 2023-03-15 14:16:20 -04:00
Matt Nadareski
54a11916d2 Cleanup namespaces 2023-03-15 13:16:21 -04:00
Matt Nadareski
47f423d092 Implement IPathCheck helper 2023-03-15 12:55:08 -04:00
Matt Nadareski
5c5e68e31d Gut Executable for now 2023-03-15 11:37:20 -04:00
Matt Nadareski
9e917e2bb9 Create new Scanner helper classes 2023-03-15 11:06:29 -04:00
Matt Nadareski
4bd4d2f395 Remove errant using statement 2023-03-13 22:58:37 -04:00
Matt Nadareski
6406248840 Make extractable packers safer 2023-03-13 22:53:57 -04:00
Matt Nadareski
3d8134bbd3 Map out Executable extraction skeleton 2023-03-13 22:36:28 -04:00
Matt Nadareski
15310a6c47 Change namespaces but don't move yet 2023-03-13 22:22:52 -04:00
Matt Nadareski
450a8cd5bd Migrate wrapper methods to proper factory 2023-03-13 22:07:28 -04:00
Matt Nadareski
088f99942f Move file type helpers to Utilities 2023-03-13 22:03:10 -04:00
Matt Nadareski
3e97bd8d2d Move SupportedFileType to correct namespace 2023-03-13 21:54:40 -04:00
Matt Nadareski
866051c975 Fix MPQ namespace 2023-03-13 21:49:25 -04:00
Matt Nadareski
0be437f3cf Add skeleton to Scanner helpers 2023-03-13 21:47:40 -04:00
Matt Nadareski
11f3dec65d Add more notes about extraction 2023-03-13 21:45:17 -04:00
Matt Nadareski
912d151164 Add skeleton implementions in Executable 2023-03-13 21:12:11 -04:00
Matt Nadareski
863678f850 Add extractable protections to caches 2023-03-13 21:05:18 -04:00
Matt Nadareski
b82a6a8c5d Simplify some Executable code
Hopefully, simplifying this code will open the door to getting rid of `IScannable` in some way
2023-03-13 20:49:59 -04:00
Matt Nadareski
ab2daf2a80 Fix helper in Executable 2023-03-13 20:39:50 -04:00
Matt Nadareski
f734e3a58a Move MPQ to proper library, fix stormlibsharp 2023-03-13 16:41:53 -04:00
Matt Nadareski
212981fda9 Move stormlibsharp to Compression 2023-03-13 16:31:34 -04:00
Matt Nadareski
c64e138ba7 Figure out how to convert Textfile 2023-03-13 16:17:21 -04:00
Matt Nadareski
c43353d126 Move most detectables to new interface 2023-03-13 16:06:45 -04:00
Matt Nadareski
d439ba9592 Add unused IDetectable interface 2023-03-13 15:34:26 -04:00
Matt Nadareski
b7f06f0b59 Move extractable file types to new library 2023-03-10 13:48:24 -05:00
Matt Nadareski
60d666f8be Add skeleton file type library 2023-03-10 11:55:19 -05:00
Matt Nadareski
4ff4c2afef Move helper methods used in a single place 2023-03-10 11:41:08 -05:00
Matt Nadareski
655b8385f9 Rename tool class 2023-03-10 11:20:35 -05:00
Matt Nadareski
439c141c2c Move packer scans to their own library 2023-03-09 23:52:58 -05:00
Matt Nadareski
95755b930d Add packer library skeleton 2023-03-09 23:31:45 -05:00
Matt Nadareski
9cf54c1f2d Create dummy class for protection library 2023-03-09 23:26:18 -05:00
Matt Nadareski
e118418a23 Move protection scans to their own library
This change also removes a couple of things from `BurnOutSharp.Tools.Utilities` that are no longer needed there. Linear executables are included in the scanning classes. Update the guides accordingly.
2023-03-09 23:19:27 -05:00
Matt Nadareski
a3567d6eb2 Add protection library skeleton 2023-03-09 20:50:59 -05:00
Matt Nadareski
a359143bc7 Include debug in IExtractable 2023-03-09 17:16:39 -05:00
Matt Nadareski
77b7a24d85 Add TODO in Executable 2023-03-09 16:12:21 -05:00
Matt Nadareski
338b2593d5 Update guides 2023-03-09 16:08:56 -05:00
Matt Nadareski
ded5e27355 Migrate packers to extractable only 2023-03-09 16:02:51 -05:00
Matt Nadareski
ee1b005d96 Add call to packer extraction 2023-03-09 15:50:14 -05:00
Matt Nadareski
cd2673d1ba Implement unused packer extractions 2023-03-09 15:46:48 -05:00
Matt Nadareski
41d77085ae Add IExtractable skeletons to packers 2023-03-09 15:33:21 -05:00
Matt Nadareski
67059b2e43 Update guides 2023-03-09 15:17:35 -05:00
Matt Nadareski
f6157ef79b Implementations act the same 2023-03-09 15:07:35 -05:00
Matt Nadareski
6e5d517e82 Replace parts of Scan with Extract 2023-03-09 14:50:24 -05:00
Matt Nadareski
1dca51988a Implement unused extractions 2023-03-09 14:39:26 -05:00
Matt Nadareski
3c064bad55 Add skeleton IExtractable implementations 2023-03-09 14:04:31 -05:00
Matt Nadareski
d60a3ce05a Add extractable interface (unused) 2023-03-09 13:48:51 -05:00
Matt Nadareski
f68438ff8c Remove some errant temp directories 2023-03-09 13:45:42 -05:00
Matt Nadareski
d351f1d08e Create separate Options object 2023-03-09 13:26:20 -05:00
Matt Nadareski
70bdb8f37d Move most interfaces to separate library 2023-03-09 11:52:28 -05:00
TheRogueArchivist
3cd713e078 Add SafeDisc entry point check (#240)
* Add SafeDisc entry point check

* Add SafeDisc entry point check

* Address PR comments
2023-03-08 18:46:14 -08:00
Matt Nadareski
454655de5a Missed a couple in Wrappers 2023-03-08 17:53:26 -05:00
Matt Nadareski
268ed1a6a6 Clean up namespaces in Builders 2023-03-08 17:51:17 -05:00
Matt Nadareski
a42ce601b8 Simplify namespaces in Wrappers 2023-03-08 17:49:14 -05:00
Matt Nadareski
756b37ef6c Minor update for clarity 2023-03-08 17:16:29 -05:00
TheRogueArchivist
ab7e708e02 fuck macrovision (#239)
* Make SafeDisc stxt* section checks more accurate.
* Add unknown SafeDisc section notes.
2023-03-08 14:08:36 -08:00
TheRogueArchivist
326d916c0b Separate unconfirmed Macrovision checks (#238)
* Separate unconfirmed Macrovision checks

* Separate unconfirmed Macrovision checks.

* Separate unconfirmed SafeDisc version

* Separate unconfirmed SafeDisc version.
2023-03-08 13:21:34 -08:00
Matt Nadareski
db09bd931b Macrovision-adjacent additions (TheRogueArchivist) 2023-03-08 15:21:21 -05:00
TheRogueArchivist
d1e9eb90f1 Add DRML link to phenoProtect (#235)
* Add DRML link to phenoProtect.
* Fix case of the "phenoProtect" class name.
2023-03-08 11:59:57 -08:00
Matt Nadareski
20a5c4c78d Use new Macrovision helper method 2023-03-08 09:50:34 -05:00
Matt Nadareski
499f9888b1 Create helper for Macrovision version mapping 2023-03-08 09:40:19 -05:00
Matt Nadareski
7bb3364b43 Trim not TrimEnd 2023-03-08 08:47:46 -05:00
Matt Nadareski
473cbc5694 BOS.* -> BOS.* 2023-03-07 16:59:14 -05:00
Matt Nadareski
e32b24c9f6 BOS.ASN1 -> BOS.ASN1 2023-03-07 12:42:39 -05:00
Matt Nadareski
777fdc14c8 BOS.Utilities -> BOS.Utilities 2023-03-07 12:04:48 -05:00
Matt Nadareski
ffbb01c25c Migrate CDS path checks 2023-03-07 11:31:55 -05:00
Matt Nadareski
47380c2c1c Start migrating CDS, fix Macrovision directory check 2023-03-07 11:28:02 -05:00
Matt Nadareski
51e9121a6b Update generic Macrovision check 2023-03-07 11:22:45 -05:00
Matt Nadareski
94f51d518d Move SafeDisc-specific checks 2023-03-07 11:19:18 -05:00
Matt Nadareski
8fdc17b239 Missed an access modifier 2023-03-07 11:12:31 -05:00
Matt Nadareski
42bb29185f Macrovision cleanup 2023-03-07 11:10:56 -05:00
Matt Nadareski
05ae0f4e80 Add .NET 7 support 2023-03-06 09:34:51 -05:00
693 changed files with 5748 additions and 5065 deletions

4
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "BurnOutSharp/External/stormlibsharp"]
path = BurnOutSharp/External/stormlibsharp
[submodule "BinaryObjectScanner.Compression/_EXTERNAL/stormlibsharp"]
path = BinaryObjectScanner.Compression/_EXTERNAL/stormlibsharp
url = https://github.com/robpaveza/stormlibsharp.git

View File

@@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace BurnOutSharp.ASN1
namespace BinaryObjectScanner.ASN1
{
/// <summary>
/// ASN.1 Parser

View File

@@ -1,17 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;net6.0</TargetFrameworks>
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Title>BurnOutSharp.ASN1</Title>
<AssemblyName>BurnOutSharp.ASN1</AssemblyName>
<Title>BinaryObjectScanner.ASN1</Title>
<AssemblyName>BinaryObjectScanner.ASN1</AssemblyName>
<Authors>Matt Nadareski</Authors>
<Product>BurnOutSharp</Product>
<Copyright>Copyright (c)2022 Matt Nadareski</Copyright>
<RepositoryUrl>https://github.com/mnadareski/BurnOutSharp</RepositoryUrl>
<Version>2.7</Version>
<AssemblyVersion>2.7</AssemblyVersion>
<FileVersion>2.7</FileVersion>
<Version>2.8</Version>
<AssemblyVersion>2.8</AssemblyVersion>
<FileVersion>2.8</FileVersion>
<IncludeSource>true</IncludeSource>
<IncludeSymbols>true</IncludeSymbols>
</PropertyGroup>
@@ -21,7 +21,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\BurnOutSharp.Utilities\BurnOutSharp.Utilities.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Utilities\BinaryObjectScanner.Utilities.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,6 +1,6 @@
using System;
namespace BurnOutSharp.ASN1
namespace BinaryObjectScanner.ASN1
{
/// <summary>
/// ASN.1 type indicators

View File

@@ -1,4 +1,4 @@
namespace BurnOutSharp.ASN1
namespace BinaryObjectScanner.ASN1
{
#pragma warning disable IDE0011

View File

@@ -1,7 +1,7 @@
using System.Linq;
using System.Text;
namespace BurnOutSharp.ASN1
namespace BinaryObjectScanner.ASN1
{
#pragma warning disable IDE0011

View File

@@ -1,7 +1,7 @@
using System.Linq;
using System.Text;
namespace BurnOutSharp.ASN1
namespace BinaryObjectScanner.ASN1
{
#pragma warning disable IDE0011

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
namespace BurnOutSharp.ASN1
namespace BinaryObjectScanner.ASN1
{
/// <summary>
/// Methods related to Object Identifiers (OID)

View File

@@ -1,4 +1,4 @@
namespace BurnOutSharp.ASN1
namespace BinaryObjectScanner.ASN1
{
#pragma warning disable IDE0011

View File

@@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using BurnOutSharp.Utilities;
using BinaryObjectScanner.Utilities;
namespace BurnOutSharp.ASN1
namespace BinaryObjectScanner.ASN1
{
/// <summary>
/// ASN.1 type/length/value class that all types are based on

View File

@@ -2,10 +2,10 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.AACS;
using BurnOutSharp.Utilities;
using BinaryObjectScanner.Models.AACS;
using BinaryObjectScanner.Utilities;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public class AACS
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.BDPlus;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.BDPlus.Constants;
using BinaryObjectScanner.Models.BDPlus;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.BDPlus.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public class BDPlus
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.BFPK;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.BFPK.Constants;
using BinaryObjectScanner.Models.BFPK;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.BFPK.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public class BFPK
{

View File

@@ -1,11 +1,11 @@
using System.IO;
using System.Linq;
using System.Text;
using BurnOutSharp.Models.BSP;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.BSP.Constants;
using BinaryObjectScanner.Models.BSP;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.BSP.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class BSP
{

View File

@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Title>BinaryObjectScanner.Builders</Title>
<AssemblyName>BinaryObjectScanner.Builders</AssemblyName>
<Authors>Matt Nadareski</Authors>
<Product>BurnOutSharp</Product>
<Copyright>Copyright (c)2022 Matt Nadareski</Copyright>
<RepositoryUrl>https://github.com/mnadareski/BurnOutSharp</RepositoryUrl>
<Version>2.8</Version>
<AssemblyVersion>2.8</AssemblyVersion>
<FileVersion>2.8</FileVersion>
<IncludeSource>true</IncludeSource>
<IncludeSymbols>true</IncludeSymbols>
</PropertyGroup>
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\BinaryObjectScanner.Models\BinaryObjectScanner.Models.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Utilities\BinaryObjectScanner.Utilities.csproj" />
</ItemGroup>
</Project>

View File

@@ -2,11 +2,11 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.CFB;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.CFB.Constants;
using BinaryObjectScanner.Models.CFB;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.CFB.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public class CFB
{

View File

@@ -4,9 +4,9 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using BurnOutSharp.Utilities;
using BinaryObjectScanner.Utilities;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class Extensions
{
@@ -1228,6 +1228,7 @@ namespace BurnOutSharp.Builders
int currentOffset = offset;
offset += 6;
string nextKey = entry.Data.ReadString(ref offset, Encoding.Unicode);
offset = currentOffset;
@@ -1278,12 +1279,18 @@ namespace BurnOutSharp.Builders
{
var stringFileInfo = new Models.PortableExecutable.StringFileInfo();
// Cache the initial offset
int currentOffset = offset;
stringFileInfo.Length = data.ReadUInt16(ref offset);
stringFileInfo.ValueLength = data.ReadUInt16(ref offset);
stringFileInfo.ResourceType = (Models.PortableExecutable.VersionResourceType)data.ReadUInt16(ref offset);
stringFileInfo.Key = data.ReadString(ref offset, Encoding.Unicode);
if (stringFileInfo.Key != "StringFileInfo")
{
offset -= 6 + ((stringFileInfo.Key.Length + 1) * 2);
return null;
}
// Align to the DWORD boundary if we're not at the end
if (offset != data.Length)
@@ -1293,7 +1300,7 @@ namespace BurnOutSharp.Builders
}
var stringFileInfoChildren = new List<Models.PortableExecutable.StringTable>();
while (offset < stringFileInfo.Length)
while ((offset - currentOffset) < stringFileInfo.Length)
{
var stringTable = new Models.PortableExecutable.StringTable();
@@ -1310,7 +1317,7 @@ namespace BurnOutSharp.Builders
}
var stringTableChildren = new List<Models.PortableExecutable.StringData>();
while (offset < stringTable.Length)
while ((offset - currentOffset) < stringTable.Length)
{
var stringData = new Models.PortableExecutable.StringData();
@@ -1362,6 +1369,9 @@ namespace BurnOutSharp.Builders
{
var varFileInfo = new Models.PortableExecutable.VarFileInfo();
// Cache the initial offset
int initialOffset = offset;
varFileInfo.Length = data.ReadUInt16(ref offset);
varFileInfo.ValueLength = data.ReadUInt16(ref offset);
varFileInfo.ResourceType = (Models.PortableExecutable.VersionResourceType)data.ReadUInt16(ref offset);
@@ -1377,7 +1387,7 @@ namespace BurnOutSharp.Builders
}
var varFileInfoChildren = new List<Models.PortableExecutable.VarData>();
while (offset < varFileInfo.Length)
while ((offset - initialOffset) < varFileInfo.Length)
{
var varData = new Models.PortableExecutable.VarData();
@@ -1386,7 +1396,10 @@ namespace BurnOutSharp.Builders
varData.ResourceType = (Models.PortableExecutable.VersionResourceType)data.ReadUInt16(ref offset);
varData.Key = data.ReadString(ref offset, Encoding.Unicode);
if (varData.Key != "Translation")
{
offset -= 6 + ((varData.Key.Length + 1) * 2);
return null;
}
// Align to the DWORD boundary if we're not at the end
if (offset != data.Length)
@@ -1395,8 +1408,11 @@ namespace BurnOutSharp.Builders
varData.Padding = data.ReadByte(ref offset);
}
// Cache the current offset
int currentOffset = offset;
var varDataValue = new List<uint>();
while (offset < (varData.ValueLength * sizeof(ushort)))
while ((offset - currentOffset) < varData.ValueLength)
{
uint languageAndCodeIdentifierPair = data.ReadUInt32(ref offset);
varDataValue.Add(languageAndCodeIdentifierPair);

View File

@@ -1,10 +1,10 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.GCF;
using BurnOutSharp.Utilities;
using BinaryObjectScanner.Models.GCF;
using BinaryObjectScanner.Utilities;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class GCF
{

View File

@@ -1,11 +1,11 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.InstallShieldCabinet;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.InstallShieldCabinet.Constants;
using BinaryObjectScanner.Models.InstallShieldCabinet;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.InstallShieldCabinet.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
// TODO: Add multi-cabinet reading
public class InstallShieldCabinet

View File

@@ -1,11 +1,11 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.LinearExecutable;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.LinearExecutable.Constants;
using BinaryObjectScanner.Models.LinearExecutable;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.LinearExecutable.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class LinearExecutable
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.MSDOS;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.MSDOS.Constants;
using BinaryObjectScanner.Models.MSDOS;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.MSDOS.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class MSDOS
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.MicrosoftCabinet;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.MicrosoftCabinet.Constants;
using BinaryObjectScanner.Models.MicrosoftCabinet;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.MicrosoftCabinet.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
// TODO: Add multi-cabinet reading
public class MicrosoftCabinet

View File

@@ -2,11 +2,11 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.MoPaQ;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.MoPaQ.Constants;
using BinaryObjectScanner.Models.MoPaQ;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.MoPaQ.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public class MoPaQ
{

View File

@@ -1,11 +1,11 @@
using System;
using System.IO;
using System.Text;
using BurnOutSharp.Models.N3DS;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.N3DS.Constants;
using BinaryObjectScanner.Models.N3DS;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.N3DS.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public class N3DS
{

View File

@@ -1,10 +1,10 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.NCF;
using BurnOutSharp.Utilities;
using BinaryObjectScanner.Models.NCF;
using BinaryObjectScanner.Utilities;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class NCF
{

View File

@@ -2,11 +2,11 @@
using System.IO;
using System.Linq;
using System.Text;
using BurnOutSharp.Models.NewExecutable;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.NewExecutable.Constants;
using BinaryObjectScanner.Models.NewExecutable;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.NewExecutable.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class NewExecutable
{

View File

@@ -1,10 +1,10 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.Nitro;
using BurnOutSharp.Utilities;
using BinaryObjectScanner.Models.Nitro;
using BinaryObjectScanner.Utilities;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public class Nitro
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.PAK;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.PAK.Constants;
using BinaryObjectScanner.Models.PAK;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.PAK.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class PAK
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.PFF;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.PFF.Constants;
using BinaryObjectScanner.Models.PFF;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.PFF.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public class PFF
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.PlayJ;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.PlayJ.Constants;
using BinaryObjectScanner.Models.PlayJ;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.PlayJ.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public class PlayJ
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using BurnOutSharp.Models.PortableExecutable;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.PortableExecutable.Constants;
using BinaryObjectScanner.Models.PortableExecutable;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.PortableExecutable.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class PortableExecutable
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.Quantum;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.Quantum.Constants;
using BinaryObjectScanner.Models.Quantum;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.Quantum.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public class Quantum
{

View File

@@ -1,11 +1,11 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.SGA;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.SGA.Constants;
using BinaryObjectScanner.Models.SGA;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.SGA.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class SGA
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.VBSP;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.VBSP.Constants;
using BinaryObjectScanner.Models.VBSP;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.VBSP.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class VBSP
{

View File

@@ -1,11 +1,11 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.VPK;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.VPK.Constants;
using BinaryObjectScanner.Models.VPK;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.VPK.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class VPK
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.WAD;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.WAD.Constants;
using BinaryObjectScanner.Models.WAD;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.WAD.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class WAD
{

View File

@@ -1,10 +1,10 @@
using System.IO;
using System.Text;
using BurnOutSharp.Models.XZP;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.XZP.Constants;
using BinaryObjectScanner.Models.XZP;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.XZP.Constants;
namespace BurnOutSharp.Builders
namespace BinaryObjectScanner.Builders
{
public static class XZP
{

View File

@@ -1,4 +1,4 @@
namespace BurnOutSharp.Compression.ADPCM
namespace BinaryObjectScanner.Compression.ADPCM
{
/// <see href="https://github.com/ladislav-zezula/StormLib/blob/master/src/adpcm/adpcm.cpp"/>
public unsafe struct ADPCM_DATA

View File

@@ -1,7 +1,7 @@
using static BurnOutSharp.Compression.ADPCM.Constants;
using static BurnOutSharp.Compression.ADPCM.Helper;
using static BinaryObjectScanner.Compression.ADPCM.Constants;
using static BinaryObjectScanner.Compression.ADPCM.Helper;
namespace BurnOutSharp.Compression.ADPCM
namespace BinaryObjectScanner.Compression.ADPCM
{
public unsafe class Compressor
{

View File

@@ -1,4 +1,4 @@
namespace BurnOutSharp.Compression.ADPCM
namespace BinaryObjectScanner.Compression.ADPCM
{
/// <see href="https://github.com/ladislav-zezula/StormLib/blob/master/src/adpcm/adpcm.h"/>
public static class Constants

View File

@@ -1,7 +1,7 @@
using static BurnOutSharp.Compression.ADPCM.Constants;
using static BurnOutSharp.Compression.ADPCM.Helper;
using static BinaryObjectScanner.Compression.ADPCM.Constants;
using static BinaryObjectScanner.Compression.ADPCM.Helper;
namespace BurnOutSharp.Compression.ADPCM
namespace BinaryObjectScanner.Compression.ADPCM
{
public unsafe class Decompressor
{

View File

@@ -1,6 +1,6 @@
using static BurnOutSharp.Compression.ADPCM.Constants;
using static BinaryObjectScanner.Compression.ADPCM.Constants;
namespace BurnOutSharp.Compression.ADPCM
namespace BinaryObjectScanner.Compression.ADPCM
{
/// <see href="https://github.com/ladislav-zezula/StormLib/blob/master/src/adpcm/adpcm.cpp"/>
internal static unsafe class Helper

View File

@@ -1,4 +1,4 @@
namespace BurnOutSharp.Compression.ADPCM
namespace BinaryObjectScanner.Compression.ADPCM
{
/// <summary>
/// Helper class for writing output ADPCM data

View File

@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Title>BinaryObjectScanner.Compression</Title>
<AssemblyName>BinaryObjectScanner.Compression</AssemblyName>
<Authors>Matt Nadareski</Authors>
<Product>BurnOutSharp</Product>
<Copyright>Copyright (c)2022 Matt Nadareski</Copyright>
<RepositoryUrl>https://github.com/mnadareski/BurnOutSharp</RepositoryUrl>
<Version>2.8</Version>
<AssemblyVersion>2.8</AssemblyVersion>
<FileVersion>2.8</FileVersion>
<IncludeSource>true</IncludeSource>
<IncludeSymbols>true</IncludeSymbols>
</PropertyGroup>
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<!-- These are needed for dealing with submodules -->
<PropertyGroup>
<DefaultItemExcludes>
$(DefaultItemExcludes);
**\AssemblyInfo.cs;
External\stormlibsharp\lib\**;
External\stormlibsharp\TestConsole\**
</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SharpCompress" Version="0.32.2" />
<PackageReference Include="SharpZipLib" Version="1.4.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BinaryObjectScanner.Models\BinaryObjectScanner.Models.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Utilities\BinaryObjectScanner.Utilities.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,11 +1,11 @@
using System.IO;
using System.Linq;
using System.Text;
using BurnOutSharp.Models.Compression.LZ;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.Compression.LZ.Constants;
using BinaryObjectScanner.Models.Compression.LZ;
using BinaryObjectScanner.Utilities;
using static BinaryObjectScanner.Models.Compression.LZ.Constants;
namespace BurnOutSharp.Compression
namespace BinaryObjectScanner.Compression
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/kernel32/lzexpand.c"/>
public class LZ

View File

@@ -1,4 +1,4 @@
namespace BurnOutSharp.Compression.LZX
namespace BinaryObjectScanner.Compression.LZX
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
public class Bits

View File

@@ -1,9 +1,9 @@
using System;
using BurnOutSharp.Models.Compression.LZX;
using static BurnOutSharp.Models.Compression.LZX.Constants;
using static BurnOutSharp.Models.MicrosoftCabinet.Constants;
using BinaryObjectScanner.Compression.LZX;
using static BinaryObjectScanner.Models.Compression.LZX.Constants;
using static BinaryObjectScanner.Models.MicrosoftCabinet.Constants;
namespace BurnOutSharp.Compression.LZX
namespace BinaryObjectScanner.Compression.LZX
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/fdi.c"/>
public class Decompressor

View File

@@ -1,6 +1,6 @@
using static BurnOutSharp.Models.Compression.LZX.Constants;
using static BinaryObjectScanner.Models.Compression.LZX.Constants;
namespace BurnOutSharp.Compression.LZX
namespace BinaryObjectScanner.Compression.LZX
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
public class State

View File

@@ -1,9 +1,9 @@
using System;
using System.Runtime.InteropServices;
using BurnOutSharp.Models.Compression.MSZIP;
using static BurnOutSharp.Models.Compression.MSZIP.Constants;
using BinaryObjectScanner.Models.Compression.MSZIP;
using static BinaryObjectScanner.Models.Compression.MSZIP.Constants;
namespace BurnOutSharp.Compression.MSZIP
namespace BinaryObjectScanner.Compression.MSZIP
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/fdi.c"/>
public unsafe class Decompressor
@@ -21,7 +21,7 @@ namespace BurnOutSharp.Compression.MSZIP
return false;
// CK = Chris Kirmse, official Microsoft purloiner
if (state.inpos[0] != 0x43 || state.inpos[1] != 0x48)
if (state.inpos[0] != 0x43 || state.inpos[1] != 0x4B)
return false;
state.inpos += 2;
@@ -191,6 +191,7 @@ namespace BurnOutSharp.Compression.MSZIP
b = state.bb;
k = state.bk;
state.ll = new uint[288 + 32];
fixed (uint* ll = state.ll)
{
/* read in table lengths */

View File

@@ -1,4 +1,4 @@
namespace BurnOutSharp.Compression.MSZIP
namespace BinaryObjectScanner.Compression.MSZIP
{
public unsafe struct HuffmanNode
{

View File

@@ -1,6 +1,6 @@
using static BurnOutSharp.Models.Compression.MSZIP.Constants;
using static BinaryObjectScanner.Models.Compression.MSZIP.Constants;
namespace BurnOutSharp.Compression.MSZIP
namespace BinaryObjectScanner.Compression.MSZIP
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
public unsafe class State

View File

@@ -1,9 +1,9 @@
using System;
using System.Linq;
using BurnOutSharp.Models.Compression.Quantum;
using BurnOutSharp.Models.MicrosoftCabinet;
using BinaryObjectScanner.Models.Compression.Quantum;
using BinaryObjectScanner.Models.MicrosoftCabinet;
namespace BurnOutSharp.Compression.Quantum
namespace BinaryObjectScanner.Compression.Quantum
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/fdi.c"/>

View File

@@ -1,6 +1,6 @@
using BurnOutSharp.Models.Compression.Quantum;
using BinaryObjectScanner.Models.Compression.Quantum;
namespace BurnOutSharp.Compression.Quantum
namespace BinaryObjectScanner.Compression.Quantum
{
/// <see href="https://github.com/kyz/libmspack/blob/master/libmspack/mspack/qtmd.c"/>
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>

View File

@@ -1,4 +1,4 @@
namespace BurnOutSharp.Compression.bzip2
namespace BinaryObjectScanner.Compression.bzip2
{
/// <see href="https://github.com/ladislav-zezula/StormLib/blob/master/src/bzip2/bzlib.h"/>
/// <see href="https://github.com/ladislav-zezula/StormLib/blob/master/src/bzip2/bzlib_private.h"/>

View File

@@ -1,6 +1,6 @@
using static BurnOutSharp.Compression.bzip2.Constants;
using static BinaryObjectScanner.Compression.bzip2.Constants;
namespace BurnOutSharp.Compression.bzip2
namespace BinaryObjectScanner.Compression.bzip2
{
/// <summary>
/// Structure holding all the decompression-side stuff.

View File

@@ -1,6 +1,6 @@
using static BurnOutSharp.Compression.bzip2.Constants;
using static BinaryObjectScanner.Compression.bzip2.Constants;
namespace BurnOutSharp.Compression.bzip2
namespace BinaryObjectScanner.Compression.bzip2
{
/// <summary>
/// Structure holding all the compression-side stuff.

View File

@@ -1,6 +1,6 @@
using static BurnOutSharp.Compression.bzip2.Constants;
using static BinaryObjectScanner.Compression.bzip2.Constants;
namespace BurnOutSharp.Compression.bzip2
namespace BinaryObjectScanner.Compression.bzip2
{
/// <summary>
/// Huffman coding low-level stuff

View File

@@ -1,6 +1,6 @@
using static BurnOutSharp.Compression.bzip2.Constants;
using static BinaryObjectScanner.Compression.bzip2.Constants;
namespace BurnOutSharp.Compression.bzip2
namespace BinaryObjectScanner.Compression.bzip2
{
/// <summary>
/// Block sorting machinery

View File

@@ -1,4 +1,4 @@
namespace BurnOutSharp.Compression.bzip2
namespace BinaryObjectScanner.Compression.bzip2
{
/// <see href="https://github.com/ladislav-zezula/StormLib/blob/master/src/bzip2/bzlib.h"/>
public unsafe struct bz_stream

View File

@@ -1,8 +1,8 @@
using System.Runtime.InteropServices;
using static BurnOutSharp.Compression.bzip2.Constants;
using static BurnOutSharp.Compression.bzip2.Huffman;
using static BinaryObjectScanner.Compression.bzip2.Constants;
using static BinaryObjectScanner.Compression.bzip2.Huffman;
namespace BurnOutSharp.Compression.bzip2
namespace BinaryObjectScanner.Compression.bzip2
{
/// <see href="https://github.com/ladislav-zezula/StormLib/blob/master/src/bzip2/decompress.c"/>
internal static unsafe class decompress

View File

@@ -0,0 +1,51 @@
using System;
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// AACS media key block
/// </summary>
public class AACSMediaKeyBlock : IDetectable
{
/// <inheritdoc/>
public string Detect(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Detect(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Detect(Stream stream, string file, bool includeDebug)
{
// If the MKB file itself fails
try
{
// Create the wrapper
Wrappers.AACSMediaKeyBlock mkb = Wrappers.AACSMediaKeyBlock.Create(stream);
if (mkb == null)
return null;
// Derive the version, if possible
var typeAndVersion = mkb.Records.FirstOrDefault(r => r.RecordType == Models.AACS.RecordType.TypeAndVersion);
if (typeAndVersion == null)
return "AACS (Unknown Version)";
else
return $"AACS {(typeAndVersion as Models.AACS.TypeAndVersionRecord).VersionNumber}";
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
return null;
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// BD+ SVM
/// </summary>
public class BDPlusSVM : IDetectable
{
/// <inheritdoc/>
public string Detect(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Detect(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Detect(Stream stream, string file, bool includeDebug)
{
// If the BD+ file itself fails
try
{
// Create the wrapper
Wrappers.BDPlusSVM svm = Wrappers.BDPlusSVM.Create(stream);
if (svm == null)
return null;
// Format the date
string date = $"{svm.Year:0000}/{svm.Month:00}/{svm.Day:00}";
// Return the formatted value
return $"BD+ {date}";
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
return null;
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// BFPK custom archive format
/// </summary>
public class BFPK : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create the wrapper
Wrappers.BFPK bfpk = Wrappers.BFPK.Create(stream);
if (bfpk == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// Extract all files
bfpk.ExtractAll(tempPath);
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Half-Life Level
/// </summary>
public class BSP : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create the wrapper
Wrappers.BSP bsp = Wrappers.BSP.Create(stream);
if (bsp == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// Loop through and extract all files
bsp.ExtractAllLumps(tempPath);
bsp.ExtractAllTextures(tempPath);
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
using SharpCompress.Compressors;
using SharpCompress.Compressors.BZip2;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// bzip2 archive
/// </summary>
public class BZip2 : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
using (BZip2Stream bz2File = new BZip2Stream(stream, CompressionMode.Decompress, true))
{
string tempFile = Path.Combine(tempPath, Guid.NewGuid().ToString());
using (FileStream fs = File.OpenWrite(tempFile))
{
bz2File.CopyTo(fs);
}
}
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Title>BinaryObjectScanner.FileType</Title>
<AssemblyName>BinaryObjectScanner.FileType</AssemblyName>
<Authors>Matt Nadareski</Authors>
<Product>BurnOutSharp</Product>
<Copyright>Copyright (c)2022 Matt Nadareski</Copyright>
<RepositoryUrl>https://github.com/mnadareski/BurnOutSharp</RepositoryUrl>
<Version>2.8</Version>
<AssemblyVersion>2.8</AssemblyVersion>
<FileVersion>2.8</FileVersion>
<IncludeSource>true</IncludeSource>
<IncludeSymbols>true</IncludeSymbols>
</PropertyGroup>
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\BinaryObjectScanner.Compression\BinaryObjectScanner.Compression.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.GameEngine\BinaryObjectScanner.GameEngine.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Interfaces\BinaryObjectScanner.Interfaces.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Matching\BinaryObjectScanner.Matching.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Packer\BinaryObjectScanner.Packer.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Protection\BinaryObjectScanner.Protection.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Wrappers\BinaryObjectScanner.Wrappers.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="OpenMcdf" Version="2.2.1.12" />
<PackageReference Include="SharpCompress" Version="0.32.2" />
<PackageReference Include="UnshieldSharp" Version="1.6.9" />
</ItemGroup>
</Project>

View File

@@ -1,37 +1,34 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Text;
using BurnOutSharp.Interfaces;
using BinaryObjectScanner.Interfaces;
using OpenMcdf;
using static BurnOutSharp.Utilities.Dictionary;
namespace BurnOutSharp.FileType
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Compound File Binary
/// </summary>
public class CFB : IScannable
public class CFB : IExtractable
{
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
return Extract(fs, file, includeDebug);
}
}
// TODO: Add stream opening support
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
public string Extract(Stream stream, string file, bool includeDebug)
{
// If the MSI file itself fails
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
@@ -39,61 +36,51 @@ namespace BurnOutSharp.FileType
{
msi.RootStorage.VisitEntries((e) =>
{
if (!e.IsStream)
return;
var str = msi.RootStorage.GetStream(e.Name);
if (str == null)
return;
byte[] strData = str.GetData();
if (strData == null)
return;
string decoded = DecodeStreamName(e.Name).TrimEnd('\0');
byte[] nameBytes = Encoding.UTF8.GetBytes(e.Name);
// UTF-8 encoding of 0x4840.
if (nameBytes[0] == 0xe4 && nameBytes[1] == 0xa1 && nameBytes[2] == 0x80)
decoded = decoded.Substring(3);
foreach (char c in Path.GetInvalidFileNameChars())
try
{
decoded = decoded.Replace(c, '_');
if (!e.IsStream)
return;
var str = msi.RootStorage.GetStream(e.Name);
if (str == null)
return;
byte[] strData = str.GetData();
if (strData == null)
return;
string decoded = DecodeStreamName(e.Name).TrimEnd('\0');
byte[] nameBytes = Encoding.UTF8.GetBytes(e.Name);
// UTF-8 encoding of 0x4840.
if (nameBytes[0] == 0xe4 && nameBytes[1] == 0xa1 && nameBytes[2] == 0x80)
decoded = decoded.Substring(3);
foreach (char c in Path.GetInvalidFileNameChars())
{
decoded = decoded.Replace(c, '_');
}
string filename = Path.Combine(tempPath, decoded);
using (Stream fs = File.OpenWrite(filename))
{
fs.Write(strData, 0, strData.Length);
}
}
string filename = Path.Combine(tempPath, decoded);
using (Stream fs = File.OpenWrite(filename))
catch (Exception ex)
{
fs.Write(strData, 0, strData.Length);
if (includeDebug) Console.WriteLine(ex);
}
}, recursive: true);
}
// 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
StripFromKeys(protections, tempPath);
return protections;
return tempPath;
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
return null;
}
return null;
}
/// <remarks>Adapted from LibMSI</remarks>

View File

@@ -0,0 +1,437 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using BinaryObjectScanner.Interfaces;
using BinaryObjectScanner.Utilities;
using BinaryObjectScanner.Wrappers;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Executable or library
/// </summary>
/// <remarks>
/// Due to the complexity of executables, all extraction handling
/// another class that is used by the scanner
/// </remarks>
public class Executable : IDetectable
{
#region Properties
/// <summary>
/// Determines if game engines are counted as detected protections or not
/// </summary>
public bool IncludeGameEngines { get; set; }
/// <summary>
/// Determines if packers are counted as detected protections or not
/// </summary>
public bool IncludePackers { get; set; }
/// <summary>
/// Cache for all IContentCheck types
/// </summary>
public static IEnumerable<IContentCheck> ContentCheckClasses
{
get
{
if (contentCheckClasses == null)
contentCheckClasses = InitCheckClasses<IContentCheck>();
return contentCheckClasses;
}
}
/// <summary>
/// Cache for all ILinearExecutableCheck types
/// </summary>
public static IEnumerable<ILinearExecutableCheck> LinearExecutableCheckClasses
{
get
{
if (linearExecutableCheckClasses == null)
linearExecutableCheckClasses = InitCheckClasses<ILinearExecutableCheck>();
return linearExecutableCheckClasses;
}
}
/// <summary>
/// Cache for all IMSDOSExecutableCheck types
/// </summary>
public static IEnumerable<IMSDOSExecutableCheck> MSDOSExecutableCheckClasses
{
get
{
if (msdosExecutableCheckClasses == null)
msdosExecutableCheckClasses = InitCheckClasses<IMSDOSExecutableCheck>();
return msdosExecutableCheckClasses;
}
}
/// <summary>
/// Cache for all INewExecutableCheck types
/// </summary>
public static IEnumerable<INewExecutableCheck> NewExecutableCheckClasses
{
get
{
if (newExecutableCheckClasses == null)
newExecutableCheckClasses = InitCheckClasses<INewExecutableCheck>();
return newExecutableCheckClasses;
}
}
/// <summary>
/// Cache for all IPortableExecutableCheck types
/// </summary>
public static IEnumerable<IPortableExecutableCheck> PortableExecutableCheckClasses
{
get
{
if (portableExecutableCheckClasses == null)
portableExecutableCheckClasses = InitCheckClasses<IPortableExecutableCheck>();
return portableExecutableCheckClasses;
}
}
#endregion
#region Internal Instances
/// <summary>
/// Cache for all IContentCheck types
/// </summary>
private static IEnumerable<IContentCheck> contentCheckClasses;
/// <summary>
/// Cache for all ILinearExecutableCheck types
/// </summary>
private static IEnumerable<ILinearExecutableCheck> linearExecutableCheckClasses;
/// <summary>
/// Cache for all IMSDOSExecutableCheck types
/// </summary>
private static IEnumerable<IMSDOSExecutableCheck> msdosExecutableCheckClasses;
/// <summary>
/// Cache for all INewExecutableCheck types
/// </summary>
private static IEnumerable<INewExecutableCheck> newExecutableCheckClasses;
/// <summary>
/// Cache for all IPortableExecutableCheck types
/// </summary>
private static IEnumerable<IPortableExecutableCheck> portableExecutableCheckClasses;
#endregion
/// <inheritdoc/>
public string Detect(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Detect(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Detect(Stream stream, string file, bool includeDebug)
{
// Try to create a wrapper for the proper executable type
var wrapper = WrapperFactory.CreateExecutableWrapper(stream);
if (wrapper == null)
return null;
// Create the internal queue
var protections = new ConcurrentQueue<string>();
// Only use generic content checks if we're in debug mode
if (includeDebug)
{
var subProtections = RunContentChecks(file, stream, includeDebug);
if (subProtections != null)
protections.AddRange(subProtections.Values.ToArray());
}
if (wrapper is MSDOS mz)
{
var subProtections = RunMSDOSExecutableChecks(file, stream, mz, includeDebug);
if (subProtections != null)
protections.AddRange(subProtections.Values.ToArray());
}
else if (wrapper is LinearExecutable lex)
{
var subProtections = RunLinearExecutableChecks(file, stream, lex, includeDebug);
if (subProtections != null)
protections.AddRange(subProtections.Values.ToArray());
}
else if (wrapper is NewExecutable nex)
{
var subProtections = RunNewExecutableChecks(file, stream, nex, includeDebug);
if (subProtections != null)
protections.AddRange(subProtections.Values.ToArray());
}
else if (wrapper is PortableExecutable pex)
{
var subProtections = RunPortableExecutableChecks(file, stream, pex, includeDebug);
if (subProtections != null)
protections.AddRange(subProtections.Values.ToArray());
}
return string.Join(";", protections);
}
#region Check Runners
/// <summary>
/// Handle a single file based on all content check implementations
/// </summary>
/// <param name="file">Name of the source file of the stream, for tracking</param>
/// <param name="stream">Stream to scan the contents of</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
public ConcurrentDictionary<IContentCheck, string> RunContentChecks(string file, Stream stream, bool includeDebug)
{
// If we have an invalid file
if (string.IsNullOrWhiteSpace(file))
return null;
else if (!File.Exists(file))
return null;
// Read the file contents
byte[] fileContent = null;
try
{
using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
{
fileContent = br.ReadBytes((int)stream.Length);
if (fileContent == null)
return null;
}
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
// Create the output dictionary
var protections = new ConcurrentDictionary<IContentCheck, string>();
// Iterate through all checks
Parallel.ForEach(ContentCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
string protection = checkClass.CheckContents(file, fileContent, includeDebug);
if (string.IsNullOrWhiteSpace(protection))
return;
// If we are filtering on game engines
if (CheckIfGameEngine(checkClass) && !IncludeGameEngines)
return;
// If we are filtering on packers
if (CheckIfPacker(checkClass) && !IncludePackers)
return;
protections.TryAdd(checkClass, protection);
});
return protections;
}
/// <summary>
/// Handle a single file based on all linear executable check implementations
/// </summary>
/// <param name="file">Name of the source file of the executable, for tracking</param>
/// <param name="lex">Executable to scan</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
public ConcurrentDictionary<ILinearExecutableCheck, string> RunLinearExecutableChecks(string file, Stream stream, LinearExecutable lex, bool includeDebug)
{
// Create the output dictionary
var protections = new ConcurrentDictionary<ILinearExecutableCheck, string>();
// Iterate through all checks
Parallel.ForEach(LinearExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
string protection = checkClass.CheckLinearExecutable(file, lex, includeDebug);
if (string.IsNullOrWhiteSpace(protection))
return;
// If we are filtering on game engines
if (CheckIfGameEngine(checkClass) && !IncludeGameEngines)
return;
// If we are filtering on packers
if (CheckIfPacker(checkClass) && !IncludePackers)
return;
protections.TryAdd(checkClass, protection);
});
return protections;
}
/// <summary>
/// Handle a single file based on all MS-DOS executable check implementations
/// </summary>
/// <param name="file">Name of the source file of the executable, for tracking</param>
/// <param name="mz">Executable to scan</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
public ConcurrentDictionary<IMSDOSExecutableCheck, string> RunMSDOSExecutableChecks(string file, Stream stream, MSDOS mz, bool includeDebug)
{
// Create the output dictionary
var protections = new ConcurrentDictionary<IMSDOSExecutableCheck, string>();
// Iterate through all checks
Parallel.ForEach(MSDOSExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
string protection = checkClass.CheckMSDOSExecutable(file, mz, includeDebug);
if (string.IsNullOrWhiteSpace(protection))
return;
// If we are filtering on game engines
if (CheckIfGameEngine(checkClass) && !IncludeGameEngines)
return;
// If we are filtering on packers
if (CheckIfPacker(checkClass) && !IncludePackers)
return;
protections.TryAdd(checkClass, protection);
});
return protections;
}
/// <summary>
/// Handle a single file based on all new executable check implementations
/// </summary>
/// <param name="file">Name of the source file of the executable, for tracking</param>
/// <param name="nex">Executable to scan</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
public ConcurrentDictionary<INewExecutableCheck, string> RunNewExecutableChecks(string file, Stream stream, NewExecutable nex, bool includeDebug)
{
// Create the output dictionary
var protections = new ConcurrentDictionary<INewExecutableCheck, string>();
// Iterate through all checks
Parallel.ForEach(NewExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
string protection = checkClass.CheckNewExecutable(file, nex, includeDebug);
if (string.IsNullOrWhiteSpace(protection))
return;
// If we are filtering on game engines
if (CheckIfGameEngine(checkClass) && !IncludeGameEngines)
return;
// If we are filtering on packers
if (CheckIfPacker(checkClass) && !IncludePackers)
return;
protections.TryAdd(checkClass, protection);
});
return protections;
}
/// <summary>
/// Handle a single file based on all portable executable check implementations
/// </summary>
/// <param name="file">Name of the source file of the executable, for tracking</param>
/// <param name="pex">Executable to scan</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
public ConcurrentDictionary<IPortableExecutableCheck, string> RunPortableExecutableChecks(string file, Stream stream, PortableExecutable pex, bool includeDebug)
{
// Create the output dictionary
var protections = new ConcurrentDictionary<IPortableExecutableCheck, string>();
// Iterate through all checks
Parallel.ForEach(PortableExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
string protection = checkClass.CheckPortableExecutable(file, pex, includeDebug);
if (string.IsNullOrWhiteSpace(protection))
return;
// If we are filtering on game engines
if (CheckIfGameEngine(checkClass) && !IncludeGameEngines)
return;
// If we are filtering on packers
if (CheckIfPacker(checkClass) && !IncludePackers)
return;
protections.TryAdd(checkClass, protection);
});
return protections;
}
#endregion
#region Initializers
/// <summary>
/// Initialize all implementations of a type
/// </summary>
private static IEnumerable<T> InitCheckClasses<T>()
=> InitCheckClasses<T>(typeof(GameEngine._DUMMY).Assembly)
.Concat(InitCheckClasses<T>(typeof(Packer._DUMMY).Assembly))
.Concat(InitCheckClasses<T>(typeof(Protection._DUMMY).Assembly));
/// <summary>
/// Initialize all implementations of a type
/// </summary>
private static IEnumerable<T> InitCheckClasses<T>(Assembly assembly)
{
return assembly.GetTypes()
.Where(t => t.IsClass && t.GetInterface(typeof(T).Name) != null)
.Select(t => (T)Activator.CreateInstance(t));
}
#endregion
#region Helpers
/// <summary>
/// Check to see if an implementation is a game engine using reflection
/// </summary>
/// <param name="impl">Implementation that was last used to check</param>
private static bool CheckIfGameEngine(object impl)
{
return impl.GetType().Namespace.ToLowerInvariant().Contains("gameengine");
}
/// <summary>
/// Check to see if an implementation is a packer using reflection
/// </summary>
/// <param name="impl">Implementation that was last used to check</param>
private static bool CheckIfPacker(object impl)
{
return impl.GetType().Namespace.ToLowerInvariant().Contains("packer");
}
#endregion
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Half-Life Game Cache File
/// </summary>
public class GCF : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create the wrapper
Wrappers.GCF gcf = Wrappers.GCF.Create(stream);
if (gcf == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// Loop through and extract all files
gcf.ExtractAll(tempPath);
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -1,36 +1,34 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using BurnOutSharp.Interfaces;
using BinaryObjectScanner.Interfaces;
using SharpCompress.Archives;
using SharpCompress.Archives.GZip;
using static BurnOutSharp.Utilities.Dictionary;
namespace BurnOutSharp.FileType
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// gzip archive
/// </summary>
public class GZIP : IScannable
public class GZIP : IExtractable
{
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
public string Extract(Stream stream, string file, bool includeDebug)
{
// If the gzip file itself fails
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
@@ -38,7 +36,6 @@ namespace BurnOutSharp.FileType
{
foreach (var entry in zipFile.Entries)
{
// If an individual entry fails
try
{
// If we have a directory, skip it
@@ -50,35 +47,18 @@ namespace BurnOutSharp.FileType
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
}
}
}
// 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
StripFromKeys(protections, tempPath);
return protections;
return tempPath;
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
return null;
}
return null;
}
}
}

View File

@@ -1,45 +1,40 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using BurnOutSharp.Interfaces;
using BinaryObjectScanner.Interfaces;
using UnshieldSharp.Archive;
using static BurnOutSharp.Utilities.Dictionary;
namespace BurnOutSharp.FileType
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// InstallShield archive v3
/// </summary>
public class InstallShieldArchiveV3 : IScannable
public class InstallShieldArchiveV3 : IExtractable
{
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
return Extract(fs, file, includeDebug);
}
}
// TODO: Add stream opening support
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
public string Extract(Stream stream, string file, bool includeDebug)
{
// If the archive itself fails
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
UnshieldSharp.Archive.InstallShieldArchiveV3 archive = new UnshieldSharp.Archive.InstallShieldArchiveV3(file);
foreach (CompressedFile cfile in archive.Files.Select(kvp => kvp.Value))
{
// If an individual entry fails
try
{
string tempFile = Path.Combine(tempPath, cfile.FullPath);
@@ -57,34 +52,17 @@ namespace BurnOutSharp.FileType
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
}
}
// 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
StripFromKeys(protections, tempPath);
return protections;
return tempPath;
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
return null;
}
return null;
}
}
}

View File

@@ -0,0 +1,87 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using BinaryObjectScanner.Interfaces;
using UnshieldSharp.Cabinet;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// InstallShield cabinet file
/// </summary>
public class InstallShieldCAB : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
// Get the name of the first cabinet file or header
string directory = Path.GetDirectoryName(file);
string noExtension = Path.GetFileNameWithoutExtension(file);
string filenamePattern = Path.Combine(directory, noExtension);
filenamePattern = new Regex(@"\d+$").Replace(filenamePattern, string.Empty);
bool cabinetHeaderExists = File.Exists(Path.Combine(directory, filenamePattern + "1.hdr"));
bool shouldScanCabinet = cabinetHeaderExists
? file.Equals(Path.Combine(directory, filenamePattern + "1.hdr"), StringComparison.OrdinalIgnoreCase)
: file.Equals(Path.Combine(directory, filenamePattern + "1.cab"), StringComparison.OrdinalIgnoreCase);
// If we have anything but the first file
if (!shouldScanCabinet)
return null;
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
InstallShieldCabinet cabfile = InstallShieldCabinet.Open(file);
for (int i = 0; i < cabfile.FileCount; i++)
{
try
{
// Check if the file is valid first
if (!cabfile.FileIsValid(i))
continue;
string tempFile;
try
{
string filename = cabfile.FileName(i);
tempFile = Path.Combine(tempPath, filename);
}
catch
{
tempFile = Path.Combine(tempPath, $"BAD_FILENAME{i}");
}
cabfile.FileSave(i, tempFile);
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
}
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
using BinaryObjectScanner.Matching;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Link Data Security encrypted file
/// </summary>
public class LDSCRYPT : IDetectable
{
/// <inheritdoc/>
public string Detect(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Detect(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Detect(Stream stream, string file, bool includeDebug)
{
try
{
byte[] magic = new byte[16];
stream.Read(magic, 0, 16);
if (magic.StartsWith(new byte?[] { 0x4C, 0x44, 0x53, 0x43, 0x52, 0x59, 0x50, 0x54 }))
return "Link Data Security encrypted file";
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
return null;
}
}
}

View File

@@ -1,42 +1,40 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using BurnOutSharp.Interfaces;
using BinaryObjectScanner.Interfaces;
#if NET48
using StormLibSharp;
#endif
using static BurnOutSharp.Utilities.Dictionary;
namespace BurnOutSharp.FileType
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// MoPaQ game data archive
/// </summary>
public class MPQ : IScannable
public class MPQ : IExtractable
{
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
return Extract(fs, file, includeDebug);
}
}
// TODO: Add stream opening support
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
public string Extract(Stream stream, string file, bool includeDebug)
{
#if NET6_0_OR_GREATER
// Not supported for .NET 6.0 due to Windows DLL requirements
return null;
#else
// If the MPQ file itself fails
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
@@ -45,7 +43,7 @@ namespace BurnOutSharp.FileType
// Try to open the listfile
string listfile = null;
MpqFileStream listStream = mpqArchive.OpenFile("(listfile)");
// If we can't read the listfile, we just return
if (!listStream.CanRead)
return null;
@@ -62,7 +60,6 @@ namespace BurnOutSharp.FileType
// Loop over each entry
foreach (string sub in listfileLines)
{
// If an individual entry fails
try
{
string tempFile = Path.Combine(tempPath, sub);
@@ -71,35 +68,18 @@ namespace BurnOutSharp.FileType
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
}
}
}
// 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
StripFromKeys(protections, tempPath);
return protections;
return tempPath;
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
return null;
}
return null;
#endif
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
using BinaryObjectScanner.Wrappers;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Microsoft cabinet file
/// </summary>
/// <remarks>Specification available at <see href="http://download.microsoft.com/download/5/0/1/501ED102-E53F-4CE0-AA6B-B0F93629DDC6/Exchange/%5BMS-CAB%5D.pdf"/></remarks>
/// <see href="https://github.com/wine-mirror/wine/tree/master/dlls/cabinet"/>
public class MicrosoftCAB : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// TODO: Fix/re-enable/do ANYTHING to get this working again
return null;
// Open the cab file
var cabFile = MicrosoftCabinet.Create(stream);
if (cabFile == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// If entry extraction fails
bool success = cabFile.ExtractAll(tempPath);
if (!success)
return null;
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -1,36 +1,34 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using BurnOutSharp.Compression;
using BurnOutSharp.Interfaces;
using static BurnOutSharp.Utilities.Dictionary;
using BinaryObjectScanner.Compression;
using BinaryObjectScanner.Interfaces;
namespace BurnOutSharp.FileType
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Microsoft LZ-compressed Files (LZ32)
/// </summary>
/// <remarks>This is treated like an archive type due to the packing style</remarks>
public class MicrosoftLZ : IScannable
public class MicrosoftLZ : IExtractable
{
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
public string Extract(Stream stream, string file, bool includeDebug)
{
// If the LZ file itself fails
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
@@ -56,30 +54,13 @@ namespace BurnOutSharp.FileType
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
StripFromKeys(protections, tempPath);
return protections;
return tempPath;
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
return null;
}
return null;
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Half-Life Package File
/// </summary>
public class PAK : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create the wrapper
Wrappers.PAK pak = Wrappers.PAK.Create(stream);
if (pak == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// Loop through and extract all files
pak.ExtractAll(tempPath);
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// NovaLogic Game Archive Format
/// </summary>
public class PFF : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create the wrapper
Wrappers.PFF pff = Wrappers.PFF.Create(stream);
if (pff == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// Extract all files
pff.ExtractAll(tempPath);
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex.Message);
return null;
}
}
}
}

View File

@@ -1,36 +1,34 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using BurnOutSharp.Interfaces;
using BinaryObjectScanner.Interfaces;
using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
using static BurnOutSharp.Utilities.Dictionary;
namespace BurnOutSharp.FileType
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// PKWARE ZIP archive and derivatives
/// </summary>
public class PKZIP : IScannable
public class PKZIP : IExtractable
{
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
public string Extract(Stream stream, string file, bool includeDebug)
{
// If the zip file itself fails
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
@@ -38,7 +36,6 @@ namespace BurnOutSharp.FileType
{
foreach (var entry in zipFile.Entries)
{
// If an individual entry fails
try
{
// If we have a directory, skip it
@@ -51,35 +48,18 @@ namespace BurnOutSharp.FileType
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
}
}
}
// 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
StripFromKeys(protections, tempPath);
return protections;
return tempPath;
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
return null;
}
return null;
}
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
using BinaryObjectScanner.Matching;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// PlayJ audio file
/// </summary>
public class PLJ : IDetectable
{
/// <inheritdoc/>
public string Detect(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Detect(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Detect(Stream stream, string file, bool includeDebug)
{
try
{
byte[] magic = new byte[16];
stream.Read(magic, 0, 16);
if (magic.StartsWith(new byte?[] { 0xFF, 0x9D, 0x53, 0x4B }))
return "PlayJ Audio File";
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
return null;
}
}
}

View File

@@ -1,36 +1,34 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using BurnOutSharp.Interfaces;
using BinaryObjectScanner.Interfaces;
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
using static BurnOutSharp.Utilities.Dictionary;
namespace BurnOutSharp.FileType
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// RAR archive
/// </summary>
public class RAR : IScannable
public class RAR : IExtractable
{
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
public string Extract(Stream stream, string file, bool includeDebug)
{
// If the rar file itself fails
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
@@ -38,7 +36,6 @@ namespace BurnOutSharp.FileType
{
foreach (var entry in rarFile.Entries)
{
// If an individual entry fails
try
{
// If we have a directory, skip it
@@ -50,35 +47,18 @@ namespace BurnOutSharp.FileType
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
}
}
}
// 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
StripFromKeys(protections, tempPath);
return protections;
return tempPath;
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
return null;
}
return null;
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
using BinaryObjectScanner.Matching;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// StarForce Filesystem file
/// </summary>
/// <see href="https://forum.xentax.com/viewtopic.php?f=21&t=2084"/>
public class SFFS : IExtractable, IDetectable
{
/// <inheritdoc/>
public string Detect(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Detect(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Detect(Stream stream, string file, bool includeDebug)
{
try
{
byte[] magic = new byte[16];
stream.Read(magic, 0, 16);
if (magic.StartsWith(new byte?[] { 0x53, 0x46, 0x46, 0x53 }))
return "StarForce Filesystem Container";
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
return null;
}
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
return null;
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// SGA game archive
/// </summary>
public class SGA : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create the wrapper
Wrappers.SGA sga = Wrappers.SGA.Create(stream);
if (sga == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// Loop through and extract all files
sga.ExtractAll(tempPath);
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -1,36 +1,34 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using BurnOutSharp.Interfaces;
using BinaryObjectScanner.Interfaces;
using SharpCompress.Archives;
using SharpCompress.Archives.SevenZip;
using static BurnOutSharp.Utilities.Dictionary;
namespace BurnOutSharp.FileType
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// 7-zip archive
/// </summary>
public class SevenZip : IScannable
public class SevenZip : IExtractable
{
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
public string Extract(Stream stream, string file, bool includeDebug)
{
// If the 7-zip file itself fails
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
@@ -38,7 +36,6 @@ namespace BurnOutSharp.FileType
{
foreach (var entry in sevenZipFile.Entries)
{
// If an individual entry fails
try
{
// If we have a directory, skip it
@@ -50,35 +47,18 @@ namespace BurnOutSharp.FileType
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
}
}
// 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
StripFromKeys(protections, tempPath);
return protections;
}
return tempPath;
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
return null;
}
return null;
}
}
}

View File

@@ -1,36 +1,34 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using BurnOutSharp.Interfaces;
using BinaryObjectScanner.Interfaces;
using SharpCompress.Archives;
using SharpCompress.Archives.Tar;
using static BurnOutSharp.Utilities.Dictionary;
namespace BurnOutSharp.FileType
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Tape archive
/// </summary>
public class TapeArchive : IScannable
public class TapeArchive : IExtractable
{
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
public string Extract(Stream stream, string file, bool includeDebug)
{
// If the tar file itself fails
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
@@ -38,7 +36,6 @@ namespace BurnOutSharp.FileType
{
foreach (var entry in tarFile.Entries)
{
// If an individual entry fails
try
{
// If we have a directory, skip it
@@ -50,35 +47,18 @@ namespace BurnOutSharp.FileType
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
}
}
}
// 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
StripFromKeys(protections, tempPath);
return protections;
return tempPath;
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
return null;
}
return null;
}
}
}

View File

@@ -1,34 +1,33 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Interfaces;
using static BurnOutSharp.Utilities.Dictionary;
using BinaryObjectScanner.Interfaces;
namespace BurnOutSharp.FileType
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Various generic textfile formats
/// </summary>
public class Textfile : IScannable
public class Textfile : IDetectable
{
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
public string Detect(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Scan(scanner, fs, file);
return Detect(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
public string Detect(Stream stream, string file, bool includeDebug)
{
// Files can be protected in multiple ways
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
var protections = new List<string>();
try
{
@@ -42,60 +41,60 @@ namespace BurnOutSharp.FileType
// AegiSoft License Manager
// Found in "setup.ins" (Redump entry 73521/IA item "Nova_HoyleCasino99USA").
if (fileContent.Contains("Failed to load the AegiSoft License Manager install program."))
AppendToDictionary(protections, file, "AegiSoft License Manager");
protections.Add("AegiSoft License Manager");
// CD-Key
if (fileContent.Contains("a valid serial number is required"))
AppendToDictionary(protections, file, "CD-Key / Serial");
protections.Add("CD-Key / Serial");
else if (fileContent.Contains("serial number is located"))
AppendToDictionary(protections, file, "CD-Key / Serial");
protections.Add("CD-Key / Serial");
// Found in "Setup.Ins" ("Word Point 2002" in IA item "advantage-language-french-beginner-langmaster-2005").
else if (fileContent.Contains("Please enter a valid registration number"))
AppendToDictionary(protections, file, "CD-Key / Serial");
protections.Add("CD-Key / Serial");
// Freelock
// Found in "FILE_ID.DIZ" distributed with Freelock.
if (fileContent.Contains("FREELOCK 1.0"))
AppendToDictionary(protections, file, "Freelock 1.0");
protections.Add("Freelock 1.0");
else if (fileContent.Contains("FREELOCK 1.2"))
AppendToDictionary(protections, file, "Freelock 1.2");
protections.Add("Freelock 1.2");
else if (fileContent.Contains("FREELOCK 1.2a"))
AppendToDictionary(protections, file, "Freelock 1.2a");
protections.Add("Freelock 1.2a");
else if (fileContent.Contains("FREELOCK 1.3"))
AppendToDictionary(protections, file, "Freelock 1.3");
protections.Add("Freelock 1.3");
else if (fileContent.Contains("FREELOCK"))
AppendToDictionary(protections, file, "Freelock");
protections.Add("Freelock");
// MediaCloQ
if (fileContent.Contains("SunnComm MediaCloQ"))
AppendToDictionary(protections, file, "MediaCloQ");
protections.Add("MediaCloQ");
else if (fileContent.Contains("http://download.mediacloq.com/"))
AppendToDictionary(protections, file, "MediaCloQ");
protections.Add("MediaCloQ");
else if (fileContent.Contains("http://www.sunncomm.com/mediacloq/"))
AppendToDictionary(protections, file, "MediaCloQ");
protections.Add("MediaCloQ");
// MediaMax
if (fileContent.Contains("MediaMax technology"))
AppendToDictionary(protections, file, "MediaMax CD-3");
protections.Add("MediaMax CD-3");
else if (fileContent.Contains("exclusive Cd3 technology"))
AppendToDictionary(protections, file, "MediaMax CD-3");
protections.Add("MediaMax CD-3");
else if (fileContent.Contains("<PROTECTION-VENDOR>MediaMAX</PROTECTION-VENDOR>"))
AppendToDictionary(protections, file, "MediaMax CD-3");
protections.Add("MediaMax CD-3");
else if (fileContent.Contains("MediaMax(tm)"))
AppendToDictionary(protections, file, "MediaMax CD-3");
protections.Add("MediaMax CD-3");
// phenoProtect
if (fileContent.Contains("phenoProtect"))
AppendToDictionary(protections, file, "phenoProtect");
protections.Add("phenoProtect");
// Rainbow Sentinel
// Found in "SENTW95.HLP" and "SENTINEL.HLP" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]".
if (fileContent.Contains("Rainbow Sentinel Driver Help"))
AppendToDictionary(protections, file, "Rainbow Sentinel");
protections.Add("Rainbow Sentinel");
// Found in "OEMSETUP.INF" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]".
if (fileContent.Contains("Sentinel Driver Disk"))
AppendToDictionary(protections, file, "Rainbow Sentinel");
protections.Add("Rainbow Sentinel");
// The full line from a sample is as follows:
//
@@ -105,22 +104,22 @@ namespace BurnOutSharp.FileType
// SecuROM
if (fileContent.Contains("SecuROM protected application"))
AppendToDictionary(protections, file, "SecuROM");
protections.Add("SecuROM");
// Steam
if (fileContent.Contains("All use of the Program is governed by the terms of the Steam Agreement as described below."))
AppendToDictionary(protections, file, "Steam");
protections.Add("Steam");
// XCP
if (fileContent.Contains("http://cp.sonybmg.com/xcp/"))
AppendToDictionary(protections, file, "XCP");
protections.Add("XCP");
}
catch (Exception ex)
{
if (scanner.IncludeDebug) Console.WriteLine(ex);
if (includeDebug) Console.WriteLine(ex);
}
return protections;
return string.Join(";", protections);
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Half-Life 2 Level
/// </summary>
public class VBSP : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create the wrapper
Wrappers.VBSP vbsp = Wrappers.VBSP.Create(stream);
if (vbsp == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// Loop through and extract all files
vbsp.ExtractAllLumps(tempPath);
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex.ToString());
return null;
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Valve Package File
/// </summary>
public class VPK : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create the wrapper
Wrappers.VPK vpk = Wrappers.VPK.Create(stream);
if (vpk == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// Loop through and extract all files
vpk.ExtractAll(tempPath);
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Half-Life Texture Package File
/// </summary>
public class WAD : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create the wrapper
Wrappers.WAD wad = Wrappers.WAD.Create(stream);
if (wad == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// Loop through and extract all files
wad.ExtractAllLumps(tempPath);
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
using SharpCompress.Compressors.Xz;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// xz archive
/// </summary>
public class XZ : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
using (XZStream xzFile = new XZStream(stream))
{
string tempFile = Path.Combine(tempPath, Guid.NewGuid().ToString());
using (FileStream fs = File.OpenWrite(tempFile))
{
xzFile.CopyTo(fs);
}
}
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// XBox Package File
/// </summary>
public class XZP : IExtractable
{
/// <inheritdoc/>
public string Extract(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string Extract(Stream stream, string file, bool includeDebug)
{
try
{
// Create the wrapper
Wrappers.XZP xzp = Wrappers.XZP.Create(stream);
if (xzp == null)
return null;
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
// Loop through and extract all files
xzp.ExtractAll(tempPath);
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
}
}
}

View File

@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Title>BinaryObjectScanner.GameEngine</Title>
<AssemblyName>BinaryObjectScanner.GameEngine</AssemblyName>
<Authors>Matt Nadareski</Authors>
<Product>BurnOutSharp</Product>
<Copyright>Copyright (c)2022 Matt Nadareski</Copyright>
<RepositoryUrl>https://github.com/mnadareski/BurnOutSharp</RepositoryUrl>
<Version>2.8</Version>
<AssemblyVersion>2.8</AssemblyVersion>
<FileVersion>2.8</FileVersion>
<IncludeSource>true</IncludeSource>
<IncludeSymbols>true</IncludeSymbols>
</PropertyGroup>
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\BinaryObjectScanner.Interfaces\BinaryObjectScanner.Interfaces.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Matching\BinaryObjectScanner.Matching.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Wrappers\BinaryObjectScanner.Wrappers.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,40 @@
using BinaryObjectScanner.Interfaces;
using BinaryObjectScanner.Wrappers;
namespace BinaryObjectScanner.GameEngine
{
/// <summary>
/// RenderWare (https://web.archive.org/web/20070214132346/http://www.renderware.com/) is an API and graphics engine created by Criterion in 1993.
/// It appears that version 4.X was exclusively used by EA internally, with version 3.X being the final public version (https://sigmaco.org/3782-renderware/).
/// It was available to use on many different platforms, with it being particularly useful for the PS2 (https://en.wikipedia.org/wiki/RenderWare).
///
/// Additional resources and documentation:
/// RenderWare interview: https://web.archive.org/web/20031208124348/http://www.homelanfed.com/index.php?id=9856
/// RenderWare V2.1 API reference: http://www.tnlc.com/rw/api/rwdoc.htm
/// RenderWare 2 official docs: https://github.com/electronicarts/RenderWare3Docs
/// RenderWare 3.7 SDK: https://github.com/sigmaco/rwsdk-v37-pc
/// Wikipedia list of RenderWare games: https://en.wikipedia.org/wiki/Category:RenderWare_games
/// </summary>
public class RenderWare : IPortableExecutableCheck
{
/// <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;
// Found in Redump entries 20138, 55823, and 102493.
bool rwcsegSection = pex.ContainsSection("_rwcseg", exact: true);
// Found in Redump entry 20138.
bool rwdsegSection = pex.ContainsSection("_rwdseg", exact: true);
// TODO: Check if this indicates a specific version, or if these sections are present in multiple.
if (rwcsegSection || rwdsegSection)
return "RenderWare";
return null;
}
}
}

View File

@@ -0,0 +1,7 @@
namespace BinaryObjectScanner.GameEngine
{
/// <summary>
/// This class exists for reflection purposes and should not be used
/// </summary>
public sealed class _DUMMY { }
}

View File

@@ -1,17 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;net6.0</TargetFrameworks>
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Title>BurnOutSharp.Builders</Title>
<AssemblyName>BurnOutSharp.Builders</AssemblyName>
<Title>BinaryObjectScanner.Interfaces</Title>
<AssemblyName>BinaryObjectScanner.Interfaces</AssemblyName>
<Authors>Matt Nadareski</Authors>
<Product>BurnOutSharp</Product>
<Copyright>Copyright (c)2022 Matt Nadareski</Copyright>
<RepositoryUrl>https://github.com/mnadareski/BurnOutSharp</RepositoryUrl>
<Version>2.7</Version>
<AssemblyVersion>2.7</AssemblyVersion>
<FileVersion>2.7</FileVersion>
<Version>2.8</Version>
<AssemblyVersion>2.8</AssemblyVersion>
<FileVersion>2.8</FileVersion>
<IncludeSource>true</IncludeSource>
<IncludeSymbols>true</IncludeSymbols>
</PropertyGroup>
@@ -21,8 +21,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\BurnOutSharp.Models\BurnOutSharp.Models.csproj" />
<ProjectReference Include="..\BurnOutSharp.Utilities\BurnOutSharp.Utilities.csproj" />
<ProjectReference Include="..\BinaryObjectScanner.Wrappers\BinaryObjectScanner.Wrappers.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,4 +1,4 @@
namespace BurnOutSharp.Interfaces
namespace BinaryObjectScanner.Interfaces
{
/// <summary>
/// Check a generic file for protection

View File

@@ -0,0 +1,28 @@
using System.IO;
namespace BinaryObjectScanner.Interfaces
{
/// <summary>
/// Mark a file type as being able to be detected
/// </summary>
public interface IDetectable
{
/// <summary>
/// Check if a file is detected as this file type
/// </summary>
/// <param name="file">Path to the input file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Detected file or protection type, null on error</returns>
/// <remarks>Ideally, this should just point to the other detect implementation.</remarks>
string Detect(string file, bool includeDebug);
/// <summary>
/// Check if a stream is detected as this file type
/// </summary>
/// <param name="stream">Stream representing the input file</param>
/// <param name="file">Path to the input file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Detected file or protection type, null on error</returns>
string Detect(Stream stream, string file, bool includeDebug);
}
}

View File

@@ -0,0 +1,30 @@
using System.IO;
namespace BinaryObjectScanner.Interfaces
{
/// <summary>
/// Mark a file type as being able to be extracted
/// </summary>
/// TODO: Change to have output directory passed in
/// TODO: Change to return a bool
public interface IExtractable
{
/// <summary>
/// Extract a file to a temporary path, if possible
/// </summary>
/// <param name="file">Path to the input file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Path to extracted files, null on error</returns>
/// <remarks>Ideally, this should just point to the other extract implementation.</remarks>
string Extract(string file, bool includeDebug);
/// <summary>
/// Extract a stream to a temporary path, if possible
/// </summary>
/// <param name="stream">Stream representing the input file</param>
/// <param name="file">Path to the input file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Path to extracted files, null on error</returns>
string Extract(Stream stream, string file, bool includeDebug);
}
}

Some files were not shown because too many files have changed in this diff Show More