mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-02-06 05:35:20 +00:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb03470625 | ||
|
|
b1aa2fc73a | ||
|
|
cd21c76c97 | ||
|
|
9e205ddf2a | ||
|
|
07a183955b | ||
|
|
b49c6e96fd | ||
|
|
148cfed141 | ||
|
|
cebbe6a1e8 | ||
|
|
558e23a9cd | ||
|
|
d7c37f6e0a | ||
|
|
c05090db8c | ||
|
|
fa19304a6d | ||
|
|
ec4962a3c9 | ||
|
|
7122aa44a1 | ||
|
|
cf62be365c | ||
|
|
9cc2f99334 | ||
|
|
d9d9f23af9 | ||
|
|
c29354f054 | ||
|
|
7738630952 | ||
|
|
c945ca4fe3 | ||
|
|
6acf5ccc09 | ||
|
|
a5f9006ef1 | ||
|
|
ae7111e201 | ||
|
|
5a94cd3b66 | ||
|
|
3de58ff05e | ||
|
|
6e409988a5 | ||
|
|
864fa8d3f8 | ||
|
|
622f36b056 | ||
|
|
efe144313b | ||
|
|
1e3aac6748 | ||
|
|
984ad1f642 | ||
|
|
b379e1781b | ||
|
|
e244d6939c |
2
.github/workflows/build_nupkg.yml
vendored
2
.github/workflows/build_nupkg.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
10
.github/workflows/build_programs.yml
vendored
10
.github/workflows/build_programs.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
matrix:
|
||||
project: [ExtractionTool, ProtectionScan]
|
||||
runtime: [win-x86, win-x64, win-arm64, linux-x64, linux-arm64, osx-x64]
|
||||
framework: [net8.0] #[net20, net35, net40, net452, net472, net48, netcoreapp3.1, net5.0, net6.0, net7.0, net8.0]
|
||||
framework: [net9.0] #[net20, net35, net40, net452, net472, net48, netcoreapp3.1, net5.0, net6.0, net7.0, net8.0, net9.0]
|
||||
conf: [Debug] #[Release, Debug]
|
||||
|
||||
steps:
|
||||
@@ -23,16 +23,18 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Build
|
||||
run: dotnet publish ${{ matrix.project }}/${{ matrix.project }}.csproj -f ${{ matrix.framework }} -r ${{ matrix.runtime }} -c ${{ matrix.conf == 'Release' && 'Release -p:DebugType=None -p:DebugSymbols=false' || 'Debug'}} --self-contained true --version-suffix ${{ github.sha }} ${{ (startsWith(matrix.framework, 'net5') || startsWith(matrix.framework, 'net6') || startsWith(matrix.framework, 'net7') || startsWith(matrix.framework, 'net8')) && '-p:PublishSingleFile=true' || ''}}
|
||||
run: dotnet publish ${{ matrix.project }}/${{ matrix.project }}.csproj -f ${{ matrix.framework }} -r ${{ matrix.runtime }} -c ${{ matrix.conf == 'Release' && 'Release -p:DebugType=None -p:DebugSymbols=false' || 'Debug'}} --self-contained true --version-suffix ${{ github.sha }} ${{ (startsWith(matrix.framework, 'net5') || startsWith(matrix.framework, 'net6') || startsWith(matrix.framework, 'net7') || startsWith(matrix.framework, 'net8') || startsWith(matrix.framework, 'net9')) && '-p:PublishSingleFile=true' || ''}}
|
||||
|
||||
- name: Archive build
|
||||
run: zip -r ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_${{ matrix.conf }}.zip ${{ matrix.project }}/bin/${{ matrix.conf }}/${{ matrix.framework }}/${{ matrix.runtime }}/publish/
|
||||
run: |
|
||||
cd ${{ matrix.project }}/bin/Debug/${{ matrix.framework }}/${{ matrix.runtime }}/publish/
|
||||
zip -r ${{ github.workspace }}/${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_${{ matrix.conf }}.zip ./
|
||||
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
2
.github/workflows/check_pr.yml
vendored
2
.github/workflows/check_pr.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Build
|
||||
run: dotnet build
|
||||
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
@@ -10,7 +10,7 @@
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/ProtectionScan/bin/Debug/net8.0/ProtectionScan.dll",
|
||||
"program": "${workspaceFolder}/ProtectionScan/bin/Debug/net9.0/ProtectionScan.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/ProtectionScan",
|
||||
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||
@@ -23,7 +23,7 @@
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/ExtractionTool/bin/Debug/net8.0/ExtractionTool.dll",
|
||||
"program": "${workspaceFolder}/ExtractionTool/bin/Debug/net9.0/ExtractionTool.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/ExtractionTool",
|
||||
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||
|
||||
@@ -1,103 +1,97 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Assembly Properties -->
|
||||
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>3.1.16</Version>
|
||||
<!-- Mostly added due to external libraries -->
|
||||
<WarningsNotAsErrors>CS0162;CS0612;CS8600;CS8601;CS8602;CS8603;CS8604;CS8605;CS8618;CS8625;CS8634;CS8765;IL3000;NU5100</WarningsNotAsErrors>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Description>Protection scanning library</Description>
|
||||
<Copyright>Copyright (c)2018-2024 Matt Nadareski</Copyright>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/SabreTools/BinaryObjectScanner</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>protection copy-protection scanning packer</PackageTags>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<!-- Assembly Properties -->
|
||||
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<NoWarn>CS0162;CS0612</NoWarn>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>3.2.3</Version>
|
||||
<!-- Mostly added due to external libraries -->
|
||||
<WarningsNotAsErrors>CS8600;CS8601;CS8602;CS8603;CS8604;CS8605;CS8618;CS8625;CS8634;CS8765;IL3000;NU5100</WarningsNotAsErrors>
|
||||
|
||||
<!-- Set a build flag for Windows specifically -->
|
||||
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x86'">
|
||||
<DefineConstants>$(DefineConstants);WIN</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Description>Protection scanning library</Description>
|
||||
<Copyright>Copyright (c)2018-2024 Matt Nadareski</Copyright>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/SabreTools/BinaryObjectScanner</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>protection copy-protection scanning packer</PackageTags>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Exclude certain parts of external modules for by default -->
|
||||
<PropertyGroup>
|
||||
<DefaultItemExcludes>
|
||||
$(DefaultItemExcludes);
|
||||
**\AssemblyInfo.cs;
|
||||
_EXTERNAL\LessIO\src\LessIO.Tests\**;
|
||||
_EXTERNAL\libmspack4n\lib\**;
|
||||
_EXTERNAL\libmspack4n\libmspack4ntest\**;
|
||||
_EXTERNAL\stormlibsharp\lib\**;
|
||||
_EXTERNAL\stormlibsharp\src\TestConsole\**
|
||||
</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
<!-- Set a build flag for Windows specifically -->
|
||||
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x86'">
|
||||
<DefineConstants>$(DefineConstants);WIN</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Exclude all StormLibSharp for .NET Framework 4.0 -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net40`))">
|
||||
<DefaultItemExcludes>
|
||||
$(DefaultItemExcludes);
|
||||
_EXTERNAL\stormlibsharp\src\**
|
||||
</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
<!-- Exclude certain parts of external modules for by default -->
|
||||
<PropertyGroup>
|
||||
<DefaultItemExcludes>
|
||||
$(DefaultItemExcludes);
|
||||
**\AssemblyInfo.cs;
|
||||
_EXTERNAL\LessIO\src\LessIO.Tests\**;
|
||||
_EXTERNAL\libmspack4n\lib\**;
|
||||
_EXTERNAL\libmspack4n\libmspack4ntest\**;
|
||||
_EXTERNAL\stormlibsharp\lib\**;
|
||||
_EXTERNAL\stormlibsharp\src\TestConsole\**
|
||||
</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Exclude all external modules for .NET Framework 2.0, .NET Framework 3.5, or non-Windows builds -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR !$(RuntimeIdentifier.StartsWith(`win-x86`))">
|
||||
<DefaultItemExcludes>
|
||||
$(DefaultItemExcludes);
|
||||
_EXTERNAL\**
|
||||
</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
<!-- Exclude all external modules for .NET Framework 2.0, .NET Framework 3.5, or non-Windows
|
||||
builds -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR !$(RuntimeIdentifier.StartsWith(`win-x86`))">
|
||||
<DefaultItemExcludes>
|
||||
$(DefaultItemExcludes);
|
||||
_EXTERNAL\**
|
||||
</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- These are needed for dealing with native Windows DLLs -->
|
||||
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND $(RuntimeIdentifier.StartsWith(`win-x86`))">
|
||||
<Content Include="*.dll">
|
||||
<Pack>true</Pack>
|
||||
<PackagePath>contentFiles;content</PackagePath>
|
||||
<IncludeInPackage>true</IncludeInPackage>
|
||||
<CopyToOutput>true</CopyToOutput>
|
||||
<BuildAction>Content</BuildAction>
|
||||
<copyToOutput>true</copyToOutput>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<!-- These are needed for dealing with native Windows DLLs -->
|
||||
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND $(RuntimeIdentifier.StartsWith(`win-x86`))">
|
||||
<Content Include="*.dll">
|
||||
<Pack>true</Pack>
|
||||
<PackagePath>contentFiles;content</PackagePath>
|
||||
<IncludeInPackage>true</IncludeInPackage>
|
||||
<CopyToOutput>true</CopyToOutput>
|
||||
<BuildAction>Content</BuildAction>
|
||||
<copyToOutput>true</copyToOutput>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Support for old .NET versions -->
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))">
|
||||
<PackageReference Include="MinThreadingBridge" Version="0.11.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`))">
|
||||
<PackageReference Include="OpenMcdf" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))">
|
||||
<PackageReference Include="SharpCompress" Version="0.38.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
|
||||
<PackageReference Include="System.Memory" Version="4.5.5" />
|
||||
</ItemGroup>
|
||||
<!-- Support for old .NET versions -->
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`))">
|
||||
<PackageReference Include="Net30.LinqBridge" Version="1.3.0" />
|
||||
<PackageReference Include="Net35.Actions" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`))">
|
||||
<PackageReference Include="OpenMcdf" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))">
|
||||
<PackageReference Include="MinAsyncBridge" Version="0.12.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))">
|
||||
<PackageReference Include="SharpCompress" Version="0.38.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.5.2" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.2.2" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.4.13" />
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.3.3" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.11" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.6.9" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.8.5" />
|
||||
<PackageReference Include="WiseUnpacker" Version="1.4.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.6.1" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.4.0" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.5.1" />
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.4.1" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.5.3" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.7.6" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.9.1" />
|
||||
<PackageReference Include="WiseUnpacker" Version="1.5.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -133,22 +132,26 @@ namespace BinaryObjectScanner.Data
|
||||
List<T> classTypes = [];
|
||||
|
||||
// If not all types can be loaded, use the ones that could be
|
||||
List<Type> assemblyTypes = [];
|
||||
Type?[] assemblyTypes = [];
|
||||
try
|
||||
{
|
||||
assemblyTypes = assembly.GetTypes().ToList<Type>();
|
||||
assemblyTypes = assembly.GetTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException rtle)
|
||||
{
|
||||
assemblyTypes = rtle.Types.Where(t => t != null)!.ToList<Type>();
|
||||
assemblyTypes = [.. rtle.Types];
|
||||
}
|
||||
|
||||
// Get information from the type param
|
||||
string interfaceName = typeof(T)!.FullName!;
|
||||
|
||||
// Loop through all types
|
||||
foreach (Type type in assemblyTypes)
|
||||
foreach (Type? type in assemblyTypes)
|
||||
{
|
||||
// Skip invalid types
|
||||
if (type == null)
|
||||
continue;
|
||||
|
||||
// If the type isn't a class
|
||||
if (!type.IsClass)
|
||||
continue;
|
||||
|
||||
9
BinaryObjectScanner/ExtensionAttribute.cs
Normal file
9
BinaryObjectScanner/ExtensionAttribute.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
#if NET20
|
||||
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
internal sealed class ExtensionAttribute : Attribute {}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -62,7 +62,7 @@ namespace BinaryObjectScanner
|
||||
WrapperType.TapeArchive => new FileType.TapeArchive(),
|
||||
WrapperType.VBSP => new FileType.VBSP(),
|
||||
WrapperType.VPK => new FileType.VPK(),
|
||||
WrapperType.WAD => new FileType.WAD(),
|
||||
WrapperType.WAD => new FileType.WAD3(),
|
||||
WrapperType.XZ => new FileType.XZ(),
|
||||
WrapperType.XZP => new FileType.XZP(),
|
||||
_ => null,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
@@ -32,7 +31,7 @@ namespace BinaryObjectScanner.FileType
|
||||
return null;
|
||||
|
||||
// Derive the version, if possible
|
||||
var typeAndVersion = mkb.Model.Records?.FirstOrDefault(r => r?.RecordType == SabreTools.Models.AACS.RecordType.TypeAndVersion);
|
||||
var typeAndVersion = Array.Find(mkb.Model.Records ?? [], r => r?.RecordType == SabreTools.Models.AACS.RecordType.TypeAndVersion);
|
||||
if (typeAndVersion == null)
|
||||
return "AACS (Unknown Version)";
|
||||
else
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Models.BSP;
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
{
|
||||
@@ -30,10 +30,11 @@ namespace BinaryObjectScanner.FileType
|
||||
if (bsp == null)
|
||||
return false;
|
||||
|
||||
// TODO: Introduce helper methods for all specialty lump types
|
||||
|
||||
// Loop through and extract all files
|
||||
Directory.CreateDirectory(outDir);
|
||||
ExtractAllLumps(bsp, outDir);
|
||||
ExtractAllTextures(bsp, outDir);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -52,12 +53,12 @@ namespace BinaryObjectScanner.FileType
|
||||
public static bool ExtractAllLumps(SabreTools.Serialization.Wrappers.BSP item, string outputDirectory)
|
||||
{
|
||||
// If we have no lumps
|
||||
if (item.Model.Lumps == null || item.Model.Lumps.Length == 0)
|
||||
if (item.Model.Header?.Lumps == null || item.Model.Header.Lumps.Length == 0)
|
||||
return false;
|
||||
|
||||
// Loop through and extract all lumps to the output
|
||||
bool allExtracted = true;
|
||||
for (int i = 0; i < item.Model.Lumps.Length; i++)
|
||||
for (int i = 0; i < item.Model.Header.Lumps.Length; i++)
|
||||
{
|
||||
allExtracted &= ExtractLump(item, i, outputDirectory);
|
||||
}
|
||||
@@ -74,15 +75,15 @@ namespace BinaryObjectScanner.FileType
|
||||
public static bool ExtractLump(SabreTools.Serialization.Wrappers.BSP item, int index, string outputDirectory)
|
||||
{
|
||||
// If we have no lumps
|
||||
if (item.Model.Lumps == null || item.Model.Lumps.Length == 0)
|
||||
if (item.Model.Header?.Lumps == null || item.Model.Header.Lumps.Length == 0)
|
||||
return false;
|
||||
|
||||
// If the lumps index is invalid
|
||||
if (index < 0 || index >= item.Model.Lumps.Length)
|
||||
if (index < 0 || index >= item.Model.Header.Lumps.Length)
|
||||
return false;
|
||||
|
||||
// Get the lump
|
||||
var lump = item.Model.Lumps[index];
|
||||
var lump = item.Model.Header.Lumps[index];
|
||||
if (lump == null)
|
||||
return false;
|
||||
|
||||
@@ -93,12 +94,12 @@ namespace BinaryObjectScanner.FileType
|
||||
|
||||
// Create the filename
|
||||
string filename = $"lump_{index}.bin";
|
||||
switch (index)
|
||||
switch ((LumpType)index)
|
||||
{
|
||||
case SabreTools.Models.BSP.Constants.HL_BSP_LUMP_ENTITIES:
|
||||
case LumpType.LUMP_ENTITIES:
|
||||
filename = "entities.ent";
|
||||
break;
|
||||
case SabreTools.Models.BSP.Constants.HL_BSP_LUMP_TEXTUREDATA:
|
||||
case LumpType.LUMP_TEXTURES:
|
||||
filename = "texture_data.bin";
|
||||
break;
|
||||
}
|
||||
@@ -119,10 +120,8 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -131,172 +130,5 @@ namespace BinaryObjectScanner.FileType
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract all textures from the BSP to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <returns>True if all textures extracted, false otherwise</returns>
|
||||
public static bool ExtractAllTextures(SabreTools.Serialization.Wrappers.BSP item, string outputDirectory)
|
||||
{
|
||||
// If we have no textures
|
||||
if (item.Model.TextureHeader?.Offsets == null || item.Model.TextureHeader.Offsets.Length == 0)
|
||||
return false;
|
||||
|
||||
// Loop through and extract all lumps to the output
|
||||
bool allExtracted = true;
|
||||
for (int i = 0; i < item.Model.TextureHeader.Offsets.Length; i++)
|
||||
{
|
||||
allExtracted &= ExtractTexture(item, i, outputDirectory);
|
||||
}
|
||||
|
||||
return allExtracted;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract a texture from the BSP to an output directory by index
|
||||
/// </summary>
|
||||
/// <param name="index">Lump index to extract</param>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <returns>True if the texture extracted, false otherwise</returns>
|
||||
public static bool ExtractTexture(SabreTools.Serialization.Wrappers.BSP item, int index, string outputDirectory)
|
||||
{
|
||||
// If we have no textures
|
||||
if (item.Model.Textures == null || item.Model.Textures.Length == 0)
|
||||
return false;
|
||||
|
||||
// If the texture index is invalid
|
||||
if (index < 0 || index >= item.Model.Textures.Length)
|
||||
return false;
|
||||
|
||||
// Get the texture
|
||||
var texture = item.Model.Textures[index];
|
||||
if (texture == null)
|
||||
return false;
|
||||
|
||||
// Read the data
|
||||
var data = CreateTextureData(texture);
|
||||
if (data == null)
|
||||
return false;
|
||||
|
||||
// Create the filename
|
||||
string filename = $"{texture.Name}.bmp";
|
||||
|
||||
// If we have an invalid output directory
|
||||
if (string.IsNullOrEmpty(outputDirectory))
|
||||
return false;
|
||||
|
||||
// Create the full output path
|
||||
filename = Path.Combine(outputDirectory, filename);
|
||||
|
||||
// Ensure the output directory is created
|
||||
var directoryName = Path.GetDirectoryName(filename);
|
||||
if (directoryName != null)
|
||||
Directory.CreateDirectory(directoryName);
|
||||
|
||||
// Try to write the data
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a bitmap from the texture and palette data
|
||||
/// </summary>
|
||||
/// <param name="texture">Texture object to format</param>
|
||||
/// <returns>Byte array representing the texture as a bitmap</returns>
|
||||
private static byte[]? CreateTextureData(SabreTools.Models.BSP.Texture texture)
|
||||
{
|
||||
// If there's no palette data
|
||||
if (texture.PaletteData == null || texture.PaletteData.Length == 0)
|
||||
return null;
|
||||
|
||||
// If there's no texture data
|
||||
if (texture.TextureData == null || texture.TextureData.Length == 0)
|
||||
return null;
|
||||
|
||||
// Create the bitmap file header
|
||||
var fileHeader = new SabreTools.Models.BMP.BITMAPFILEHEADER()
|
||||
{
|
||||
Type = ('M' << 8) | 'B',
|
||||
Size = 14 + 40 + (texture.PaletteSize * 4) + (texture.Width * texture.Height),
|
||||
OffBits = 14 + 40 + (texture.PaletteSize * 4),
|
||||
};
|
||||
|
||||
// Create the bitmap info header
|
||||
var infoHeader = new SabreTools.Models.BMP.BITMAPINFOHEADER
|
||||
{
|
||||
Size = 40,
|
||||
Width = (int)texture.Width,
|
||||
Height = (int)texture.Height,
|
||||
Planes = 1,
|
||||
BitCount = 8,
|
||||
SizeImage = 0,
|
||||
ClrUsed = texture.PaletteSize,
|
||||
ClrImportant = texture.PaletteSize,
|
||||
};
|
||||
|
||||
// Reformat the palette data
|
||||
byte[] paletteData = new byte[texture.PaletteSize * 4];
|
||||
for (uint i = 0; i < texture.PaletteSize; i++)
|
||||
{
|
||||
paletteData[i * 4 + 0] = texture.PaletteData[i * 3 + 2];
|
||||
paletteData[i * 4 + 1] = texture.PaletteData[i * 3 + 1];
|
||||
paletteData[i * 4 + 2] = texture.PaletteData[i * 3 + 0];
|
||||
paletteData[i * 4 + 3] = 0;
|
||||
}
|
||||
|
||||
// Reformat the pixel data
|
||||
byte[] pixelData = new byte[texture.Width * texture.Height];
|
||||
for (uint i = 0; i < texture.Width; i++)
|
||||
{
|
||||
for (uint j = 0; j < texture.Height; j++)
|
||||
{
|
||||
pixelData[i + ((texture.Height - 1 - j) * texture.Width)] = texture.TextureData[i + j * texture.Width];
|
||||
}
|
||||
}
|
||||
|
||||
// Build the file data
|
||||
List<byte> buffer = new List<byte>();
|
||||
|
||||
// Bitmap file header
|
||||
buffer.AddRange(BitConverter.GetBytes(fileHeader.Type));
|
||||
buffer.AddRange(BitConverter.GetBytes(fileHeader.Size));
|
||||
buffer.AddRange(BitConverter.GetBytes(fileHeader.Reserved1));
|
||||
buffer.AddRange(BitConverter.GetBytes(fileHeader.Reserved2));
|
||||
buffer.AddRange(BitConverter.GetBytes(fileHeader.OffBits));
|
||||
|
||||
// Bitmap info header
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.Size));
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.Width));
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.Height));
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.Planes));
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.BitCount));
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.Compression));
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.SizeImage));
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.XPelsPerMeter));
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.YPelsPerMeter));
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.ClrUsed));
|
||||
buffer.AddRange(BitConverter.GetBytes(infoHeader.ClrImportant));
|
||||
|
||||
// Palette data
|
||||
buffer.AddRange(paletteData);
|
||||
|
||||
// Pixel data
|
||||
buffer.AddRange(pixelData);
|
||||
|
||||
return buffer.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,41 +94,49 @@ namespace BinaryObjectScanner.FileType
|
||||
if (wrapper is MSDOS mz)
|
||||
{
|
||||
// Standard checks
|
||||
var subProtections = RunExecutableChecks(file, mz, StaticChecks.MSDOSExecutableCheckClasses, includeDebug);
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, mz, StaticChecks.MSDOSExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
|
||||
// Extractable checks
|
||||
var extractedProtections = HandleExtractableProtections(file, mz, subProtections.Keys, getProtections, includeDebug);
|
||||
var extractedProtections
|
||||
= HandleExtractableProtections(file, mz, subProtections.Keys, getProtections, includeDebug);
|
||||
protections.Append(extractedProtections);
|
||||
}
|
||||
else if (wrapper is LinearExecutable lex)
|
||||
{
|
||||
// Standard checks
|
||||
var subProtections = RunExecutableChecks(file, lex, StaticChecks.LinearExecutableCheckClasses, includeDebug);
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, lex, StaticChecks.LinearExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
|
||||
// Extractable checks
|
||||
var extractedProtections = HandleExtractableProtections(file, lex, subProtections.Keys, getProtections, includeDebug);
|
||||
var extractedProtections
|
||||
= HandleExtractableProtections(file, lex, subProtections.Keys, getProtections, includeDebug);
|
||||
protections.Append(extractedProtections);
|
||||
}
|
||||
else if (wrapper is NewExecutable nex)
|
||||
{
|
||||
// Standard checks
|
||||
var subProtections = RunExecutableChecks(file, nex, StaticChecks.NewExecutableCheckClasses, includeDebug);
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, nex, StaticChecks.NewExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
|
||||
// Extractable checks
|
||||
var extractedProtections = HandleExtractableProtections(file, nex, subProtections.Keys, getProtections, includeDebug);
|
||||
var extractedProtections
|
||||
= HandleExtractableProtections(file, nex, subProtections.Keys, getProtections, includeDebug);
|
||||
protections.Append(extractedProtections);
|
||||
}
|
||||
else if (wrapper is PortableExecutable pex)
|
||||
{
|
||||
// Standard checks
|
||||
var subProtections = RunExecutableChecks(file, pex, StaticChecks.PortableExecutableCheckClasses, includeDebug);
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, pex, StaticChecks.PortableExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
|
||||
// Extractable checks
|
||||
var extractedProtections = HandleExtractableProtections(file, pex, subProtections.Keys, getProtections, includeDebug);
|
||||
var extractedProtections
|
||||
= HandleExtractableProtections(file, pex, subProtections.Keys, getProtections, includeDebug);
|
||||
protections.Append(extractedProtections);
|
||||
}
|
||||
|
||||
@@ -155,10 +163,15 @@ namespace BinaryObjectScanner.FileType
|
||||
else if (!File.Exists(file))
|
||||
return protections;
|
||||
|
||||
// If the stream isn't seekable
|
||||
if (!stream.CanSeek)
|
||||
return protections;
|
||||
|
||||
// Read the file contents
|
||||
byte[] fileContent = [];
|
||||
try
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
fileContent = stream.ReadBytes((int)stream.Length);
|
||||
if (fileContent == null)
|
||||
return protections;
|
||||
@@ -240,7 +253,7 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <returns>Set of protections found from extraction, empty on error</returns>
|
||||
private static ProtectionDictionary HandleExtractableProtections<T, U>(string file,
|
||||
T exe,
|
||||
IEnumerable<U> checks,
|
||||
ICollection<U> checks,
|
||||
Func<string, ProtectionDictionary>? getProtections,
|
||||
bool includeDebug)
|
||||
where T : WrapperBase
|
||||
@@ -250,7 +263,7 @@ namespace BinaryObjectScanner.FileType
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// If we have an invalid set of classes
|
||||
if (checks == null || !checks.Any())
|
||||
if (checks == null)
|
||||
return protections;
|
||||
|
||||
// If we have any extractable packers
|
||||
|
||||
@@ -126,19 +126,18 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
// Now read the data sequentially and write out while we have data left
|
||||
long fileSize = file.Size;
|
||||
for (int i = 0; i < dataBlockOffsets.Count; i++)
|
||||
{
|
||||
int readSize = (int)Math.Min(item.Model.DataBlockHeader?.BlockSize ?? 0, fileSize);
|
||||
var data = item.ReadFromDataSource((int)dataBlockOffsets[i], readSize);
|
||||
if (data == null)
|
||||
return false;
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
// Now read the data sequentially and write out while we have data left
|
||||
long fileSize = file.Size;
|
||||
for (int i = 0; i < dataBlockOffsets.Count; i++)
|
||||
{
|
||||
int readSize = (int)Math.Min(item.Model.DataBlockHeader?.BlockSize ?? 0, fileSize);
|
||||
var data = item.ReadFromDataSource((int)dataBlockOffsets[i], readSize);
|
||||
if (data == null)
|
||||
return false;
|
||||
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
byte[] magic = new byte[16];
|
||||
stream.Read(magic, 0, 16);
|
||||
int read = stream.Read(magic, 0, 16);
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x4C, 0x44, 0x53, 0x43, 0x52, 0x59, 0x50, 0x54 }))
|
||||
return "Link Data Security encrypted file";
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(Stream? stream, string file, string outDir, bool includeDebug)
|
||||
{
|
||||
#if NET20 || NET35 || NET40 || !WIN
|
||||
#if NET20 || NET35 || !WIN
|
||||
// Not supported for old .NET due to feature requirements
|
||||
// Not supported in non-Windows builds due to DLL requirements
|
||||
return false;
|
||||
|
||||
@@ -108,10 +108,8 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
byte[] magic = new byte[16];
|
||||
stream.Read(magic, 0, 16);
|
||||
int read = stream.Read(magic, 0, 16);
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0xFF, 0x9D, 0x53, 0x4B }))
|
||||
return "PlayJ Audio File";
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
byte[] magic = new byte[16];
|
||||
stream.Read(magic, 0, 16);
|
||||
int read = stream.Read(magic, 0, 16);
|
||||
|
||||
// RASGI2.0
|
||||
// Found in the ".rgs" files in IA item "Nova_RealArcadeCD_USA".
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
byte[] magic = new byte[16];
|
||||
stream.Read(magic, 0, 16);
|
||||
int read = stream.Read(magic, 0, 16);
|
||||
|
||||
// XZip2.0
|
||||
// Found in the ".mez" files in IA item "Nova_RealArcadeCD_USA".
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
byte[] magic = new byte[16];
|
||||
stream.Read(magic, 0, 16);
|
||||
int read = stream.Read(magic, 0, 16);
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x53, 0x46, 0x46, 0x53 }))
|
||||
return "StarForce Filesystem Container";
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Compression.zlib;
|
||||
|
||||
@@ -52,16 +51,15 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <returns>True if all files extracted, false otherwise</returns>
|
||||
public static bool ExtractAll(SabreTools.Serialization.Wrappers.SGA item, string outputDirectory)
|
||||
{
|
||||
// Get the number of files
|
||||
int filesLength;
|
||||
switch (item.Model.Header?.MajorVersion)
|
||||
// Get the file count
|
||||
int filesLength = item.Model.Directory switch
|
||||
{
|
||||
case 4: filesLength = (item.Model.Directory as SabreTools.Models.SGA.Directory4)?.Files?.Length ?? 0; break;
|
||||
case 5: filesLength = (item.Model.Directory as SabreTools.Models.SGA.Directory5)?.Files?.Length ?? 0; break;
|
||||
case 6: filesLength = (item.Model.Directory as SabreTools.Models.SGA.Directory6)?.Files?.Length ?? 0; break;
|
||||
case 7: filesLength = (item.Model.Directory as SabreTools.Models.SGA.Directory7)?.Files?.Length ?? 0; break;
|
||||
default: return false;
|
||||
}
|
||||
SabreTools.Models.SGA.Directory4 d4 => filesLength = d4.Files?.Length ?? 0,
|
||||
SabreTools.Models.SGA.Directory5 d5 => filesLength = d5.Files?.Length ?? 0,
|
||||
SabreTools.Models.SGA.Directory6 d6 => filesLength = d6.Files?.Length ?? 0,
|
||||
SabreTools.Models.SGA.Directory7 d7 => filesLength = d7.Files?.Length ?? 0,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
// If we have no files
|
||||
if (filesLength == 0)
|
||||
@@ -85,16 +83,15 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <returns>True if the file extracted, false otherwise</returns>
|
||||
public static bool ExtractFile(SabreTools.Serialization.Wrappers.SGA item, int index, string outputDirectory)
|
||||
{
|
||||
// Get the number of files
|
||||
int filesLength;
|
||||
switch (item.Model.Header?.MajorVersion)
|
||||
// Get the file count
|
||||
int filesLength = item.Model.Directory switch
|
||||
{
|
||||
case 4: filesLength = (item.Model.Directory as SabreTools.Models.SGA.Directory4)?.Files?.Length ?? 0; break;
|
||||
case 5: filesLength = (item.Model.Directory as SabreTools.Models.SGA.Directory5)?.Files?.Length ?? 0; break;
|
||||
case 6: filesLength = (item.Model.Directory as SabreTools.Models.SGA.Directory6)?.Files?.Length ?? 0; break;
|
||||
case 7: filesLength = (item.Model.Directory as SabreTools.Models.SGA.Directory7)?.Files?.Length ?? 0; break;
|
||||
default: return false;
|
||||
}
|
||||
SabreTools.Models.SGA.Directory4 d4 => filesLength = d4.Files?.Length ?? 0,
|
||||
SabreTools.Models.SGA.Directory5 d5 => filesLength = d5.Files?.Length ?? 0,
|
||||
SabreTools.Models.SGA.Directory6 d6 => filesLength = d6.Files?.Length ?? 0,
|
||||
SabreTools.Models.SGA.Directory7 d7 => filesLength = d7.Files?.Length ?? 0,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
// If we have no files
|
||||
if (filesLength == 0)
|
||||
@@ -105,55 +102,53 @@ namespace BinaryObjectScanner.FileType
|
||||
return false;
|
||||
|
||||
// Get the files
|
||||
object? file;
|
||||
switch (item.Model.Header?.MajorVersion)
|
||||
object? file = item.Model.Directory switch
|
||||
{
|
||||
case 4: file = (item.Model.Directory as SabreTools.Models.SGA.Directory4)?.Files?[index]; break;
|
||||
case 5: file = (item.Model.Directory as SabreTools.Models.SGA.Directory5)?.Files?[index]; break;
|
||||
case 6: file = (item.Model.Directory as SabreTools.Models.SGA.Directory6)?.Files?[index]; break;
|
||||
case 7: file = (item.Model.Directory as SabreTools.Models.SGA.Directory7)?.Files?[index]; break;
|
||||
default: return false;
|
||||
}
|
||||
SabreTools.Models.SGA.Directory4 d4 => d4.Files![index],
|
||||
SabreTools.Models.SGA.Directory5 d5 => d5.Files![index],
|
||||
SabreTools.Models.SGA.Directory6 d6 => d6.Files![index],
|
||||
SabreTools.Models.SGA.Directory7 d7 => d7.Files![index],
|
||||
_ => null,
|
||||
};
|
||||
|
||||
// If the file is invalid
|
||||
if (file == null)
|
||||
return false;
|
||||
|
||||
// Create the filename
|
||||
var filename = string.Empty;
|
||||
switch (item.Model.Header?.MajorVersion)
|
||||
var filename = file switch
|
||||
{
|
||||
case 4:
|
||||
case 5: filename = (file as SabreTools.Models.SGA.File4)?.Name; break;
|
||||
case 6: filename = (file as SabreTools.Models.SGA.File6)?.Name; break;
|
||||
case 7: filename = (file as SabreTools.Models.SGA.File7)?.Name; break;
|
||||
default: return false;
|
||||
}
|
||||
SabreTools.Models.SGA.File4 f4 => f4.Name,
|
||||
_ => null,
|
||||
};
|
||||
|
||||
// If the filename is invalid
|
||||
if (filename == null)
|
||||
return false;
|
||||
|
||||
// Loop through and get all parent directories
|
||||
var parentNames = new List<string?> { filename };
|
||||
var parentNames = new List<string> { filename };
|
||||
|
||||
// Get the parent directory
|
||||
var folder = default(object);
|
||||
switch (item.Model.Header?.MajorVersion)
|
||||
var folder = item.Model.Directory switch
|
||||
{
|
||||
case 4: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory4)?.Folders?.FirstOrDefault(f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex); break;
|
||||
case 5: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory5)?.Folders?.FirstOrDefault(f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex); break;
|
||||
case 6: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory6)?.Folders?.FirstOrDefault(f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex); break;
|
||||
case 7: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory7)?.Folders?.FirstOrDefault(f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex); break;
|
||||
default: return false;
|
||||
}
|
||||
SabreTools.Models.SGA.Directory4 d4 => Array.Find(d4.Folders ?? [], f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex),
|
||||
SabreTools.Models.SGA.Directory5 d5 => Array.Find(d5.Folders ?? [], f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex),
|
||||
SabreTools.Models.SGA.Directory6 d6 => Array.Find(d6.Folders ?? [], f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex),
|
||||
SabreTools.Models.SGA.Directory7 d7 => Array.Find(d7.Folders ?? [], f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex),
|
||||
_ => default(object),
|
||||
};
|
||||
|
||||
// If we have a parent folder
|
||||
if (folder != null)
|
||||
{
|
||||
switch (item.Model.Header?.MajorVersion)
|
||||
string folderName = folder switch
|
||||
{
|
||||
case 4: parentNames.Add((folder as SabreTools.Models.SGA.Folder4)?.Name); break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7: parentNames.Add((folder as SabreTools.Models.SGA.Folder5)?.Name); break;
|
||||
default: return false;
|
||||
}
|
||||
SabreTools.Models.SGA.Folder4 f4 => f4.Name ?? string.Empty,
|
||||
SabreTools.Models.SGA.Folder5 f5 => f5.Name ?? string.Empty,
|
||||
_ => string.Empty,
|
||||
};
|
||||
parentNames.Add(folderName);
|
||||
}
|
||||
|
||||
// TODO: Should the section name/alias be used in the path as well?
|
||||
@@ -161,55 +156,45 @@ namespace BinaryObjectScanner.FileType
|
||||
// Reverse and assemble the filename
|
||||
parentNames.Reverse();
|
||||
#if NET20 || NET35
|
||||
var parentNamesArray = parentNames.Cast<string>().ToArray();
|
||||
filename = parentNamesArray[0];
|
||||
for (int i = 1; i < parentNamesArray.Length; i++)
|
||||
filename = parentNames[0];
|
||||
for (int i = 1; i < parentNames.Count; i++)
|
||||
{
|
||||
filename = Path.Combine(filename, parentNamesArray[i]);
|
||||
filename = Path.Combine(filename, parentNames[i]);
|
||||
}
|
||||
#else
|
||||
filename = Path.Combine(parentNames.Cast<string>().ToArray());
|
||||
filename = Path.Combine([.. parentNames]);
|
||||
#endif
|
||||
|
||||
// Get the file offset
|
||||
long fileOffset;
|
||||
switch (item.Model.Header?.MajorVersion)
|
||||
long fileOffset = file switch
|
||||
{
|
||||
case 4:
|
||||
case 5: fileOffset = (file as SabreTools.Models.SGA.File4)?.Offset ?? 0; break;
|
||||
case 6: fileOffset = (file as SabreTools.Models.SGA.File6)?.Offset ?? 0; break;
|
||||
case 7: fileOffset = (file as SabreTools.Models.SGA.File7)?.Offset ?? 0; break;
|
||||
default: return false;
|
||||
}
|
||||
SabreTools.Models.SGA.File4 f4 => f4.Offset,
|
||||
_ => -1,
|
||||
};
|
||||
|
||||
// Adjust the file offset
|
||||
switch (item.Model.Header?.MajorVersion)
|
||||
fileOffset += item.Model.Header switch
|
||||
{
|
||||
case 4: fileOffset += (item.Model.Header as SabreTools.Models.SGA.Header4)?.FileDataOffset ?? 0; break;
|
||||
case 5: fileOffset += (item.Model.Header as SabreTools.Models.SGA.Header4)?.FileDataOffset ?? 0; break;
|
||||
case 6: fileOffset += (item.Model.Header as SabreTools.Models.SGA.Header6)?.FileDataOffset ?? 0; break;
|
||||
case 7: fileOffset += (item.Model.Header as SabreTools.Models.SGA.Header6)?.FileDataOffset ?? 0; break;
|
||||
default: return false;
|
||||
SabreTools.Models.SGA.Header4 h4 => h4.FileDataOffset,
|
||||
SabreTools.Models.SGA.Header6 h6 => h6.FileDataOffset,
|
||||
_ => -1,
|
||||
};
|
||||
|
||||
// If the offset is invalid
|
||||
if (fileOffset < 0)
|
||||
return false;
|
||||
|
||||
// Get the file sizes
|
||||
long fileSize, outputFileSize;
|
||||
switch (item.Model.Header?.MajorVersion)
|
||||
switch (file)
|
||||
{
|
||||
case 4:
|
||||
case 5:
|
||||
fileSize = (file as SabreTools.Models.SGA.File4)?.SizeOnDisk ?? 0;
|
||||
outputFileSize = (file as SabreTools.Models.SGA.File4)?.Size ?? 0;
|
||||
case SabreTools.Models.SGA.File4 f4:
|
||||
fileSize = f4.SizeOnDisk;
|
||||
outputFileSize = f4.Size;
|
||||
break;
|
||||
case 6:
|
||||
fileSize = (file as SabreTools.Models.SGA.File6)?.SizeOnDisk ?? 0;
|
||||
outputFileSize = (file as SabreTools.Models.SGA.File6)?.Size ?? 0;
|
||||
break;
|
||||
case 7:
|
||||
fileSize = (file as SabreTools.Models.SGA.File7)?.SizeOnDisk ?? 0;
|
||||
outputFileSize = (file as SabreTools.Models.SGA.File7)?.Size ?? 0;
|
||||
break;
|
||||
default: return false;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the compressed data directly
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Models.BSP;
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
{
|
||||
@@ -29,6 +30,8 @@ namespace BinaryObjectScanner.FileType
|
||||
if (vbsp == null)
|
||||
return false;
|
||||
|
||||
// TODO: Introduce helper methods for all specialty lump types
|
||||
|
||||
// Loop through and extract all files
|
||||
Directory.CreateDirectory(outDir);
|
||||
ExtractAllLumps(vbsp, outDir);
|
||||
@@ -91,12 +94,12 @@ namespace BinaryObjectScanner.FileType
|
||||
|
||||
// Create the filename
|
||||
string filename = $"lump_{index}.bin";
|
||||
switch (index)
|
||||
switch ((LumpType)index)
|
||||
{
|
||||
case SabreTools.Models.VBSP.Constants.HL_VBSP_LUMP_ENTITIES:
|
||||
case LumpType.LUMP_ENTITIES:
|
||||
filename = "entities.ent";
|
||||
break;
|
||||
case SabreTools.Models.VBSP.Constants.HL_VBSP_LUMP_PAKFILE:
|
||||
case LumpType.LUMP_PAKFILE:
|
||||
filename = "pakfile.zip";
|
||||
break;
|
||||
}
|
||||
@@ -117,10 +120,8 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.IO.Extensions;
|
||||
|
||||
@@ -138,7 +137,7 @@ namespace BinaryObjectScanner.FileType
|
||||
|
||||
// If we have preload data, prepend it
|
||||
if (data != null && directoryItem.PreloadData != null)
|
||||
data = directoryItem.PreloadData.Concat(data).ToArray();
|
||||
data = [.. directoryItem.PreloadData, .. data];
|
||||
}
|
||||
|
||||
// If there is nothing to write out
|
||||
@@ -166,10 +165,8 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <summary>
|
||||
/// Half-Life Texture Package File
|
||||
/// </summary>
|
||||
public class WAD : IExtractable
|
||||
public class WAD3 : IExtractable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string file, string outDir, bool includeDebug)
|
||||
@@ -25,7 +25,7 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
// Create the wrapper
|
||||
var wad = SabreTools.Serialization.Wrappers.WAD.Create(stream);
|
||||
var wad = SabreTools.Serialization.Wrappers.WAD3.Create(stream);
|
||||
if (wad == null)
|
||||
return false;
|
||||
|
||||
@@ -43,19 +43,19 @@ namespace BinaryObjectScanner.FileType
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract all lumps from the WAD to an output directory
|
||||
/// Extract all lumps from the WAD3 to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <returns>True if all lumps extracted, false otherwise</returns>
|
||||
public static bool ExtractAllLumps(SabreTools.Serialization.Wrappers.WAD item, string outputDirectory)
|
||||
public static bool ExtractAllLumps(SabreTools.Serialization.Wrappers.WAD3 item, string outputDirectory)
|
||||
{
|
||||
// If we have no lumps
|
||||
if (item.Model.Lumps == null || item.Model.Lumps.Length == 0)
|
||||
if (item.Model.DirEntries == null || item.Model.DirEntries.Length == 0)
|
||||
return false;
|
||||
|
||||
// Loop through and extract all lumps to the output
|
||||
bool allExtracted = true;
|
||||
for (int i = 0; i < item.Model.Lumps.Length; i++)
|
||||
for (int i = 0; i < item.Model.DirEntries.Length; i++)
|
||||
{
|
||||
allExtracted &= ExtractLump(item, i, outputDirectory);
|
||||
}
|
||||
@@ -64,23 +64,23 @@ namespace BinaryObjectScanner.FileType
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract a lump from the WAD to an output directory by index
|
||||
/// Extract a lump from the WAD3 to an output directory by index
|
||||
/// </summary>
|
||||
/// <param name="index">Lump index to extract</param>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <returns>True if the lump extracted, false otherwise</returns>
|
||||
public static bool ExtractLump(SabreTools.Serialization.Wrappers.WAD item, int index, string outputDirectory)
|
||||
public static bool ExtractLump(SabreTools.Serialization.Wrappers.WAD3 item, int index, string outputDirectory)
|
||||
{
|
||||
// If we have no lumps
|
||||
if (item.Model.Lumps == null || item.Model.Lumps.Length == 0)
|
||||
if (item.Model.DirEntries == null || item.Model.DirEntries.Length == 0)
|
||||
return false;
|
||||
|
||||
// If the lumps index is invalid
|
||||
if (index < 0 || index >= item.Model.Lumps.Length)
|
||||
if (index < 0 || index >= item.Model.DirEntries.Length)
|
||||
return false;
|
||||
|
||||
// Get the lump
|
||||
var lump = item.Model.Lumps[index];
|
||||
var lump = item.Model.DirEntries[index];
|
||||
if (lump == null)
|
||||
return false;
|
||||
|
||||
@@ -108,10 +108,8 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
@@ -90,7 +89,7 @@ namespace BinaryObjectScanner.FileType
|
||||
return false;
|
||||
|
||||
// Get the associated directory item
|
||||
var directoryItem = item.Model.DirectoryItems.Where(di => di?.FileNameCRC == directoryEntry.FileNameCRC).FirstOrDefault();
|
||||
var directoryItem = Array.Find(item.Model.DirectoryItems, di => di?.FileNameCRC == directoryEntry.FileNameCRC);
|
||||
if (directoryItem == null)
|
||||
return false;
|
||||
|
||||
@@ -118,10 +117,8 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace BinaryObjectScanner.Interfaces
|
||||
/// Check a file path for protections based on path name
|
||||
/// </summary>
|
||||
/// <param name="path">Path to check for protection indicators</param>
|
||||
/// <param name="files">Enumerable of strings representing files in a directory</param>
|
||||
/// <param name="files">List of strings representing files in a directory</param>
|
||||
/// <remarks>This can do some limited content checking as well, but it's suggested to use a content check instead, if possible</remarks>
|
||||
IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files);
|
||||
List<string> CheckDirectoryPath(string path, List<string>? files);
|
||||
|
||||
/// <summary>
|
||||
/// Check a file path for protections based on path name
|
||||
|
||||
@@ -19,8 +19,7 @@ namespace BinaryObjectScanner.Packer
|
||||
return null;
|
||||
|
||||
// Get the .aspack section, if it exists
|
||||
bool aspackSection = pex.ContainsSection(".aspack", exact: true);
|
||||
if (aspackSection)
|
||||
if (pex.ContainsSection(".aspack", exact: true))
|
||||
return "ASPack 2.29";
|
||||
|
||||
// TODO: Re-enable all Entry Point checks after implementing
|
||||
@@ -60,10 +59,10 @@ namespace BinaryObjectScanner.Packer
|
||||
/// Generate the set of matchers used for each section
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private List<ContentMatchSet> GenerateMatchers()
|
||||
private static List<ContentMatchSet> GenerateMatchers()
|
||||
{
|
||||
return new List<ContentMatchSet>
|
||||
{
|
||||
return
|
||||
[
|
||||
#region No Wildcards (Long)
|
||||
|
||||
new(new byte?[]
|
||||
@@ -641,7 +640,7 @@ namespace BinaryObjectScanner.Packer
|
||||
new(new byte?[] { 0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81, 0xED }, "ASPack 1.02b/1.08.03"),
|
||||
|
||||
#endregion
|
||||
};
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -20,7 +19,7 @@ namespace BinaryObjectScanner.Packer
|
||||
var strs = pex.GetFirstSectionStrings(".rdata");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("Software\\Caphyon\\Advanced Installer")))
|
||||
if (strs.Exists(s => s.Contains("Software\\Caphyon\\Advanced Installer")))
|
||||
return "Caphyon Advanced Installer";
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace BinaryObjectScanner.Packer
|
||||
name = Utilities.GetLegalCopyright(pex);
|
||||
if (name?.StartsWith("Runtime Engine", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"AutoPlay Media Studio {GetVersion(pex)}";
|
||||
*/
|
||||
*/
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ namespace BinaryObjectScanner.Packer
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
private static string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
// Check the product version explicitly
|
||||
var version = pex.ProductVersion;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Compression.zlib;
|
||||
using SabreTools.Matching;
|
||||
@@ -24,23 +23,23 @@ namespace BinaryObjectScanner.Packer
|
||||
return null;
|
||||
|
||||
// If there are exactly 2 resources with type 99
|
||||
if (pex.FindResourceByNamedType("99, ").Count() == 2)
|
||||
if (pex.FindResourceByNamedType("99, ").Count == 2)
|
||||
return "CExe";
|
||||
|
||||
if (pex.StubExecutableData != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
new(new byte?[]
|
||||
{
|
||||
0x25, 0x57, 0x6F, 0xC1, 0x61, 0x36, 0x01, 0x92,
|
||||
0x61, 0x36, 0x01, 0x92, 0x61, 0x36, 0x01, 0x92,
|
||||
0x61, 0x36, 0x00, 0x92, 0x7B, 0x36, 0x01, 0x92,
|
||||
0x03, 0x29, 0x12, 0x92, 0x66, 0x36, 0x01, 0x92,
|
||||
0x89, 0x29, 0x0A, 0x92, 0x60, 0x36, 0x01, 0x92,
|
||||
0xD9, 0x30, 0x07, 0x92, 0x60, 0x36, 0x01, 0x92
|
||||
}, "CExe")
|
||||
};
|
||||
new(new byte?[]
|
||||
{
|
||||
0x25, 0x57, 0x6F, 0xC1, 0x61, 0x36, 0x01, 0x92,
|
||||
0x61, 0x36, 0x01, 0x92, 0x61, 0x36, 0x01, 0x92,
|
||||
0x61, 0x36, 0x00, 0x92, 0x7B, 0x36, 0x01, 0x92,
|
||||
0x03, 0x29, 0x12, 0x92, 0x66, 0x36, 0x01, 0x92,
|
||||
0x89, 0x29, 0x0A, 0x92, 0x60, 0x36, 0x01, 0x92,
|
||||
0xD9, 0x30, 0x07, 0x92, 0x60, 0x36, 0x01, 0x92
|
||||
}, "CExe")
|
||||
};
|
||||
|
||||
var match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug);
|
||||
if (!string.IsNullOrEmpty(match))
|
||||
@@ -55,19 +54,21 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get all resources of type 99 with index 2
|
||||
var resources = pex.FindResourceByNamedType("99, 2");
|
||||
if (resources == null || resources.Count == 0)
|
||||
return false;
|
||||
|
||||
// Get the first resource of type 99 with index 2
|
||||
var payload = pex.FindResourceByNamedType("99, 2").FirstOrDefault();
|
||||
var payload = resources[0];
|
||||
if (payload == null || payload.Length == 0)
|
||||
return false;
|
||||
|
||||
// Determine which compression was used
|
||||
bool zlib = pex.FindResourceByNamedType("99, 1").Any();
|
||||
|
||||
// Create the output data buffer
|
||||
var data = new byte[0];
|
||||
byte[]? data = [];
|
||||
|
||||
// If we had the decompression DLL included, it's zlib
|
||||
if (zlib)
|
||||
if (pex.FindResourceByNamedType("99, 1").Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -94,12 +95,12 @@ namespace BinaryObjectScanner.Packer
|
||||
|
||||
// Trim the buffer to the proper size
|
||||
uint read = zstream.total_out;
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
data = new ReadOnlySpan<byte>(data, 0, (int)read).ToArray();
|
||||
#else
|
||||
#if NETFRAMEWORK
|
||||
var temp = new byte[read];
|
||||
Array.Copy(data, 0, temp, 0, read);
|
||||
data = temp;
|
||||
#else
|
||||
data = new ReadOnlySpan<byte>(data, 0, (int)read).ToArray();
|
||||
#endif
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
@@ -19,7 +18,7 @@ namespace BinaryObjectScanner.Packer
|
||||
var strs = pex.GetFirstSectionStrings(".text");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("DotfuscatorAttribute")))
|
||||
if (strs.Exists(s => s.Contains("DotfuscatorAttribute")))
|
||||
return "dotFuscator";
|
||||
}
|
||||
|
||||
|
||||
@@ -28,71 +28,67 @@ namespace BinaryObjectScanner.Packer
|
||||
return null;
|
||||
|
||||
// Get the .text section, if it exists
|
||||
if (pex.ContainsSection(".text"))
|
||||
var textData = pex.GetFirstSectionData(".text");
|
||||
if (textData != null)
|
||||
{
|
||||
var textData = pex.GetFirstSectionData(".text");
|
||||
if (textData != null)
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
// Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617.
|
||||
// <PrivateImplementationDetails>{[8]-[4]-[4]-[4]-[12]}
|
||||
new(new byte?[]
|
||||
{
|
||||
// Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617.
|
||||
// <PrivateImplementationDetails>{[8]-[4]-[4]-[4]-[12]}
|
||||
new(new byte?[]
|
||||
{
|
||||
0x3C, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
|
||||
0x49, 0x6D, 0x70, 0x6C, 0x65, 0x6D, 0x65, 0x6E,
|
||||
0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x65,
|
||||
0x74, 0x61, 0x69, 0x6C, 0x73, 0x3E, 0x7B, null,
|
||||
null, null, null, null, null, null, null, 0x2D,
|
||||
null, null, null, null, 0x2D, null, null, null,
|
||||
null, 0x2D, null, null, null, null, 0x2D, null,
|
||||
null, null, null, null, null, null, null, null,
|
||||
null, null, null, 0x7D
|
||||
}, ".NET Reactor"),
|
||||
0x3C, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
|
||||
0x49, 0x6D, 0x70, 0x6C, 0x65, 0x6D, 0x65, 0x6E,
|
||||
0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x65,
|
||||
0x74, 0x61, 0x69, 0x6C, 0x73, 0x3E, 0x7B, null,
|
||||
null, null, null, null, null, null, null, 0x2D,
|
||||
null, null, null, null, 0x2D, null, null, null,
|
||||
null, 0x2D, null, null, null, null, 0x2D, null,
|
||||
null, null, null, null, null, null, null, null,
|
||||
null, null, null, 0x7D
|
||||
}, ".NET Reactor"),
|
||||
|
||||
// Modified from the previous detection to detect a presumably newer version of .NET Reactor found in "KalypsoLauncher.dll" version 2.0.4.2.
|
||||
// TODO: Check if this can/should be made more specific.
|
||||
// <PrivateImplementationDetails>.RSA
|
||||
new(new byte?[]
|
||||
{
|
||||
0x3C, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
|
||||
0x49, 0x6D, 0x70, 0x6C, 0x65, 0x6D, 0x65, 0x6E,
|
||||
0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x65,
|
||||
0x74, 0x61, 0x69, 0x6C, 0x73, 0x3E, 0x00, 0x52,
|
||||
0x53, 0x41
|
||||
}, ".NET Reactor"),
|
||||
// Modified from the previous detection to detect a presumably newer version of .NET Reactor found in "KalypsoLauncher.dll" version 2.0.4.2.
|
||||
// TODO: Check if this can/should be made more specific.
|
||||
// <PrivateImplementationDetails>.RSA
|
||||
new(new byte?[]
|
||||
{
|
||||
0x3C, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
|
||||
0x49, 0x6D, 0x70, 0x6C, 0x65, 0x6D, 0x65, 0x6E,
|
||||
0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x65,
|
||||
0x74, 0x61, 0x69, 0x6C, 0x73, 0x3E, 0x00, 0x52,
|
||||
0x53, 0x41
|
||||
}, ".NET Reactor"),
|
||||
|
||||
// Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617.
|
||||
// 3{.[9].-.[9].-.[9].}
|
||||
new(new byte?[]
|
||||
{
|
||||
0x33, 0x7B, 0x00, null, null, null, null, null,
|
||||
null, null, null, null, 0x00, 0x2D, 0x00, null,
|
||||
null, null, null, null, null, null, null, null,
|
||||
0x00, 0x2D, 0x00, null, null, null, null, null,
|
||||
null, null, null, null, 0x00, 0x2D, 0x00, null,
|
||||
null, null, null, null, null, null, null, null,
|
||||
0x00, 0x7D, 0x00
|
||||
}, ".NET Reactor (Unconfirmed - Please report to us on GitHub)"),
|
||||
|
||||
// Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617.
|
||||
// <Module>{[8]-[4]-[4]-[4]-[12]}
|
||||
new(new byte?[]
|
||||
{
|
||||
0x3C, 0x4D, 0x6F, 0x64, 0x75, 0x6C, 0x65, 0x3E,
|
||||
0x7B, null, null, null, null, null, null, null,
|
||||
null, 0x2D, null, null, null, null, 0x2D, null,
|
||||
null, null, null, 0x2D, null, null, null, null,
|
||||
0x2D, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, 0x7D
|
||||
}, ".NET Reactor (Unconfirmed - Please report to us on GitHub)")
|
||||
};
|
||||
// Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617.
|
||||
// 3{.[9].-.[9].-.[9].}
|
||||
new(new byte?[]
|
||||
{
|
||||
0x33, 0x7B, 0x00, null, null, null, null, null,
|
||||
null, null, null, null, 0x00, 0x2D, 0x00, null,
|
||||
null, null, null, null, null, null, null, null,
|
||||
0x00, 0x2D, 0x00, null, null, null, null, null,
|
||||
null, null, null, null, 0x00, 0x2D, 0x00, null,
|
||||
null, null, null, null, null, null, null, null,
|
||||
0x00, 0x7D, 0x00
|
||||
}, ".NET Reactor (Unconfirmed - Please report to us on GitHub)"),
|
||||
|
||||
// Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617.
|
||||
// <Module>{[8]-[4]-[4]-[4]-[12]}
|
||||
new(new byte?[]
|
||||
{
|
||||
0x3C, 0x4D, 0x6F, 0x64, 0x75, 0x6C, 0x65, 0x3E,
|
||||
0x7B, null, null, null, null, null, null, null,
|
||||
null, 0x2D, null, null, null, null, 0x2D, null,
|
||||
null, null, null, 0x2D, null, null, null, null,
|
||||
0x2D, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, 0x7D
|
||||
}, ".NET Reactor (Unconfirmed - Please report to us on GitHub)")
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, textData, matchers, includeDebug);
|
||||
}
|
||||
return MatchUtil.GetFirstMatch(file, textData, matchers, includeDebug);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,26 +15,25 @@ namespace BinaryObjectScanner.Packer
|
||||
/// <inheritdoc/>
|
||||
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// Only allow during debug
|
||||
if (!includeDebug)
|
||||
return null;
|
||||
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
// ??[[__[[_ + (char)0x00 + {{ + (char)0x0 + (char)0x00 + {{ + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x0 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + ?;??;??
|
||||
new(new byte?[]
|
||||
{
|
||||
0x3F, 0x3F, 0x5B, 0x5B, 0x5F, 0x5F, 0x5B, 0x5B,
|
||||
0x5F, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x7B, 0x7B,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x20, 0x3F, 0x3B, 0x3F, 0x3F, 0x3B, 0x3F,
|
||||
0x3F
|
||||
}, "EXE Stealth"),
|
||||
};
|
||||
// ??[[__[[_ + (char)0x00 + {{ + (char)0x0 + (char)0x00 + {{ + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x0 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + ?;??;??
|
||||
new(new byte?[]
|
||||
{
|
||||
0x3F, 0x3F, 0x5B, 0x5B, 0x5F, 0x5F, 0x5B, 0x5B,
|
||||
0x5F, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x7B, 0x7B,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x20, 0x3F, 0x3B, 0x3F, 0x3F, 0x3B, 0x3F,
|
||||
0x3F
|
||||
}, "EXE Stealth"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
return null;
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -57,18 +56,17 @@ namespace BinaryObjectScanner.Packer
|
||||
// `ExeStealth V2 Shareware not for public - This text not in registered version - www.webtoolmaster.com`
|
||||
|
||||
// Get the ExeS/EXES section, if it exists
|
||||
bool exesSection = pex.ContainsSection("ExeS", exact: true) || pex.ContainsSection("EXES", exact: true);
|
||||
if (exesSection)
|
||||
if (pex.ContainsSection("ExeS", exact: true))
|
||||
return "EXE Stealth 2.41-2.75";
|
||||
if (pex.ContainsSection("EXES", exact: true))
|
||||
return "EXE Stealth 2.41-2.75";
|
||||
|
||||
// Get the mtw section, if it exists
|
||||
bool mtwSection = pex.ContainsSection("mtw", exact: true);
|
||||
if (mtwSection)
|
||||
if (pex.ContainsSection("mtw", exact: true))
|
||||
return "EXE Stealth 1.1";
|
||||
|
||||
// Get the rsrr section, if it exists
|
||||
bool rsrrSection = pex.ContainsSection("rsrr", exact: true);
|
||||
if (rsrrSection)
|
||||
if (pex.ContainsSection("rsrr", exact: true))
|
||||
return "EXE Stealth 2.76";
|
||||
|
||||
return null;
|
||||
|
||||
139
BinaryObjectScanner/Packer/EmbeddedArchive.cs
Normal file
139
BinaryObjectScanner/Packer/EmbeddedArchive.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
/// <summary>
|
||||
/// Though not technically a packer, this detection is for any executables that include
|
||||
/// archives in their resources in some uncompressed manner to be used at runtime.
|
||||
/// </summary>
|
||||
public class EmbeddedArchive : IExtractableExecutable<PortableExecutable>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex.Model.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the resources that have a PKZIP signature
|
||||
if (pex.ResourceData != null)
|
||||
{
|
||||
foreach (var value in pex.ResourceData.Values)
|
||||
{
|
||||
if (value == null || value is not byte[] ba)
|
||||
continue;
|
||||
if (!ba.StartsWith(SabreTools.Models.PKZIP.Constants.LocalFileHeaderSignatureBytes))
|
||||
continue;
|
||||
|
||||
return "Embedded Archive";
|
||||
}
|
||||
}
|
||||
|
||||
// Check the overlay, if it exists
|
||||
if (pex.OverlayData != null && pex.OverlayData.Length > 0)
|
||||
{
|
||||
if (pex.OverlayData.StartsWith(SabreTools.Models.PKZIP.Constants.LocalFileHeaderSignatureBytes))
|
||||
return "Embedded Archive";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string file, PortableExecutable pex, string outDir, bool includeDebug)
|
||||
{
|
||||
bool overlay = ExtractFromOverlay(pex, outDir, includeDebug);
|
||||
bool resources = ExtractFromResources(pex, outDir, includeDebug);
|
||||
return overlay || resources;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract archive data from the overlay
|
||||
/// </summary>
|
||||
private static bool ExtractFromOverlay(PortableExecutable pex, string outDir, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the overlay data for easier reading
|
||||
var overlayData = pex.OverlayData;
|
||||
if (overlayData == null)
|
||||
return false;
|
||||
|
||||
// Only process the overlay if it has an archive signature
|
||||
if (!overlayData.StartsWith(SabreTools.Models.PKZIP.Constants.LocalFileHeaderSignatureBytes))
|
||||
return false;
|
||||
|
||||
// Create the temp filename
|
||||
string tempFile = $"embedded_overlay.zip";
|
||||
tempFile = Path.Combine(outDir, tempFile);
|
||||
var directoryName = Path.GetDirectoryName(tempFile);
|
||||
if (directoryName != null && !Directory.Exists(directoryName))
|
||||
Directory.CreateDirectory(directoryName);
|
||||
|
||||
// Write the resource data to a temp file
|
||||
using var tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
|
||||
tempStream?.Write(overlayData, 0, overlayData.Length);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract archive data from the resources
|
||||
/// </summary>
|
||||
private static bool ExtractFromResources(PortableExecutable pex, string outDir, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If there are no resources
|
||||
if (pex.ResourceData == null)
|
||||
return false;
|
||||
|
||||
// Get the resources that have an archive signature
|
||||
int i = 0;
|
||||
foreach (var value in pex.ResourceData.Values)
|
||||
{
|
||||
if (value == null || value is not byte[] ba)
|
||||
continue;
|
||||
if (!ba.StartsWith(SabreTools.Models.PKZIP.Constants.LocalFileHeaderSignatureBytes))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
// Create the temp filename
|
||||
string tempFile = $"embedded_resource_{i++}.zip";
|
||||
tempFile = Path.Combine(outDir, tempFile);
|
||||
var directoryName = Path.GetDirectoryName(tempFile);
|
||||
if (directoryName != null && !Directory.Exists(directoryName))
|
||||
Directory.CreateDirectory(directoryName);
|
||||
|
||||
// Write the resource data to a temp file
|
||||
using var tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
|
||||
tempStream?.Write(ba, 0, ba.Length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -22,14 +21,77 @@ namespace BinaryObjectScanner.Packer
|
||||
return null;
|
||||
|
||||
// Get the resources that have an executable signature
|
||||
if (pex.ResourceData?.Any(kvp => kvp.Value is byte[] ba && ba.StartsWith(SabreTools.Models.MSDOS.Constants.SignatureBytes)) == true)
|
||||
return "Embedded Executable";
|
||||
if (pex.ResourceData != null)
|
||||
{
|
||||
foreach (var value in pex.ResourceData.Values)
|
||||
{
|
||||
if (value == null || value is not byte[] ba)
|
||||
continue;
|
||||
if (!ba.StartsWith(SabreTools.Models.MSDOS.Constants.SignatureBytes))
|
||||
continue;
|
||||
|
||||
return "Embedded Executable";
|
||||
}
|
||||
}
|
||||
|
||||
// Check the overlay, if it exists
|
||||
if (pex.OverlayData != null && pex.OverlayData.Length > 0)
|
||||
{
|
||||
if (pex.OverlayData.StartsWith(SabreTools.Models.MSDOS.Constants.SignatureBytes))
|
||||
return "Embedded Executable";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string file, PortableExecutable pex, string outDir, bool includeDebug)
|
||||
{
|
||||
bool overlay = ExtractFromOverlay(pex, outDir, includeDebug);
|
||||
bool resources = ExtractFromResources(pex, outDir, includeDebug);
|
||||
return overlay || resources;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract executable data from the overlay
|
||||
/// </summary>
|
||||
private static bool ExtractFromOverlay(PortableExecutable pex, string outDir, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the overlay data for easier reading
|
||||
var overlayData = pex.OverlayData;
|
||||
if (overlayData == null)
|
||||
return false;
|
||||
|
||||
// Only process the overlay if it has an executable signature
|
||||
if (!overlayData.StartsWith(SabreTools.Models.MSDOS.Constants.SignatureBytes))
|
||||
return false;
|
||||
|
||||
// Create the temp filename
|
||||
string tempFile = $"embedded_overlay.bin"; // exe/dll
|
||||
tempFile = Path.Combine(outDir, tempFile);
|
||||
var directoryName = Path.GetDirectoryName(tempFile);
|
||||
if (directoryName != null && !Directory.Exists(directoryName))
|
||||
Directory.CreateDirectory(directoryName);
|
||||
|
||||
// Write the resource data to a temp file
|
||||
using var tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
|
||||
tempStream?.Write(overlayData, 0, overlayData.Length);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract executable data from the resources
|
||||
/// </summary>
|
||||
private static bool ExtractFromResources(PortableExecutable pex, string outDir, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -38,23 +100,18 @@ namespace BinaryObjectScanner.Packer
|
||||
return false;
|
||||
|
||||
// Get the resources that have an executable signature
|
||||
var resources = pex.ResourceData
|
||||
.Where(kvp => kvp.Value != null && kvp.Value is byte[])
|
||||
.Select(kvp => kvp.Value as byte[])
|
||||
.Where(b => b != null && b.StartsWith(SabreTools.Models.MSDOS.Constants.SignatureBytes))
|
||||
.ToList();
|
||||
|
||||
for (int i = 0; i < resources.Count; i++)
|
||||
int i = 0;
|
||||
foreach (var value in pex.ResourceData.Values)
|
||||
{
|
||||
if (value == null || value is not byte[] ba)
|
||||
continue;
|
||||
if (!ba.StartsWith(SabreTools.Models.MSDOS.Constants.SignatureBytes))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
// Get the resource data
|
||||
var data = resources[i];
|
||||
if (data == null)
|
||||
continue;
|
||||
|
||||
// Create the temp filename
|
||||
string tempFile = $"embedded_resource_{i}.bin";
|
||||
string tempFile = $"embedded_resource_{i++}.bin"; // exe/dll
|
||||
tempFile = Path.Combine(outDir, tempFile);
|
||||
var directoryName = Path.GetDirectoryName(tempFile);
|
||||
if (directoryName != null && !Directory.Exists(directoryName))
|
||||
@@ -62,7 +119,7 @@ namespace BinaryObjectScanner.Packer
|
||||
|
||||
// Write the resource data to a temp file
|
||||
using var tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
|
||||
tempStream?.Write(data, 0, data.Length);
|
||||
tempStream?.Write(ba, 0, ba.Length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -20,10 +19,10 @@ namespace BinaryObjectScanner.Packer
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("Gentee installer")))
|
||||
if (strs.Exists(s => s.Contains("Gentee installer")))
|
||||
return "Gentee Installer";
|
||||
|
||||
if (strs.Any(s => s.Contains("ginstall.dll")))
|
||||
if (strs.Exists(s => s.Contains("ginstall.dll")))
|
||||
return "Gentee Installer";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -21,10 +21,10 @@ namespace BinaryObjectScanner.Packer
|
||||
|
||||
// This check may be overly limiting, as it excludes the sample provided to DiE (https://github.com/horsicq/Detect-It-Easy/issues/102).
|
||||
// TODO: Find further samples and invesitgate if the "peC" section is only present on specific versions.
|
||||
bool peCSection = pex.ContainsSection("peC", exact: true);
|
||||
bool importTableMatch = (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte?.Name == "KeRnEl32.dLl") ?? false);
|
||||
bool importTableMatch = Array.Exists(pex.Model.ImportTable?.ImportDirectoryTable ?? [],
|
||||
idte => idte?.Name == "KeRnEl32.dLl");
|
||||
|
||||
if (peCSection && importTableMatch)
|
||||
if (pex.ContainsSection("peC", exact: true) && importTableMatch)
|
||||
return "HyperTech CrackProof";
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Content;
|
||||
@@ -16,13 +15,17 @@ namespace BinaryObjectScanner.Packer
|
||||
public string? CheckExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
// Check for "Inno" in the reserved words
|
||||
if (nex.Model.Stub?.Header?.Reserved2?[4] == 0x6E49 && nex.Model.Stub?.Header?.Reserved2?[5] == 0x6F6E)
|
||||
var reserved2 = nex.Model.Stub?.Header?.Reserved2;
|
||||
if (reserved2 != null && reserved2.Length > 5)
|
||||
{
|
||||
string version = GetOldVersion(file, nex);
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
return $"Inno Setup {version}";
|
||||
|
||||
return "Inno Setup (Unknown Version)";
|
||||
if (reserved2[4] == 0x6E49 && reserved2[5] == 0x6F6E)
|
||||
{
|
||||
string version = GetOldVersion(file, nex);
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
return $"Inno Setup {version}";
|
||||
|
||||
return "Inno Setup (Unknown Version)";
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -40,7 +43,7 @@ namespace BinaryObjectScanner.Packer
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
var str = strs.FirstOrDefault(s => s.StartsWith("Inno Setup Setup Data"));
|
||||
var str = strs.Find(s => s.StartsWith("Inno Setup Setup Data"));
|
||||
if (str != null)
|
||||
{
|
||||
return str.Replace("Inno Setup Setup Data", "Inno Setup")
|
||||
@@ -79,8 +82,8 @@ namespace BinaryObjectScanner.Packer
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, data, matchers, false) ?? "Unknown 1.X";
|
||||
}
|
||||
|
||||
return "Unknown 1.X";
|
||||
|
||||
return "Unknown 1.X";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace BinaryObjectScanner.Packer
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
private static string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
// Check the internal versions
|
||||
var version = pex.GetInternalVersion();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -21,7 +20,7 @@ namespace BinaryObjectScanner.Packer
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("ViseMain")))
|
||||
if (strs.Exists(s => s.Contains("ViseMain")))
|
||||
return "Installer VISE";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -29,7 +28,7 @@ namespace BinaryObjectScanner.Packer
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("wextract_cleanup")))
|
||||
if (strs.Exists(s => s.Contains("wextract_cleanup")))
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
}
|
||||
|
||||
@@ -39,7 +38,7 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// This detects a different but similar type of SFX that uses Microsoft CAB files.
|
||||
// Further research is needed to see if it's just a different version or entirely separate.
|
||||
if (strs.Any(s => s.Contains("MSCFu")))
|
||||
if (strs.Exists(s => s.Contains("MSCFu")))
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
}
|
||||
|
||||
@@ -52,7 +51,7 @@ namespace BinaryObjectScanner.Packer
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
private static string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
// Check the internal versions
|
||||
var version = pex.GetInternalVersion();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -15,15 +14,15 @@ namespace BinaryObjectScanner.Packer
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
var description = pex.AssemblyDescription;
|
||||
if (!string.IsNullOrEmpty(description) && description!.StartsWith("Nullsoft Install System"))
|
||||
return $"NSIS {description.Substring("Nullsoft Install System".Length).Trim()}";
|
||||
var name = pex.AssemblyDescription;
|
||||
if (name?.StartsWith("Nullsoft Install System") == true)
|
||||
return $"NSIS {name.Substring("Nullsoft Install System".Length).Trim()}";
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("NullsoftInst")))
|
||||
if (strs.Exists(s => s.Contains("NullsoftInst")))
|
||||
return "NSIS";
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,7 @@ namespace BinaryObjectScanner.Packer
|
||||
|
||||
// Get the .neolit section, if it exists.
|
||||
// TODO: Check if this section is also present in NeoLite 1.X.
|
||||
bool neolitSection = pex.ContainsSection(".neolit", exact: true);
|
||||
if (neolitSection)
|
||||
if (pex.ContainsSection(".neolit", exact: true))
|
||||
return "NeoLite";
|
||||
|
||||
// If more specific or additional checks are needed, "NeoLite Executable File Compressor" should be present
|
||||
|
||||
@@ -23,13 +23,12 @@ namespace BinaryObjectScanner.Packer
|
||||
// on the data in the file. This may be related to information in other fields
|
||||
|
||||
// Get the pec1 section, if it exists
|
||||
bool pec1Section = pex.ContainsSection("pec1", exact: true);
|
||||
if (pec1Section)
|
||||
if (pex.ContainsSection("pec1", exact: true))
|
||||
return "PE Compact v1.x";
|
||||
|
||||
// Get the PEC2 section, if it exists -- TODO: Verify this comment since it's pulling the .text section
|
||||
var textSection = pex.GetFirstSection(".text", exact: true);
|
||||
if (textSection != null && textSection.PointerToRelocations == 0x32434550)
|
||||
if (textSection?.PointerToRelocations == 0x32434550)
|
||||
{
|
||||
if (textSection.PointerToLinenumbers != 0)
|
||||
return $"PE Compact v{textSection.PointerToLinenumbers} (internal version)";
|
||||
|
||||
@@ -16,8 +16,7 @@ namespace BinaryObjectScanner.Packer
|
||||
return null;
|
||||
|
||||
// Get the .petite section, if it exists -- TODO: Is there a version number that can be found?
|
||||
bool petiteSection = pex.ContainsSection(".petite", exact: true);
|
||||
if (petiteSection)
|
||||
if (pex.ContainsSection(".petite", exact: true))
|
||||
return "PEtite";
|
||||
|
||||
return null;
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace BinaryObjectScanner.Packer
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
private static string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
// Check the product version explicitly
|
||||
var version = pex.ProductVersion;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -37,7 +36,7 @@ namespace BinaryObjectScanner.Packer
|
||||
return "7-Zip SFX";
|
||||
|
||||
// If any dialog boxes match
|
||||
if (pex.FindDialogByTitle("7-Zip self-extracting archive").Any())
|
||||
if (pex.FindDialogByTitle("7-Zip self-extracting archive").Count > 0)
|
||||
return "7-Zip SFX";
|
||||
|
||||
return null;
|
||||
|
||||
@@ -16,9 +16,7 @@ namespace BinaryObjectScanner.Packer
|
||||
return null;
|
||||
|
||||
// Get the .shrink0 and .shrink2 sections, if they exist -- TODO: Confirm if both are needed or either/or is fine
|
||||
bool shrink0Section = pex.ContainsSection(".shrink0", true);
|
||||
bool shrink2Section = pex.ContainsSection(".shrink2", true);
|
||||
if (shrink0Section || shrink2Section)
|
||||
if (pex.ContainsSection(".shrink0", true) || pex.ContainsSection(".shrink2", true))
|
||||
return "Shrinker";
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
@@ -24,13 +23,13 @@ namespace BinaryObjectScanner.Packer
|
||||
return null;
|
||||
|
||||
// Check header padding strings
|
||||
if (pex.HeaderPaddingStrings?.Any() == true)
|
||||
if (pex.HeaderPaddingStrings != null && pex.HeaderPaddingStrings.Count > 0)
|
||||
{
|
||||
var match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.Contains("UPX!"));
|
||||
var match = pex.HeaderPaddingStrings.Find(s => s.Contains("UPX!"));
|
||||
//if (match != null)
|
||||
// return "UPX";
|
||||
|
||||
match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.StartsWith("$Id: UPX"));
|
||||
match = pex.HeaderPaddingStrings.Find(s => s.StartsWith("$Id: UPX"));
|
||||
if (match != null)
|
||||
{
|
||||
var regexMatch = _oldUpxVersionMatch.Match(match);
|
||||
@@ -40,8 +39,8 @@ namespace BinaryObjectScanner.Packer
|
||||
return "UPX (Unknown Version)";
|
||||
}
|
||||
|
||||
match = pex.HeaderPaddingStrings.FirstOrDefault(s => _upxVersionMatch.IsMatch(s));
|
||||
if (match != null && pex.HeaderPaddingStrings.Any(s => s == "UPX!"))
|
||||
match = pex.HeaderPaddingStrings.Find(s => _upxVersionMatch.IsMatch(s));
|
||||
if (match != null && pex.HeaderPaddingStrings.Exists(s => s == "UPX!"))
|
||||
{
|
||||
var regexMatch = _upxVersionMatch.Match(match);
|
||||
if (regexMatch.Success)
|
||||
@@ -49,7 +48,7 @@ namespace BinaryObjectScanner.Packer
|
||||
else
|
||||
return "UPX (Unknown Version)";
|
||||
}
|
||||
else if (match != null && pex.HeaderPaddingStrings.Any(s => s == "NOS "))
|
||||
else if (match != null && pex.HeaderPaddingStrings.Exists(s => s == "NOS "))
|
||||
{
|
||||
var regexMatch = _upxVersionMatch.Match(match);
|
||||
if (regexMatch.Success)
|
||||
@@ -74,10 +73,13 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// Check the normal version location first
|
||||
int index = positions[0] - 5;
|
||||
string versionString = Encoding.ASCII.GetString(fileContent, index, 4);
|
||||
if (char.IsNumber(versionString[0]))
|
||||
return versionString;
|
||||
|
||||
if (index >= 0 && index < fileContent.Length - 4)
|
||||
{
|
||||
string versionString = Encoding.ASCII.GetString(fileContent, index, 4);
|
||||
if (char.IsNumber(versionString[0]))
|
||||
return versionString;
|
||||
}
|
||||
|
||||
// Check for the old-style string
|
||||
//
|
||||
// Example:
|
||||
@@ -85,9 +87,12 @@ namespace BinaryObjectScanner.Packer
|
||||
// $Id: UPX 1.02 Copyright (C) 1996-2000 the UPX Team. All Rights Reserved. $
|
||||
// UPX!
|
||||
index = positions[0] - 67;
|
||||
versionString = Encoding.ASCII.GetString(fileContent, index, 4);
|
||||
if (char.IsNumber(versionString[0]))
|
||||
return versionString;
|
||||
if (index >= 0 && index < fileContent.Length - 4)
|
||||
{
|
||||
string versionString = Encoding.ASCII.GetString(fileContent, index, 4);
|
||||
if (char.IsNumber(versionString[0]))
|
||||
return versionString;
|
||||
}
|
||||
|
||||
return "(Unknown Version)";
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -18,8 +17,7 @@ namespace BinaryObjectScanner.Packer
|
||||
if (name?.Contains("WinRAR archiver") == true)
|
||||
return "WinRAR SFX";
|
||||
|
||||
var resources = pex.FindDialogByTitle("WinRAR self-extracting archive");
|
||||
if (resources.Any())
|
||||
if (pex.FindDialogByTitle("WinRAR self-extracting archive").Count > 0)
|
||||
return "WinRAR SFX";
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Text;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -14,13 +14,15 @@ namespace BinaryObjectScanner.Packer
|
||||
if (nex.Model.ResidentNameTable == null)
|
||||
return null;
|
||||
|
||||
// Get the resident and non-resident name table strings
|
||||
var rntStrs = Array.ConvertAll(nex.Model.ResidentNameTable,
|
||||
rnte => rnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(rnte.NameString));
|
||||
var nrntStrs = Array.ConvertAll(nex.Model.NonResidentNameTable ?? [],
|
||||
nrnte => nrnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(nrnte.NameString));
|
||||
|
||||
// Check for the WinZip name strings
|
||||
bool winZipNameFound = nex.Model.ResidentNameTable
|
||||
.Select(rnte => rnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(rnte.NameString))
|
||||
.Any(s => s.Contains("WZ-SE-01"));
|
||||
winZipNameFound |= nex.Model.NonResidentNameTable?
|
||||
.Select(nrnte => nrnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(nrnte.NameString))
|
||||
.Any(s => s.Contains("WinZip(R) Self-Extractor")) ?? false;
|
||||
bool winZipNameFound = Array.Exists(rntStrs, s => s.Contains("WZ-SE-01"));
|
||||
winZipNameFound |= Array.Exists(nrntStrs, s => s.Contains("WinZip(R) Self-Extractor"));
|
||||
|
||||
// If we didn't find it
|
||||
if (!winZipNameFound)
|
||||
@@ -646,8 +648,10 @@ namespace BinaryObjectScanner.Packer
|
||||
string assemblyVersion = pex.AssemblyVersion ?? "Unknown Version";
|
||||
|
||||
// Standard
|
||||
if (sfxFileName == "VW95SE.SFX" || sfxFileName == "ST32E.SFX"
|
||||
|| sfxFileName == "WZIPSE32.exe" || sfxFileName == "SI32LPG.SFX"
|
||||
if (sfxFileName == "VW95SE.SFX"
|
||||
|| sfxFileName == "ST32E.SFX"
|
||||
|| sfxFileName == "WZIPSE32.exe"
|
||||
|| sfxFileName == "SI32LPG.SFX"
|
||||
|| sfxFileName == "ST32E.WZE")
|
||||
{
|
||||
return sfxTimeDateStamp switch
|
||||
@@ -670,8 +674,10 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
// Personal Edition
|
||||
if (sfxFileName == "VW95LE.SFX" || sfxFileName == "PE32E.SFX"
|
||||
|| sfxFileName == "wzsepe32.exe" || sfxFileName == "SI32PE.SFX"
|
||||
if (sfxFileName == "VW95LE.SFX"
|
||||
|| sfxFileName == "PE32E.SFX"
|
||||
|| sfxFileName == "wzsepe32.exe"
|
||||
|| sfxFileName == "SI32PE.SFX"
|
||||
|| sfxFileName == "SI32LPE.SFX")
|
||||
{
|
||||
return sfxTimeDateStamp switch
|
||||
@@ -713,7 +719,8 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
// Software Installation
|
||||
else if (sfxFileName == "VW95SRE.SFX" || sfxFileName == "SI32E.SFX"
|
||||
else if (sfxFileName == "VW95SRE.SFX"
|
||||
|| sfxFileName == "SI32E.SFX"
|
||||
|| sfxFileName == "SI32E.WZE")
|
||||
{
|
||||
return sfxTimeDateStamp switch
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
@@ -59,7 +58,7 @@ namespace BinaryObjectScanner.Packer
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("WiseMain")))
|
||||
if (strs.Exists(s => s.Contains("WiseMain")))
|
||||
return "Wise Installation Wizard Module";
|
||||
}
|
||||
|
||||
@@ -67,7 +66,7 @@ namespace BinaryObjectScanner.Packer
|
||||
strs = pex.GetFirstSectionStrings(".rdata");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("WiseMain")))
|
||||
if (strs.Exists(s => s.Contains("WiseMain")))
|
||||
return "Wise Installation Wizard Module";
|
||||
}
|
||||
|
||||
@@ -189,7 +188,7 @@ namespace BinaryObjectScanner.Packer
|
||||
/// </summary>
|
||||
/// <param name="nex">New executable to check</param>
|
||||
/// <returns>True if it matches a known version, false otherwise</returns>
|
||||
private FormatProperty? MatchesNEVersion(NewExecutable nex)
|
||||
private static FormatProperty? MatchesNEVersion(NewExecutable nex)
|
||||
{
|
||||
// TODO: Offset is _not_ the EXE header address, rather where the data starts. Fix this.
|
||||
switch (nex.Model.Stub?.Header?.NewExeHeaderAddr)
|
||||
@@ -246,7 +245,7 @@ namespace BinaryObjectScanner.Packer
|
||||
/// </summary>
|
||||
/// <param name="pex">Portable executable to check</param>
|
||||
/// <returns>True if it matches a known version, false otherwise</returns>
|
||||
private FormatProperty? GetPEFormat(PortableExecutable pex)
|
||||
private static FormatProperty? GetPEFormat(PortableExecutable pex)
|
||||
{
|
||||
if (pex.OverlayAddress == 0x6e00
|
||||
&& pex.GetFirstSection(".text")?.VirtualSize == 0x3cf4
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
@@ -14,24 +13,23 @@ namespace BinaryObjectScanner.Protection
|
||||
/// <inheritdoc/>
|
||||
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// Only allow during debug
|
||||
if (!includeDebug)
|
||||
return null;
|
||||
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
// " " + (char)0xC2 + (char)0x16 + (char)0x00 + (char)0xA8 + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0xB8 + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0x86 + (char)0xC8 + (char)0x16 + (char)0x00 + (char)0x9A + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0x10 + (char)0xC2 + (char)0x16 + (char)0x00
|
||||
new(new byte?[]
|
||||
{
|
||||
// " " + (char)0xC2 + (char)0x16 + (char)0x00 + (char)0xA8 + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0xB8 + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0x86 + (char)0xC8 + (char)0x16 + (char)0x00 + (char)0x9A + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0x10 + (char)0xC2 + (char)0x16 + (char)0x00
|
||||
new(new byte?[]
|
||||
{
|
||||
0x20, 0xC2, 0x16, 0x00, 0xA8, 0xC1, 0x16, 0x00,
|
||||
0xB8, 0xC1, 0x16, 0x00, 0x86, 0xC8, 0x16, 0x00,
|
||||
0x9A, 0xC1, 0x16, 0x00, 0x10, 0xC2, 0x16, 0x00
|
||||
}, "ActiveMARK 5 (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
0x20, 0xC2, 0x16, 0x00, 0xA8, 0xC1, 0x16, 0x00,
|
||||
0xB8, 0xC1, 0x16, 0x00, 0x86, 0xC8, 0x16, 0x00,
|
||||
0x9A, 0xC1, 0x16, 0x00, 0x10, 0xC2, 0x16, 0x00
|
||||
}, "ActiveMARK 5 (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
return null;
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -52,28 +50,16 @@ namespace BinaryObjectScanner.Protection
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
else if (pex.EntryPointData.StartsWith(new byte?[] { 0x89, 0x25, null, null, null, null, 0xEB }))
|
||||
return "ActiveMark -> Trymedia Systems Inc. (Unconfirmed - Please report to us on Github)";
|
||||
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
else if (pex.EntryPointData.StartsWith(new byte?[] { 0x89, 0x25, null, null, null, null, 0x33, 0xED, 0x55, 0x8B, 0xEC, 0xE8, null, null, null, null, 0x8B, 0xD0, 0x81, 0xE2, 0xFF, 0x00, 0x00, 0x00, 0x89, 0x15, null, null, null, null, 0x8B, 0xD0, 0xC1, 0xEA, 0x08, 0x81, 0xE2, 0xFF, 0x00, 0x00, 0x00, 0xA3, null, null, null, null, 0xD1, 0xE0, 0x0F, 0x93, 0xC3, 0x33, 0xC0, 0x8A, 0xC3, 0xA3, null, null, null, null, 0x68, 0xFF, 0x00, 0x00, 0x00, 0xE8, null, null, null, null, 0x6A, 0x00, 0xE8, null, null, null, null, 0xA3, null, null, null, null, 0xBB, null, null, null, null, 0xC7, 0x03, 0x44, 0x00, 0x00, 0x00 }))
|
||||
return "ActiveMark -> Trymedia Systems Inc. (Unconfirmed - Please report to us on Github)";
|
||||
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
else if (pex.EntryPointData.StartsWith(new byte?[] { 0x20, 0x2D, 0x2D, 0x4D, 0x50, 0x52, 0x4D, 0x4D, 0x47, 0x56, 0x41, 0x2D, 0x2D, 0x00, 0x75, 0x73, 0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6F, 0x78, 0x41, 0x00, 0x54, 0x68, 0x69, 0x73, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6E, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67 }))
|
||||
return "ActiveMARK 5.x -> Trymedia Systems Inc. (h) (Unconfirmed - Please report to us on Github)";
|
||||
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
else if (pex.EntryPointData.StartsWith(new byte?[] { 0x20, 0x2D, 0x2D, 0x4D, 0x50, 0x52, 0x4D, 0x4D, 0x47, 0x56, 0x41, 0x2D, 0x2D, 0x00, 0x75, 0x73, 0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6F, 0x78, 0x41, 0x00, 0x54, 0x68, 0x69, 0x73, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6E, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x65, 0x72, 0x20, 0x69, 0x6E, 0x20, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x2E, 0x0D, 0x0A, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x75, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x65, 0x72, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2E, 0x00, 0x57, 0x61, 0x72, 0x6E, 0x69, 0x6E, 0x67 }))
|
||||
return "ActiveMARK 5.x -> Trymedia Systems,Inc. (Unconfirmed - Please report to us on Github)";
|
||||
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
else if (pex.EntryPointData.StartsWith(new byte?[] { 0x79, 0x11, 0x7F, 0xAB, 0x9A, 0x4A, 0x83, 0xB5, 0xC9, 0x6B, 0x1A, 0x48, 0xF9, 0x27, 0xB4, 0x25 }))
|
||||
return "ActiveMARK[TM] (Unconfirmed - Please report to us on Github)";
|
||||
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
else if (pex.EntryPointData.StartsWith(new byte?[] { 0x79, 0x07, 0x0F, 0xB7, 0x07, 0x47, 0x50, 0x47, 0xB9, 0x57, 0x48, 0xF2, 0xAE, 0x55, 0xFF, 0x96, 0x84, null, 0x00, 0x00, 0x09, 0xC0, 0x74, 0x07, 0x89, 0x03, 0x83, 0xC3, 0x04, 0xEB, 0xD8, 0xFF, 0x96, 0x88, null, 0x00, 0x00, 0x61, 0xE9, null, null, null, 0xFF }))
|
||||
return "ActiveMARK[TM] R5.31.1140 -> Trymedia (Unconfirmed - Please report to us on Github)";
|
||||
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
else if (pex.EntryPointData.StartsWith(new byte?[] { 0xBE, 0x48, 0x01, 0x40, 0x00, 0xAD, 0x8B, 0xF8, 0x95, 0xA5, 0x33, 0xC0, 0x33, 0xC9, 0xAB, 0x48, 0xAB, 0xF7, 0xD8, 0xB1, 0x04, 0xF3, 0xAB, 0xC1, 0xE0, 0x0A, 0xB5, 0x1C, 0xF3, 0xAB, 0xAD, 0x50, 0x97, 0x51, 0xAD, 0x87, 0xF5, 0x58, 0x8D, 0x54, 0x86, 0x5C, 0xFF, 0xD5, 0x72, 0x5A, 0x2C, 0x03, 0x73, 0x02, 0xB0, 0x00, 0x3C, 0x07, 0x72, 0x02, 0x2C, 0x03, 0x50, 0x0F, 0xB6, 0x5F, 0xFF, 0xC1, 0xE3, 0x03, 0xB3, 0x00, 0x8D, 0x1C, 0x5B, 0x8D, 0x9C, 0x9E, 0x0C, 0x10, 0x00, 0x00, 0xB0, 0x01, 0x67, 0xE3, 0x29, 0x8B, 0xD7, 0x2B, 0x56, 0x0C, 0x8A, 0x2A, 0x33, 0xD2, 0x84, 0xE9, 0x0F, 0x95, 0xC6, 0x52, 0xFE, 0xC6, 0x8A, 0xD0, 0x8D, 0x14, 0x93, 0xFF, 0xD5, 0x5A, 0x9F, 0x12, 0xC0, 0xD0, 0xE9, 0x74, 0x0E, 0x9E, 0x1A, 0xF2, 0x74, 0xE4, 0xB4, 0x00, 0x33, 0xC9, 0xB5, 0x01, 0xFF, 0x55, 0xCC, 0x33, 0xC9, 0xE9, 0xDF, 0x00, 0x00, 0x00, 0x8B, 0x5E, 0x0C, 0x83, 0xC2, 0x30, 0xFF, 0xD5, 0x73, 0x50, 0x83, 0xC2, 0x30, 0xFF, 0xD5, 0x72, 0x1B, 0x83, 0xC2, 0x30, 0xFF, 0xD5, 0x72, 0x2B, 0x3C, 0x07, 0xB0, 0x09, 0x72, 0x02, 0xB0, 0x0B, 0x50, 0x8B, 0xC7, 0x2B, 0x46, 0x0C, 0xB1, 0x80, 0x8A, 0x00, 0xEB, 0xCF, 0x83, 0xC2, 0x60, 0xFF, 0xD5, 0x87, 0x5E, 0x10, 0x73, 0x0D, 0x83, 0xC2, 0x30, 0xFF, 0xD5, 0x87, 0x5E, 0x14, 0x73, 0x03, 0x87, 0x5E, 0x18, 0x3C, 0x07, 0xB0, 0x08, 0x72, 0x02, 0xB0, 0x0B, 0x50, 0x53, 0x8D, 0x96, 0x7C, 0x07, 0x00, 0x00, 0xFF, 0x55, 0xD0, 0x5B, 0x91, 0xEB, 0x77, 0x3C, 0x07, 0xB0, 0x07, 0x72, 0x02, 0xB0, 0x0A, 0x50, 0x87, 0x5E, 0x10, 0x87, 0x5E, 0x14, 0x89, 0x5E, 0x18, 0x8D, 0x96, 0xC4, 0x0B, 0x00, 0x00, 0xFF, 0x55, 0xD0, 0x50, 0x48 }))
|
||||
return "ActiveMARK 5.x -> Trymedia Systems,Inc. (h) (Unconfirmed - Please report to us on Github)";
|
||||
}
|
||||
@@ -82,8 +68,8 @@ namespace BinaryObjectScanner.Protection
|
||||
var strs = pex.GetLastSectionStrings(".data");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("MPRMMGVA"))
|
||||
&& strs.Any(s => s.Contains("This application cannot run with an active debugger in memory.")))
|
||||
if (strs.Exists(s => s.Contains("MPRMMGVA"))
|
||||
&& strs.Exists(s => s.Contains("This application cannot run with an active debugger in memory.")))
|
||||
{
|
||||
return "ActiveMARK 6.x";
|
||||
}
|
||||
@@ -91,11 +77,11 @@ namespace BinaryObjectScanner.Protection
|
||||
|
||||
// Get "REGISTRY, AMINTERNETPROTOCOL" resource items
|
||||
var resources = pex.FindResourceByNamedType("REGISTRY, AMINTERNETPROTOCOL");
|
||||
if (resources.Any())
|
||||
if (resources.Count > 0)
|
||||
{
|
||||
bool match = resources
|
||||
.Select(r => r == null ? string.Empty : Encoding.ASCII.GetString(r))
|
||||
.Any(r => r.Contains("ActiveMARK"));
|
||||
.ConvertAll(r => r == null ? string.Empty : Encoding.ASCII.GetString(r))
|
||||
.FindIndex(r => r.Contains("ActiveMARK")) > -1;
|
||||
if (match)
|
||||
return "ActiveMARK";
|
||||
}
|
||||
@@ -103,7 +89,7 @@ namespace BinaryObjectScanner.Protection
|
||||
// Get the overlay data, if it exists
|
||||
if (pex.OverlayStrings != null)
|
||||
{
|
||||
if (pex.OverlayStrings.Any(s => s.Contains("TMSAMVOH")))
|
||||
if (pex.OverlayStrings.Exists(s => s.Contains("TMSAMVOH")))
|
||||
return "ActiveMARK";
|
||||
}
|
||||
|
||||
@@ -111,7 +97,7 @@ namespace BinaryObjectScanner.Protection
|
||||
strs = pex.GetLastSectionStrings(".bss");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("TMSAMVOF")))
|
||||
if (strs.Exists(s => s.Contains("TMSAMVOF")))
|
||||
return "ActiveMARK";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Content;
|
||||
@@ -41,7 +40,7 @@ namespace BinaryObjectScanner.Protection
|
||||
|
||||
// Get string table resources
|
||||
var resource = pex.FindStringTableByEntry("AegiSoft License Manager");
|
||||
if (resource.Any())
|
||||
if (resource.Count > 0)
|
||||
return "AegiSoft License Manager";
|
||||
|
||||
// Get the .data/DATA section, if it exists
|
||||
@@ -68,7 +67,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.Protection
|
||||
public class AlphaDVD : IPathCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
@@ -57,10 +56,10 @@ namespace BinaryObjectScanner.Protection
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("\\SETTEC")))
|
||||
if (strs.Exists(s => s.Contains("\\SETTEC")))
|
||||
return "Alpha-ROM";
|
||||
|
||||
if (strs.Any(s => s.Contains("SETTEC0000")))
|
||||
if (strs.Exists(s => s.Contains("SETTEC0000")))
|
||||
return "Alpha-ROM";
|
||||
}
|
||||
|
||||
@@ -68,13 +67,15 @@ namespace BinaryObjectScanner.Protection
|
||||
strs = pex.GetFirstSectionStrings(".rdata");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("This Game is Japan Only")))
|
||||
if (strs.Exists(s => s.Contains("This Game is Japan Only")))
|
||||
return "Alpha-ROM";
|
||||
|
||||
// Found in "Filechk.exe" in Redump entry 115358.
|
||||
if (strs.Any(s => s.Contains("AlphaCheck.exe")))
|
||||
if (strs.Exists(s => s.Contains("AlphaCheck.exe")))
|
||||
return "Alpha-ROM";
|
||||
|
||||
// Found in "Uninstall.exe" in Redump entry 115358.
|
||||
if (strs.Any(s => s.Contains("AlphaCheck.dat")))
|
||||
if (strs.Exists(s => s.Contains("AlphaCheck.dat")))
|
||||
return "Alpha-ROM";
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (pex.OverlayStrings != null)
|
||||
{
|
||||
// Found in Redump entry 84122.
|
||||
if (pex.OverlayStrings.Any(s => s.Contains("SETTEC0000")))
|
||||
if (pex.OverlayStrings.Exists(s => s.Contains("SETTEC0000")))
|
||||
return "Alpha-ROM";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -29,20 +29,19 @@ namespace BinaryObjectScanner.Protection
|
||||
return null;
|
||||
|
||||
// Get the .nicode section, if it exists
|
||||
bool nicodeSection = pex.ContainsSection(".nicode", exact: true);
|
||||
if (nicodeSection)
|
||||
if (pex.ContainsSection(".nicode", exact: true))
|
||||
return "Armadillo";
|
||||
|
||||
// Loop through all "extension" sections -- usually .data1 or .text1
|
||||
if (pex.SectionNames != null)
|
||||
{
|
||||
foreach (var sectionName in pex.SectionNames.Where(s => s != null && s.EndsWith("1")))
|
||||
foreach (var sectionName in Array.FindAll(pex.SectionNames ?? [], s => s != null && s.EndsWith("1")))
|
||||
{
|
||||
// Get the section strings, if they exist
|
||||
var strs = pex.GetFirstSectionStrings(sectionName);
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("ARMDEBUG")))
|
||||
if (strs.Exists(s => s.Contains("ARMDEBUG")))
|
||||
return "Armadillo";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace BinaryObjectScanner.Protection
|
||||
public class Bitpool : IPathCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -74,20 +73,17 @@ namespace BinaryObjectScanner.Protection
|
||||
return "ByteShield Component Module";
|
||||
|
||||
// Found in "LineRider2.exe" in Redump entry 6236
|
||||
var stMatch = pex.FindStringTableByEntry("ByteShield");
|
||||
if (stMatch.Any())
|
||||
if (pex.FindStringTableByEntry("ByteShield").Count > 0)
|
||||
return $"ByteShield Activation Client {pex.GetInternalVersion()}";
|
||||
|
||||
// Found in "LineRider2.exe" in Redump entry 6236
|
||||
var dbMatch = pex.FindDialogByTitle("About ByteShield");
|
||||
if (dbMatch.Any())
|
||||
if (pex.FindDialogByTitle("About ByteShield").Count > 0)
|
||||
return "ByteShield";
|
||||
|
||||
// TODO: See if the version number is anywhere else
|
||||
// TODO: Parse the version number out of the dialog box item
|
||||
// Found in "LineRider2.exe" in Redump entry 6236
|
||||
dbMatch = pex.FindDialogBoxByItemTitle("ByteShield Version 1.0");
|
||||
if (dbMatch.Any())
|
||||
if (pex.FindDialogBoxByItemTitle("ByteShield Version 1.0").Count > 0)
|
||||
return "ByteShield";
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
@@ -95,7 +91,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "LineRider2.exe" in Redump entry 6236
|
||||
if (strs.Any(s => s?.Contains("ByteShield") == true))
|
||||
if (strs.Exists(s => s?.Contains("ByteShield") == true))
|
||||
return "ByteShield";
|
||||
}
|
||||
|
||||
@@ -104,15 +100,15 @@ namespace BinaryObjectScanner.Protection
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "ByteShield.dll" in Redump entry 6236
|
||||
if (strs.Any(s => s?.Contains("Byte|Shield") == true))
|
||||
if (strs.Exists(s => s?.Contains("Byte|Shield") == true))
|
||||
return "ByteShield Component Module";
|
||||
|
||||
// Found in "ByteShield.dll" in Redump entry 6236
|
||||
else if (strs.Any(s => s?.Contains("Byteshield0") == true))
|
||||
else if (strs.Exists(s => s?.Contains("Byteshield0") == true))
|
||||
return "ByteShield Component Module";
|
||||
|
||||
// Found in "ByteShield.dll" in Redump entry 6236
|
||||
else if (strs.Any(s => s?.Contains("ByteShieldLoader") == true))
|
||||
else if (strs.Exists(s => s?.Contains("ByteShieldLoader") == true))
|
||||
return "ByteShield Component Module";
|
||||
}
|
||||
|
||||
@@ -122,7 +118,7 @@ namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
// TODO: Figure out if this specifically indicates if the file is encrypted
|
||||
// Found in "LineRider2.bbz" in Redump entry 6236
|
||||
if (strs.Any(s => s?.Contains("ByteShield") == true))
|
||||
if (strs.Exists(s => s?.Contains("ByteShield") == true))
|
||||
return "ByteShield";
|
||||
}
|
||||
|
||||
@@ -130,7 +126,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
// TODO: Investigate reference to "bbz650.tmp" in "Byteshield.dll" (Redump entry 6236)
|
||||
// Files with the ".bbz" extension are associated with ByteShield, but the extenstion is known to be used in other places as well.
|
||||
|
||||
@@ -69,31 +69,30 @@ namespace BinaryObjectScanner.Protection
|
||||
/// <inheritdoc/>
|
||||
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// Only allow during debug
|
||||
if (!includeDebug)
|
||||
return null;
|
||||
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
// TODO: Remove from here once it's confirmed that no PE executables contain this string
|
||||
// CD-Cops, ver.
|
||||
new(new byte?[]
|
||||
{
|
||||
// TODO: Remove from here once it's confirmed that no PE executables contain this string
|
||||
// CD-Cops, ver.
|
||||
new(new byte?[]
|
||||
{
|
||||
0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C,
|
||||
0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20
|
||||
}, GetVersion, "CD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C,
|
||||
0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20
|
||||
}, GetVersion, "CD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
|
||||
// // DVD-Cops, ver.
|
||||
new(new byte?[]
|
||||
{
|
||||
0x44, 0x56, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73,
|
||||
0x2C, 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20
|
||||
}, GetVersion, "DVD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
// // DVD-Cops, ver.
|
||||
new(new byte?[]
|
||||
{
|
||||
0x44, 0x56, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73,
|
||||
0x2C, 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20
|
||||
}, GetVersion, "DVD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
return null;
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -120,21 +119,21 @@ namespace BinaryObjectScanner.Protection
|
||||
if (!string.IsNullOrEmpty(match))
|
||||
return match;
|
||||
|
||||
// Get the resident and non-resident name table strings
|
||||
var nrntStrs = Array.ConvertAll(nex.Model.NonResidentNameTable ?? [],
|
||||
nrnte => nrnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(nrnte.NameString));
|
||||
|
||||
// Check the imported-name table
|
||||
// Found in "h3blade.exe" in Redump entry 85077.
|
||||
bool importedNameTableEntries = nex.Model.ImportedNameTable?
|
||||
.Select(kvp => kvp.Value)
|
||||
bool intMatch = nex.Model.ImportedNameTable?.Values?
|
||||
.Select(inte => inte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(inte.NameString))
|
||||
.Any(s => s.Contains("CDCOPS")) ?? false;
|
||||
if (importedNameTableEntries)
|
||||
if (intMatch)
|
||||
return "CD-Cops";
|
||||
|
||||
// Check the nonresident-name table
|
||||
// Found in "CDCOPS.DLL" in Redump entry 85077.
|
||||
bool nonresidentNameTableEntries = nex.Model.NonResidentNameTable?
|
||||
.Select(nrnte => nrnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(nrnte.NameString))
|
||||
.Any(s => s.Contains("CDcops assembly-language DLL")) ?? false;
|
||||
if (nonresidentNameTableEntries)
|
||||
if (Array.Exists(nrntStrs, s => s.Contains("CDcops assembly-language DLL")))
|
||||
return "CD-Cops";
|
||||
|
||||
return null;
|
||||
@@ -152,14 +151,14 @@ namespace BinaryObjectScanner.Protection
|
||||
if (pex.StubExecutableData != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// WEBCOPS
|
||||
// Found in "HyperBowl.C_S" in https://web.archive.org/web/20120616074941/http://icm.games.tucows.com/files2/HyperDemo-109a.exe.
|
||||
new(new byte?[]
|
||||
{
|
||||
0x57, 0x45, 0x42, 0x43, 0x4F, 0x50, 0x53
|
||||
}, "WEB-Cops")
|
||||
};
|
||||
// WEBCOPS
|
||||
// Found in "HyperBowl.C_S" in https://web.archive.org/web/20120616074941/http://icm.games.tucows.com/files2/HyperDemo-109a.exe.
|
||||
new(new byte?[]
|
||||
{
|
||||
0x57, 0x45, 0x42, 0x43, 0x4F, 0x50, 0x53
|
||||
}, "WEB-Cops")
|
||||
};
|
||||
|
||||
var match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug);
|
||||
if (!string.IsNullOrEmpty(match))
|
||||
@@ -168,21 +167,19 @@ namespace BinaryObjectScanner.Protection
|
||||
|
||||
// Get the .grand section, if it exists
|
||||
// Found in "AGENTHUG.QZ_" in Redump entry 84517 and "h3blade.QZ_" in Redump entry 85077.
|
||||
bool grandSection = pex.ContainsSection(".grand", exact: true);
|
||||
if (grandSection)
|
||||
if (pex.ContainsSection(".grand", exact: true))
|
||||
return "CD/DVD/WEB-Cops";
|
||||
|
||||
// Get the UNICops section, if it exists
|
||||
// Found in "FGP.exe" in IA item "flaklypa-grand-prix-dvd"/Redump entry 108169.
|
||||
bool UNICopsSection = pex.ContainsSection("UNICops", exact: true);
|
||||
if (UNICopsSection)
|
||||
if (pex.ContainsSection("UNICops", exact: true))
|
||||
return "UNI-Cops";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
// TODO: Original had "CDCOPS.DLL" required and all the rest in a combined OR
|
||||
var matchers = new List<PathMatchSet>
|
||||
@@ -228,17 +225,11 @@ namespace BinaryObjectScanner.Protection
|
||||
if (fileContent == null)
|
||||
return null;
|
||||
|
||||
#if NET20 || NET35 || NET40
|
||||
byte[] versionBytes = new byte[4];
|
||||
Array.Copy(fileContent, positions[0] + 15, versionBytes, 0, 4);
|
||||
char[] version = versionBytes.Select(b => (char)b).ToArray();
|
||||
#else
|
||||
char[] version = new ArraySegment<byte>(fileContent, positions[0] + 15, 4).Select(b => (char)b).ToArray();
|
||||
#endif
|
||||
string version = Encoding.ASCII.GetString(fileContent, positions[0] + 15, 4);
|
||||
if (version[0] == 0x00)
|
||||
return string.Empty;
|
||||
|
||||
return new string(version);
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -46,7 +45,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (pex.Model.ImportTable?.ImportDirectoryTable != null)
|
||||
{
|
||||
// Found in "Randevu.exe" in Redump entry 97142.
|
||||
bool match = pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte?.Name != null && idte.Name.Equals("cdguard.dll", StringComparison.OrdinalIgnoreCase));
|
||||
bool match = Array.Exists(pex.Model.ImportTable.ImportDirectoryTable, idte => idte?.Name != null && idte.Name.Equals("cdguard.dll", StringComparison.OrdinalIgnoreCase));
|
||||
if (match)
|
||||
return "CD-Guard Copy Protection System";
|
||||
}
|
||||
@@ -55,7 +54,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace BinaryObjectScanner.Protection
|
||||
public class CDProtector : IPathCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
@@ -27,7 +26,7 @@ namespace BinaryObjectScanner.Protection
|
||||
var strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("~0017.tmp")))
|
||||
if (strs.Exists(s => s.Contains("~0017.tmp")))
|
||||
return "CDSHiELD SE";
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace BinaryObjectScanner.Protection
|
||||
public class CDX : IPathCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
// TODO: Verify if these are OR or AND
|
||||
var matchers = new List<PathMatchSet>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Content;
|
||||
@@ -11,24 +10,22 @@ namespace BinaryObjectScanner.Protection
|
||||
/// <inheritdoc/>
|
||||
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// Only allow during debug
|
||||
if (!includeDebug)
|
||||
return null;
|
||||
|
||||
// TODO: Limit these checks to Mac binaries
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
// CDSPlayer
|
||||
new(new byte?[] { 0x43, 0x44, 0x53, 0x50, 0x6C, 0x61, 0x79, 0x65, 0x72 }, "Cactus Data Shield 200"),
|
||||
// CDSPlayer
|
||||
new([0x43, 0x44, 0x53, 0x50, 0x6C, 0x61, 0x79, 0x65, 0x72], "Cactus Data Shield 200"),
|
||||
|
||||
// yucca.cds
|
||||
new(new byte?[] { 0x79, 0x75, 0x63, 0x63, 0x61, 0x2E, 0x63, 0x64, 0x73 }, "Cactus Data Shield 200"),
|
||||
};
|
||||
// yucca.cds
|
||||
new([0x79, 0x75, 0x63, 0x63, 0x61, 0x2E, 0x63, 0x64, 0x73], "Cactus Data Shield 200"),
|
||||
};
|
||||
|
||||
if (contentMatchSets != null && contentMatchSets.Any())
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
return null;
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,28 +32,22 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
// Get the .cenega section, if it exists. Seems to be found in the protected game executable ("game.exe" in Redump entry 31422 and "Classic Car Racing.exe" in IA item "speed-pack").
|
||||
bool cenegaSection = pex.ContainsSection(".cenega", exact: true);
|
||||
if (cenegaSection)
|
||||
if (pex.ContainsSection(".cenega", exact: true))
|
||||
return "Cenega ProtectDVD";
|
||||
|
||||
// Get the .cenega0 through .cenega2 sections, if they exists. Found in "cenega.dll" in Redump entry 31422 and IA item "speed-pack".
|
||||
cenegaSection = pex.ContainsSection(".cenega0", exact: true);
|
||||
if (cenegaSection)
|
||||
if (pex.ContainsSection(".cenega0", exact: true))
|
||||
return "Cenega ProtectDVD";
|
||||
|
||||
cenegaSection = pex.ContainsSection(".cenega1", exact: true);
|
||||
if (cenegaSection)
|
||||
if (pex.ContainsSection(".cenega1", exact: true))
|
||||
return "Cenega ProtectDVD";
|
||||
|
||||
cenegaSection = pex.ContainsSection(".cenega2", exact: true);
|
||||
if (cenegaSection)
|
||||
if (pex.ContainsSection(".cenega2", exact: true))
|
||||
return "Cenega ProtectDVD";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -40,13 +39,13 @@ namespace BinaryObjectScanner.Protection
|
||||
var strs = pex.GetFirstSectionStrings(".text");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("CODE-LOCK.OCX")))
|
||||
if (strs.Exists(s => s.Contains("CODE-LOCK.OCX")))
|
||||
return "ChosenBytes Code-Lock";
|
||||
|
||||
if (strs.Any(s => s.Contains("Code-Lock.ocx")))
|
||||
if (strs.Exists(s => s.Contains("Code-Lock.ocx")))
|
||||
return "ChosenBytes Code-Lock";
|
||||
|
||||
if (strs.Any(s => s.Contains("CodeLock.Secure")))
|
||||
if (strs.Exists(s => s.Contains("CodeLock.Secure")))
|
||||
return "ChosenBytes Code-Lock";
|
||||
}
|
||||
|
||||
@@ -54,7 +53,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
// Previous versions of BOS noted to look at ".PFF" files as possible indicators of CopyKiller, but those files seem unrelated.
|
||||
// TODO: Figure out why this doesn't work.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace BinaryObjectScanner.Protection
|
||||
// If there are more than 2 icd-prefixed sections, then we have a match
|
||||
// Though this is the same name that SafeDisc uses for protected executables, this seems to be a coincidence.
|
||||
// Found in Redump entries 31557, 31674, 31675, 31708, 38239, 44210, and 53929.
|
||||
int icdSectionCount = pex.SectionNames?.Count(s => s.StartsWith("icd")) ?? 0;
|
||||
int icdSectionCount = Array.FindAll(pex.SectionNames ?? [], s => s.StartsWith("icd")).Length;
|
||||
if (icdSectionCount >= 2)
|
||||
return "CopyLok / CodeLok";
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
@@ -77,7 +76,7 @@ namespace BinaryObjectScanner.Protection
|
||||
// TODO: This might need to check every single section. Unsure until more samples are acquired.
|
||||
// TODO: TKKG also has an NE 3.1x executable with a reference. This can be added later.
|
||||
// Samples: Redump ID 108150
|
||||
if (pex.OverlayStrings.Any(s => s.Contains("optgraph.dll")))
|
||||
if (pex.OverlayStrings.Exists(s => s.Contains("optgraph.dll")))
|
||||
return "copy-X [Check disc for physical ring]";
|
||||
}
|
||||
|
||||
@@ -85,7 +84,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (strs != null)
|
||||
{
|
||||
// Samples: Redump ID 82475, German Emergency 2 Deluxe, Redump ID 48393
|
||||
if (strs.Any(s => s.Contains("optgraph.dll")))
|
||||
if (strs.Exists(s => s.Contains("optgraph.dll")))
|
||||
return "copy-X [Check disc for physical ring]";
|
||||
}
|
||||
|
||||
@@ -93,7 +92,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var protections = new List<string>();
|
||||
if (files == null)
|
||||
@@ -111,17 +110,17 @@ namespace BinaryObjectScanner.Protection
|
||||
List<string>? lightFiles = null;
|
||||
|
||||
// TODO: Compensate for the check being run a directory or more higher
|
||||
var fileList = files.Where(f => !f.EndsWith(".x64", StringComparison.OrdinalIgnoreCase));
|
||||
var fileList = files.FindAll(f => !f.EndsWith(".x64", StringComparison.OrdinalIgnoreCase));
|
||||
foreach (var dir in dirs)
|
||||
{
|
||||
lightFiles = fileList.Where(f =>
|
||||
lightFiles = fileList.FindAll(f =>
|
||||
{
|
||||
f = f.Remove(0, path.Length);
|
||||
f = f.TrimStart('/', '\\');
|
||||
return f.StartsWith(dir + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase);
|
||||
})
|
||||
.OrderBy(f => f)
|
||||
.ToList();
|
||||
});
|
||||
lightFiles.Sort();
|
||||
|
||||
if (lightFiles.Count > 0)
|
||||
break;
|
||||
}
|
||||
@@ -133,12 +132,12 @@ namespace BinaryObjectScanner.Protection
|
||||
using var stream = File.OpenRead(lightFiles[0]);
|
||||
byte[] block = stream.ReadBytes(1024);
|
||||
|
||||
// Samples: Redump ID 81628
|
||||
if (Array.TrueForAll(block, b => b == 0))
|
||||
protections.Add("copy-X");
|
||||
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Checks if the file contains 0x00
|
||||
// Samples: Redump ID 81628
|
||||
new(Enumerable.Repeat<byte?>(0x00, 1024).ToArray(), "copy-X"),
|
||||
|
||||
// Checks for whatever this data is.
|
||||
// Samples: Redump ID 84759, Redump ID 107929. Professional discs also have this data, hence the exclusion check.
|
||||
new(
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -29,15 +28,15 @@ namespace BinaryObjectScanner.Protection
|
||||
// Full string:
|
||||
// *CrypKey Instant 2.0 security i(32 - bit) *
|
||||
// *Copyright(c) 1996 Kenonic Controls Ltd. *
|
||||
if (strs.Any(s => s.Contains("CrypKey Instant 2.0 security")))
|
||||
if (strs.Exists(s => s.Contains("CrypKey Instant 2.0 security")))
|
||||
return "CrypKey Instant 2.0";
|
||||
|
||||
// Generic check to catch unknown CrypKey Instant versions.
|
||||
if (strs.Any(s => s.Contains("CrypKey Instant")))
|
||||
if (strs.Exists(s => s.Contains("CrypKey Instant")))
|
||||
return "CrypKey Instant (Unknown version - Please report to us on GitHub)";
|
||||
|
||||
// Generic check to catch unknown CrypKey products.
|
||||
if (strs.Any(s => s.Contains("CrypKey")))
|
||||
if (strs.Exists(s => s.Contains("CrypKey")))
|
||||
return "CrypKey (Unknown version - Please report to us on GitHub)";
|
||||
}
|
||||
|
||||
@@ -74,7 +73,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -21,25 +21,22 @@ namespace BinaryObjectScanner.Protection
|
||||
return null;
|
||||
|
||||
// Get the .text section, if it exists
|
||||
if (pex.ContainsSection(".text"))
|
||||
var textData = pex.GetFirstSectionData(".text");
|
||||
if (textData != null)
|
||||
{
|
||||
var textData = pex.GetFirstSectionData(".text");
|
||||
if (textData != null)
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
// Confirmed to detect most examples known of Cucko. The only known exception is the version of "TSLHost.dll" included on Redump entry 36119.
|
||||
// ŠU‰8...…™...ŠUŠ8T...
|
||||
new(new byte?[]
|
||||
{
|
||||
// Confirmed to detect most examples known of Cucko. The only known exception is the version of "TSLHost.dll" included on Redump entry 36119.
|
||||
// ŠU‰8...…™...ŠUŠ8T...
|
||||
new(new byte?[]
|
||||
{
|
||||
0x8A, 0x55, 0x89, 0x38, 0x14, 0x1E, 0x0F, 0x85,
|
||||
0x99, 0x00, 0x00, 0x00, 0x8A, 0x55, 0x8A, 0x38,
|
||||
0x54, 0x1E, 0x01, 0x0F
|
||||
}, "Cucko (EA Custom)")
|
||||
};
|
||||
0x8A, 0x55, 0x89, 0x38, 0x14, 0x1E, 0x0F, 0x85,
|
||||
0x99, 0x00, 0x00, 0x00, 0x8A, 0x55, 0x8A, 0x38,
|
||||
0x54, 0x1E, 0x01, 0x0F
|
||||
}, "Cucko (EA Custom)")
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, textData, matchers, includeDebug);
|
||||
}
|
||||
return MatchUtil.GetFirstMatch(file, textData, matchers, includeDebug);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace BinaryObjectScanner.Protection
|
||||
public class DVDCrypt : IPathCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
@@ -9,7 +8,7 @@ namespace BinaryObjectScanner.Protection
|
||||
public class DVDMoviePROTECT : IPathCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var protections = new List<string>();
|
||||
if (files == null)
|
||||
@@ -17,8 +16,8 @@ namespace BinaryObjectScanner.Protection
|
||||
|
||||
if (Directory.Exists(Path.Combine(path, "VIDEO_TS")))
|
||||
{
|
||||
string[] bupfiles = files.Where(s => s.EndsWith(".bup")).ToArray();
|
||||
for (int i = 0; i < bupfiles.Length; i++)
|
||||
var bupfiles = files.FindAll(s => s.EndsWith(".bup"));
|
||||
for (int i = 0; i < bupfiles.Count; i++)
|
||||
{
|
||||
var bupfile = new FileInfo(bupfiles[i]);
|
||||
if (bupfile.DirectoryName == null)
|
||||
|
||||
@@ -5,6 +5,7 @@ using SabreTools.Matching;
|
||||
using SabreTools.Matching.Content;
|
||||
using SabreTools.Matching.Paths;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using OHMN = SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
@@ -65,205 +66,207 @@ namespace BinaryObjectScanner.Protection
|
||||
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/Denuvo%20protector.2.sg
|
||||
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/_denuvoComplete.2.sg
|
||||
|
||||
// TODO: Re-enable all Entry Point checks after implementing
|
||||
// Denuvo Protector
|
||||
// if (pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus && pex.EntryPointRaw != null)
|
||||
// {
|
||||
// byte?[] denuvoProtector = new byte?[]
|
||||
// {
|
||||
// 0x48, 0x8D, 0x0D, null, null, null, null, null,
|
||||
// null, null, null, 0xE9, null, null, null, null,
|
||||
// 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// };
|
||||
if (pex.Model.OptionalHeader?.Magic == OHMN.PE32Plus
|
||||
&& pex.EntryPointData != null)
|
||||
{
|
||||
byte?[] denuvoProtector =
|
||||
[
|
||||
0x48, 0x8D, 0x0D, null, null, null, null, null,
|
||||
null, null, null, 0xE9, null, null, null, null,
|
||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
// if (pex.EntryPointRaw.StartsWith(denuvoProtector))
|
||||
// return "Denuvo Protector";
|
||||
// }
|
||||
if (pex.EntryPointData.StartsWith(denuvoProtector))
|
||||
return "Denuvo Protector";
|
||||
}
|
||||
|
||||
// Denuvo
|
||||
var timingMatchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Denuvo Timing
|
||||
new(
|
||||
new byte?[]
|
||||
{
|
||||
[
|
||||
0x44, 0x65, 0x6E, 0x75, 0x76, 0x6F, 0x20, 0x54,
|
||||
0x69, 0x6D, 0x69, 0x6E, 0x67,
|
||||
}, "Denuvo")
|
||||
], "Denuvo")
|
||||
};
|
||||
var timingMatch = MatchUtil.GetFirstMatch(file, pex.EntryPointData, timingMatchers, includeDebug);
|
||||
|
||||
// TODO: Re-enable all Entry Point checks after implementing
|
||||
// if (pex.ContainsSection(".arch") || pex.ContainsSection(".srdata") || !string.IsNullOrEmpty(MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, timingMatchers, includeDebug)))
|
||||
// {
|
||||
// if (pex.OH_Magic == OptionalHeaderType.PE32Plus)
|
||||
// {
|
||||
// var matchers = new List<ContentMatchSet>
|
||||
// {
|
||||
// // Mad Max, Metal Gear Solid: TPP, Rise of the Tomb Raider
|
||||
// new ContentMatchSet(
|
||||
// new ContentMatch(
|
||||
// new byte?[]
|
||||
// {
|
||||
// 0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0x4C, 0x8D,
|
||||
// null, null, null, null, null, 0x4C, 0x8D, null,
|
||||
// null, null, null, null, 0x4D, 0x29, 0xC1,
|
||||
// },
|
||||
// end: 0
|
||||
// ),
|
||||
// "Denuvo v1.0 (x64)"),
|
||||
if (pex.ContainsSection(".arch")
|
||||
|| pex.ContainsSection(".srdata")
|
||||
|| !string.IsNullOrEmpty(timingMatch))
|
||||
{
|
||||
if (pex.Model.OptionalHeader?.Magic == OHMN.PE32Plus)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Mad Max, Metal Gear Solid: TPP, Rise of the Tomb Raider
|
||||
new(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0x4C, 0x8D,
|
||||
null, null, null, null, null, 0x4C, 0x8D, null,
|
||||
null, null, null, null, 0x4D, 0x29, 0xC1,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v1.0 (x64)"),
|
||||
|
||||
// // Lords of the Fallen, Batman: AK, Just Cause 3, Sherlock Holmes: TdD, Tales of Berseria etc
|
||||
// new ContentMatchSet(
|
||||
// new ContentMatch(
|
||||
// new byte?[]
|
||||
// {
|
||||
// 0x48, 0x8D, 0x0D, null, null, null, null, 0xE9,
|
||||
// null, null, null, null,
|
||||
// },
|
||||
// end: 0
|
||||
// ),
|
||||
// "Denuvo v2.0a (x64)"),
|
||||
// Lords of the Fallen, Batman: AK, Just Cause 3, Sherlock Holmes: TdD, Tales of Berseria etc
|
||||
new(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x48, 0x8D, 0x0D, null, null, null, null, 0xE9,
|
||||
null, null, null, null,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v2.0a (x64)"),
|
||||
|
||||
// // Yesterday Origins
|
||||
// new ContentMatchSet(
|
||||
// new ContentMatch(
|
||||
// new byte?[]
|
||||
// {
|
||||
// 0x48, 0x89, null, null, null, null, null, 0x48,
|
||||
// 0x89, null, null, null, null, null, 0x4C, 0x89,
|
||||
// null, null, null, null, null, 0x4C, 0x89, null,
|
||||
// null, null, null, null, 0x48, 0x83, 0xFA, 0x01,
|
||||
// },
|
||||
// end: 0
|
||||
// ),
|
||||
// "Denuvo v2.0b (x64)"),
|
||||
// Yesterday Origins
|
||||
new(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x48, 0x89, null, null, null, null, null, 0x48,
|
||||
0x89, null, null, null, null, null, 0x4C, 0x89,
|
||||
null, null, null, null, null, 0x4C, 0x89, null,
|
||||
null, null, null, null, 0x48, 0x83, 0xFA, 0x01,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v2.0b (x64)"),
|
||||
|
||||
// // Sniper Ghost Warrior 3 (beta), Dead Rising 4 (SteamStub-free)
|
||||
// new ContentMatchSet(
|
||||
// new ContentMatch(
|
||||
// new byte?[]
|
||||
// {
|
||||
// null, null, null, null, null, null, null, null,
|
||||
// 0x4C, 0x89, 0x1C, 0x24, 0x49, 0x89, 0xE3,
|
||||
// },
|
||||
// end: 0
|
||||
// ),
|
||||
// "Denuvo v3.0a (x64)"),
|
||||
// Sniper Ghost Warrior 3 (beta), Dead Rising 4 (SteamStub-free)
|
||||
new(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
null, null, null, null, null, null, null, null,
|
||||
0x4C, 0x89, 0x1C, 0x24, 0x49, 0x89, 0xE3,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v3.0a (x64)"),
|
||||
|
||||
// // Train Sim World CSX Heavy Haul
|
||||
// new ContentMatchSet(
|
||||
// new ContentMatch(
|
||||
// new byte?[]
|
||||
// {
|
||||
// 0x4D, 0x8D, null, null, null, null, null, null,
|
||||
// null, null, null, 0x48, 0x89, null, null, null,
|
||||
// null, null, 0x48, 0x8D, null, null, 0x48, 0x89,
|
||||
// null, 0x48, 0x89, null, 0x48, 0x89,
|
||||
// },
|
||||
// end: 0
|
||||
// ),
|
||||
// "Denuvo v3.0b (x64)"),
|
||||
// };
|
||||
// Train Sim World CSX Heavy Haul
|
||||
new(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x4D, 0x8D, null, null, null, null, null, null,
|
||||
null, null, null, 0x48, 0x89, null, null, null,
|
||||
null, null, 0x48, 0x8D, null, null, 0x48, 0x89,
|
||||
null, 0x48, 0x89, null, 0x48, 0x89,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v3.0b (x64)"),
|
||||
};
|
||||
|
||||
// var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
|
||||
// if (!string.IsNullOrEmpty(match))
|
||||
// return match;
|
||||
var match = MatchUtil.GetFirstMatch(file, pex.EntryPointData, matchers, includeDebug);
|
||||
if (!string.IsNullOrEmpty(match))
|
||||
return match;
|
||||
|
||||
// return "Denuvo (Unknown x64 Version)";
|
||||
return "Denuvo (Unknown x64 Version)";
|
||||
|
||||
// //// Check if steam_api64.dll present
|
||||
// //if (PE.isLibraryPresent("steam_api64.dll"))
|
||||
// //{
|
||||
// // // Override additional info
|
||||
// // sOptions = "x64 -> Steam";
|
||||
// // bDetected = 1;
|
||||
// //}
|
||||
// //// Check if uplay_r1_loader64.dll present
|
||||
// //if (PE.isLibraryPresent("uplay_r1_loader64.dll"))
|
||||
// //{
|
||||
// // // Override additional info
|
||||
// // sOptions = "x64 -> uPlay";
|
||||
// // bDetected = 1;
|
||||
// //}
|
||||
// //// Check if uplay_r2_loader64.dll present
|
||||
// //if (PE.isLibraryPresent("uplay_r2_loader64.dll"))
|
||||
// //{
|
||||
// // // Override additional info
|
||||
// // sOptions = "x64 -> uPlay";
|
||||
// // bDetected = 1;
|
||||
// //}
|
||||
// //// Check if Core/Activation64.dll present
|
||||
// //if (PE.isLibraryPresent("Core/Activation64.dll"))
|
||||
// //{
|
||||
// // // Override additional info
|
||||
// // sOptions = "x64 -> Origin";
|
||||
// // bDetected = 1;
|
||||
// //}
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var matchers = new List<ContentMatchSet>
|
||||
// {
|
||||
// // Pro Evolution Soccer 2017, Champions of Anteria
|
||||
// new ContentMatchSet(
|
||||
// new ContentMatch(
|
||||
// new byte?[]
|
||||
// {
|
||||
// 0x55, 0x89, 0xE5, 0x8D, null, null, null, null,
|
||||
// null, null, 0xE8, null, null, null, null, 0xE8,
|
||||
// null, null, null, null, 0xE8, null, null, null,
|
||||
// null, 0xE8, null, null, null, null,
|
||||
// },
|
||||
// end: 0
|
||||
// ),
|
||||
// "Denuvo v1.0 (x86)"),
|
||||
//// Check if steam_api64.dll present
|
||||
//if (PE.isLibraryPresent("steam_api64.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x64 -> Steam";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
//// Check if uplay_r1_loader64.dll present
|
||||
//if (PE.isLibraryPresent("uplay_r1_loader64.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x64 -> uPlay";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
//// Check if uplay_r2_loader64.dll present
|
||||
//if (PE.isLibraryPresent("uplay_r2_loader64.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x64 -> uPlay";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
//// Check if Core/Activation64.dll present
|
||||
//if (PE.isLibraryPresent("Core/Activation64.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x64 -> Origin";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Pro Evolution Soccer 2017, Champions of Anteria
|
||||
new(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x55, 0x89, 0xE5, 0x8D, null, null, null, null,
|
||||
null, null, 0xE8, null, null, null, null, 0xE8,
|
||||
null, null, null, null, 0xE8, null, null, null,
|
||||
null, 0xE8, null, null, null, null,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v1.0 (x86)"),
|
||||
|
||||
// // Romance of 13 Kingdoms, 2Dark
|
||||
// new ContentMatchSet(
|
||||
// new ContentMatch(
|
||||
// new byte?[]
|
||||
// {
|
||||
// 0x8D, null, null, null, null, null, null, 0x89,
|
||||
// 0x7C, 0x24, 0x04, 0x89, 0xE7,
|
||||
// },
|
||||
// end: 0
|
||||
// ),
|
||||
// "Denuvo v2.0 (x86)"),
|
||||
// };
|
||||
// Romance of 13 Kingdoms, 2Dark
|
||||
new(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x8D, null, null, null, null, null, null, 0x89,
|
||||
0x7C, 0x24, 0x04, 0x89, 0xE7,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v2.0 (x86)"),
|
||||
};
|
||||
|
||||
// var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
|
||||
// if (!string.IsNullOrEmpty(match))
|
||||
// return match;
|
||||
var match = MatchUtil.GetFirstMatch(file, pex.EntryPointData, matchers, includeDebug);
|
||||
if (!string.IsNullOrEmpty(match))
|
||||
return match;
|
||||
|
||||
// //// Check if steam_api64.dll present
|
||||
// //if (PE.isLibraryPresent("steam_api.dll"))
|
||||
// //{
|
||||
// // // Override additional info
|
||||
// // sOptions = "x86 -> Steam";
|
||||
// // bDetected = 1;
|
||||
// //}
|
||||
// //// Check if uplay_r1_loader.dll present
|
||||
// //if (PE.isLibraryPresent("uplay_r1_loader.dll"))
|
||||
// //{
|
||||
// // // Override additional info
|
||||
// // sOptions = "x86 -> uPlay";
|
||||
// // bDetected = 1;
|
||||
// //}
|
||||
// //// Check if Core/Activation.dll present
|
||||
// //if (PE.isLibraryPresent("Core/Activation.dll"))
|
||||
// //{
|
||||
// // // Override additional info
|
||||
// // sOptions = "x86 -> Origin";
|
||||
// // bDetected = 1;
|
||||
// //}
|
||||
// }
|
||||
// }
|
||||
//// Check if steam_api64.dll present
|
||||
//if (PE.isLibraryPresent("steam_api.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x86 -> Steam";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
//// Check if uplay_r1_loader.dll present
|
||||
//if (PE.isLibraryPresent("uplay_r1_loader.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x86 -> uPlay";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
//// Check if Core/Activation.dll present
|
||||
//if (PE.isLibraryPresent("Core/Activation.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x86 -> Origin";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace BinaryObjectScanner.Protection
|
||||
// https://www.gamecopyworld.com/games/pc_pc_calcio_2000.shtml
|
||||
// https://www.gamecopyworld.com/games/pc_pc_futbol_2000.shtml
|
||||
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Content;
|
||||
@@ -66,79 +65,79 @@ namespace BinaryObjectScanner.Protection
|
||||
return "DiscGuard";
|
||||
|
||||
// Found in "Alternate.exe" (Redump entry 31914) and "Alt.exe" (Redump entries 46743, 46961, 79284, and 79374).
|
||||
var resources = pex.FindStringTableByEntry("DiscGuard")
|
||||
.Concat(pex.FindStringTableByEntry("The file Dg.vbn was not found."))
|
||||
.Concat(pex.FindStringTableByEntry("The file IosLink.VxD was not found."))
|
||||
.Concat(pex.FindStringTableByEntry("The file IosLink.sys was not found."));
|
||||
if (resources.Any())
|
||||
List<Dictionary<int, string?>?> resources =
|
||||
[
|
||||
.. pex.FindStringTableByEntry("DiscGuard"),
|
||||
.. pex.FindStringTableByEntry("The file Dg.vbn was not found."),
|
||||
.. pex.FindStringTableByEntry("The file IosLink.VxD was not found."),
|
||||
.. pex.FindStringTableByEntry("The file IosLink.sys was not found."),
|
||||
];
|
||||
if (resources.Count > 0)
|
||||
return "DiscGuard";
|
||||
|
||||
// Get the .vbn section, if it exists
|
||||
if (pex.ContainsSection(".vbn"))
|
||||
var vbnData = pex.GetFirstSectionData(".vbn");
|
||||
if (vbnData != null)
|
||||
{
|
||||
var vbnData = pex.GetFirstSectionData(".vbn");
|
||||
if (vbnData != null)
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
// Found in "T29.dll" (Redump entry 31914).
|
||||
// This check should be as long as the following check, as this data is nearly identical (including length) in the original files, but for some reason the section ends early, causing part of the remaining data to not be part of a section.
|
||||
new(new byte?[]
|
||||
{
|
||||
// Found in "T29.dll" (Redump entry 31914).
|
||||
// This check should be as long as the following check, as this data is nearly identical (including length) in the original files, but for some reason the section ends early, causing part of the remaining data to not be part of a section.
|
||||
new(new byte?[]
|
||||
{
|
||||
0x7B, 0x39, 0x8F, 0x07, 0x47, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
|
||||
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
|
||||
0xBE, 0xB3, 0xDB, 0xE9, 0x4E, 0x87, 0x8D, 0x46, 0x63, 0x0A, 0x54, 0xB8,
|
||||
0x4F, 0x85, 0x60, 0x2C, 0x06, 0xEC, 0xBD, 0x75, 0xF5, 0x6A, 0x6E, 0x35,
|
||||
0x4D, 0x5A, 0x8B, 0xF4, 0x12, 0x15, 0x23, 0xC8, 0xE9, 0x80, 0x01, 0x10,
|
||||
0xFE, 0xDB, 0xC6, 0x70, 0x1D, 0xC1, 0x4D, 0xAE, 0x9E, 0xE1, 0x01, 0xAA,
|
||||
0x9E, 0x50, 0x50, 0xC5, 0x66, 0x80, 0xC0, 0xA2, 0x2F, 0xA9, 0x7A, 0x3B,
|
||||
0x48, 0x74, 0x9D, 0x17, 0x33, 0x5D, 0x4C, 0x84, 0xD9, 0x54, 0xC4, 0x08,
|
||||
0xCC, 0x10, 0x2A, 0xF6, 0x91, 0x40, 0x51, 0xD3, 0xF5, 0x9A, 0x07, 0xE7,
|
||||
0xAB, 0xE9, 0x0B, 0xAD, 0xD4, 0x3A, 0xEC, 0xBA, 0x4B, 0x6C, 0xD2, 0x82,
|
||||
0x0D, 0xF5, 0x49, 0x83, 0x8E, 0xAB, 0x85, 0x92, 0x78, 0x1D, 0x69, 0x1E,
|
||||
0x44, 0xC6, 0xF6, 0xB4, 0x5F, 0x5F, 0xC2, 0x48, 0x5A, 0xED, 0x43, 0xD3,
|
||||
0xA4, 0x41, 0x81
|
||||
}, GetVersion, "DiscGuard"),
|
||||
0x7B, 0x39, 0x8F, 0x07, 0x47, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
|
||||
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
|
||||
0xBE, 0xB3, 0xDB, 0xE9, 0x4E, 0x87, 0x8D, 0x46, 0x63, 0x0A, 0x54, 0xB8,
|
||||
0x4F, 0x85, 0x60, 0x2C, 0x06, 0xEC, 0xBD, 0x75, 0xF5, 0x6A, 0x6E, 0x35,
|
||||
0x4D, 0x5A, 0x8B, 0xF4, 0x12, 0x15, 0x23, 0xC8, 0xE9, 0x80, 0x01, 0x10,
|
||||
0xFE, 0xDB, 0xC6, 0x70, 0x1D, 0xC1, 0x4D, 0xAE, 0x9E, 0xE1, 0x01, 0xAA,
|
||||
0x9E, 0x50, 0x50, 0xC5, 0x66, 0x80, 0xC0, 0xA2, 0x2F, 0xA9, 0x7A, 0x3B,
|
||||
0x48, 0x74, 0x9D, 0x17, 0x33, 0x5D, 0x4C, 0x84, 0xD9, 0x54, 0xC4, 0x08,
|
||||
0xCC, 0x10, 0x2A, 0xF6, 0x91, 0x40, 0x51, 0xD3, 0xF5, 0x9A, 0x07, 0xE7,
|
||||
0xAB, 0xE9, 0x0B, 0xAD, 0xD4, 0x3A, 0xEC, 0xBA, 0x4B, 0x6C, 0xD2, 0x82,
|
||||
0x0D, 0xF5, 0x49, 0x83, 0x8E, 0xAB, 0x85, 0x92, 0x78, 0x1D, 0x69, 0x1E,
|
||||
0x44, 0xC6, 0xF6, 0xB4, 0x5F, 0x5F, 0xC2, 0x48, 0x5A, 0xED, 0x43, 0xD3,
|
||||
0xA4, 0x41, 0x81
|
||||
}, GetVersion, "DiscGuard"),
|
||||
|
||||
// Found in "T5375.dll" (Redump entry 79284), "TD352.dll" and "TE091.dll" (Redump entry 46743), "T71E1.dll" and "T7181.dll" (Redump entry 46961), and "TA0E4.DLL" (Redump entry 79374).
|
||||
new(new byte?[]
|
||||
{
|
||||
0x7B, 0x39, 0x8F, 0x07, 0x45, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
|
||||
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
|
||||
0xBE, 0xB3, 0xDB, 0xE9, 0x4E, 0x87, 0x8D, 0x46, 0x63, 0x0A, 0x54, 0xB8,
|
||||
0x4F, 0x85, 0x60, 0x2C, 0x06, 0xEC, 0xBD, 0x75, 0xC6, 0xEB, 0x6E, 0x35,
|
||||
0xED, 0xD0, 0x8B, 0xF4, 0x15, 0x12, 0x3D, 0xF3, 0x65, 0xF7, 0x01, 0x10,
|
||||
0xF8, 0xFA, 0xC6, 0x70, 0x1D, 0xC1, 0x4D, 0xAE, 0x9E, 0xE1, 0x01, 0xAA,
|
||||
0x9E, 0x50, 0x50, 0xC5, 0x66, 0x80, 0xC0, 0xA2, 0x2F, 0xA9, 0x7A, 0x3B,
|
||||
0x48, 0x74, 0x9D, 0x17, 0x33, 0x5D, 0x4C, 0x84, 0xD9, 0x54, 0xC4, 0x08,
|
||||
0xCC, 0x10, 0x2A, 0xF6, 0x91, 0x40, 0x51, 0xD3, 0x41, 0x9A, 0x07, 0xE7,
|
||||
0xAB, 0xE9, 0x0B, 0xAD, 0xD4, 0x3A, 0xEC, 0xBA, 0xAF, 0x69, 0xD2, 0x82,
|
||||
0x67, 0xF5, 0x49, 0x83, 0x8E, 0xAB, 0x85, 0x92, 0x04, 0x19, 0x69, 0x1E,
|
||||
0x44, 0xC6, 0xF6, 0xB4, 0x5F, 0x5F, 0xC2, 0x48, 0x5A, 0xED, 0x43, 0xD3,
|
||||
0xA4, 0x41, 0x81, 0xAF, 0xB8, 0xCB, 0x46, 0xE3, 0xDA, 0x05, 0x36, 0xEA,
|
||||
0x05, 0xF5, 0xB9, 0xCE, 0x5F, 0x9A, 0xF5, 0x7D, 0x9E, 0x64, 0x66, 0xF9,
|
||||
0xA5, 0x7C, 0x4D, 0x1D, 0x1D, 0x95, 0x02, 0x52, 0x66, 0x23, 0xEF, 0xFF,
|
||||
0xEC, 0x63, 0x11, 0xEB, 0xF6, 0x66, 0x8F, 0x2B, 0xCF, 0x07, 0x50, 0x18,
|
||||
0xBE, 0x58, 0xCA, 0x08, 0x24, 0xAD, 0x81, 0x1A, 0xAB, 0x0E, 0x2D, 0x16,
|
||||
0x38, 0xAB, 0x22, 0xB5, 0xA8, 0xF0, 0x7D, 0x2E, 0xAF, 0x5E, 0xEA, 0x02,
|
||||
0x72, 0x20, 0x14, 0x19, 0x0E, 0x31, 0xF3, 0xD0, 0x40, 0xAE, 0xA2, 0xD5,
|
||||
0x0A, 0xA7, 0xB7, 0xAE, 0x02, 0xCF, 0xAC, 0x5F, 0xB8, 0x03, 0x15, 0x80,
|
||||
0x9A, 0x58, 0x5C, 0x03, 0x28, 0x31, 0x9E, 0xB8, 0x21, 0x5D, 0x07, 0xB3,
|
||||
0xB9, 0xEC, 0x75, 0xBA, 0xC2, 0xC8, 0x9D, 0x6F, 0x7A, 0xA1, 0x00, 0x8A
|
||||
}, GetVersion, "DiscGuard"),
|
||||
};
|
||||
// Found in "T5375.dll" (Redump entry 79284), "TD352.dll" and "TE091.dll" (Redump entry 46743), "T71E1.dll" and "T7181.dll" (Redump entry 46961), and "TA0E4.DLL" (Redump entry 79374).
|
||||
new(new byte?[]
|
||||
{
|
||||
0x7B, 0x39, 0x8F, 0x07, 0x45, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
|
||||
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
|
||||
0xBE, 0xB3, 0xDB, 0xE9, 0x4E, 0x87, 0x8D, 0x46, 0x63, 0x0A, 0x54, 0xB8,
|
||||
0x4F, 0x85, 0x60, 0x2C, 0x06, 0xEC, 0xBD, 0x75, 0xC6, 0xEB, 0x6E, 0x35,
|
||||
0xED, 0xD0, 0x8B, 0xF4, 0x15, 0x12, 0x3D, 0xF3, 0x65, 0xF7, 0x01, 0x10,
|
||||
0xF8, 0xFA, 0xC6, 0x70, 0x1D, 0xC1, 0x4D, 0xAE, 0x9E, 0xE1, 0x01, 0xAA,
|
||||
0x9E, 0x50, 0x50, 0xC5, 0x66, 0x80, 0xC0, 0xA2, 0x2F, 0xA9, 0x7A, 0x3B,
|
||||
0x48, 0x74, 0x9D, 0x17, 0x33, 0x5D, 0x4C, 0x84, 0xD9, 0x54, 0xC4, 0x08,
|
||||
0xCC, 0x10, 0x2A, 0xF6, 0x91, 0x40, 0x51, 0xD3, 0x41, 0x9A, 0x07, 0xE7,
|
||||
0xAB, 0xE9, 0x0B, 0xAD, 0xD4, 0x3A, 0xEC, 0xBA, 0xAF, 0x69, 0xD2, 0x82,
|
||||
0x67, 0xF5, 0x49, 0x83, 0x8E, 0xAB, 0x85, 0x92, 0x04, 0x19, 0x69, 0x1E,
|
||||
0x44, 0xC6, 0xF6, 0xB4, 0x5F, 0x5F, 0xC2, 0x48, 0x5A, 0xED, 0x43, 0xD3,
|
||||
0xA4, 0x41, 0x81, 0xAF, 0xB8, 0xCB, 0x46, 0xE3, 0xDA, 0x05, 0x36, 0xEA,
|
||||
0x05, 0xF5, 0xB9, 0xCE, 0x5F, 0x9A, 0xF5, 0x7D, 0x9E, 0x64, 0x66, 0xF9,
|
||||
0xA5, 0x7C, 0x4D, 0x1D, 0x1D, 0x95, 0x02, 0x52, 0x66, 0x23, 0xEF, 0xFF,
|
||||
0xEC, 0x63, 0x11, 0xEB, 0xF6, 0x66, 0x8F, 0x2B, 0xCF, 0x07, 0x50, 0x18,
|
||||
0xBE, 0x58, 0xCA, 0x08, 0x24, 0xAD, 0x81, 0x1A, 0xAB, 0x0E, 0x2D, 0x16,
|
||||
0x38, 0xAB, 0x22, 0xB5, 0xA8, 0xF0, 0x7D, 0x2E, 0xAF, 0x5E, 0xEA, 0x02,
|
||||
0x72, 0x20, 0x14, 0x19, 0x0E, 0x31, 0xF3, 0xD0, 0x40, 0xAE, 0xA2, 0xD5,
|
||||
0x0A, 0xA7, 0xB7, 0xAE, 0x02, 0xCF, 0xAC, 0x5F, 0xB8, 0x03, 0x15, 0x80,
|
||||
0x9A, 0x58, 0x5C, 0x03, 0x28, 0x31, 0x9E, 0xB8, 0x21, 0x5D, 0x07, 0xB3,
|
||||
0xB9, 0xEC, 0x75, 0xBA, 0xC2, 0xC8, 0x9D, 0x6F, 0x7A, 0xA1, 0x00, 0x8A
|
||||
}, GetVersion, "DiscGuard"),
|
||||
};
|
||||
|
||||
var match = MatchUtil.GetFirstMatch(file, vbnData, matchers, includeDebug);
|
||||
if (!string.IsNullOrEmpty(match))
|
||||
return match;
|
||||
}
|
||||
var match = MatchUtil.GetFirstMatch(file, vbnData, matchers, includeDebug);
|
||||
if (!string.IsNullOrEmpty(match))
|
||||
return match;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
// TODO: Search for the presence of the folder "EasyAntiCheat" specifically, which is present in every checked version so far.
|
||||
var matchers = new List<PathMatchSet>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -27,16 +26,16 @@ namespace BinaryObjectScanner.Protection
|
||||
if (name?.Equals("CDCode", StringComparison.Ordinal) == true)
|
||||
return $"EA CdKey Registration Module {pex.GetInternalVersion()}";
|
||||
|
||||
if (pex.FindDialogByTitle("About CDKey").Any())
|
||||
if (pex.FindDialogByTitle("About CDKey").Count > 0)
|
||||
return $"EA CdKey Registration Module {pex.GetInternalVersion()}";
|
||||
else if (pex.FindGenericResource("About CDKey").Any())
|
||||
else if (pex.FindGenericResource("About CDKey").Count > 0)
|
||||
return $"EA CdKey Registration Module {pex.GetInternalVersion()}";
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("EReg Config Form")))
|
||||
if (strs.Exists(s => s.Contains("EReg Config Form")))
|
||||
return "EA CdKey Registration Module";
|
||||
}
|
||||
|
||||
@@ -44,7 +43,7 @@ namespace BinaryObjectScanner.Protection
|
||||
strs = pex.GetFirstSectionStrings(".rdata");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("GenericEA")) && strs.Any(s => s.Contains("Activation")))
|
||||
if (strs.Exists(s => s.Contains("GenericEA")) && strs.Exists(s => s.Contains("Activation")))
|
||||
return "EA DRM Protection";
|
||||
}
|
||||
|
||||
@@ -52,7 +51,7 @@ namespace BinaryObjectScanner.Protection
|
||||
strs = pex.GetFirstSectionStrings(".text");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("GenericEA")) && strs.Any(s => s.Contains("Activation")))
|
||||
if (strs.Exists(s => s.Contains("GenericEA")) && strs.Exists(s => s.Contains("Activation")))
|
||||
return "EA DRM Protection";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -28,11 +27,12 @@ namespace BinaryObjectScanner.Protection
|
||||
// Detects Engine32 within the game executables that contain it.
|
||||
if (pex.Model.ImportTable?.ImportDirectoryTable != null && pex.Model.ImportTable?.HintNameTable != null)
|
||||
{
|
||||
bool importDirectoryTableMatch = pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte?.Name != null && idte.Name.Equals("ENGINE32.DLL", StringComparison.OrdinalIgnoreCase));
|
||||
bool hintNameTableMatch = pex.Model.ImportTable?.HintNameTable.Any(ihne => ihne?.Name == "InitEngine") ?? false;
|
||||
bool importDirectoryTableMatch = Array.Exists(pex.Model.ImportTable.ImportDirectoryTable,
|
||||
idte => idte?.Name != null && idte.Name.Equals("ENGINE32.DLL", StringComparison.OrdinalIgnoreCase));
|
||||
bool hintNameTableMatch = Array.Exists(pex.Model.ImportTable.HintNameTable,
|
||||
ihne => ihne?.Name == "InitEngine");
|
||||
|
||||
// The Hint/Name Table Entry "DeinitEngine" is present in every tested sample, aside from TOCA Race Driver 2 (Redump entries 104593-104596).
|
||||
|
||||
if (hintNameTableMatch && importDirectoryTableMatch)
|
||||
return "Engine32";
|
||||
}
|
||||
@@ -40,8 +40,8 @@ namespace BinaryObjectScanner.Protection
|
||||
// Detects Engine32 within the file "engine32.dll".
|
||||
if (pex.Model.ExportTable?.ExportNameTable?.Strings != null)
|
||||
{
|
||||
bool exportNameTableMatch1 = pex.Model.ExportTable.ExportNameTable.Strings.Any(s => s == "engine32.dll");
|
||||
bool exportNameTableMatch2 = pex.Model.ExportTable.ExportNameTable.Strings.Any(s => s == "DeinitEngine");
|
||||
bool exportNameTableMatch1 = Array.Exists(pex.Model.ExportTable.ExportNameTable.Strings, s => s == "engine32.dll");
|
||||
bool exportNameTableMatch2 = Array.Exists(pex.Model.ExportTable.ExportNameTable.Strings, s => s == "DeinitEngine");
|
||||
|
||||
if (exportNameTableMatch1 && exportNameTableMatch2)
|
||||
return "Engine32";
|
||||
@@ -51,7 +51,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.Protection
|
||||
// TODO: Add an MS-DOS executable check for "FREELOCK.EXE".
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -27,8 +26,7 @@ namespace BinaryObjectScanner.Protection
|
||||
// Get the import directory table
|
||||
if (pex.Model.ImportTable?.ImportDirectoryTable != null)
|
||||
{
|
||||
bool match = pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte?.Name == "xlive.dll");
|
||||
if (match)
|
||||
if (Array.Exists(pex.Model.ImportTable.ImportDirectoryTable, idte => idte?.Name == "xlive.dll"))
|
||||
return "Games for Windows LIVE";
|
||||
}
|
||||
|
||||
@@ -36,7 +34,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -30,7 +29,7 @@ namespace BinaryObjectScanner.Protection
|
||||
// Get the header padding strings, if it exists
|
||||
if (pex.HeaderPaddingStrings != null)
|
||||
{
|
||||
var match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.Contains("Gefest Protection System"));
|
||||
var match = pex.HeaderPaddingStrings.Find(s => s.Contains("Gefest Protection System"));
|
||||
if (match != null)
|
||||
return $"Gefest Protection System {GetVersion(match)}";
|
||||
}
|
||||
@@ -39,7 +38,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -60,7 +59,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "The Sudoku Challenge Collection.exe" in "The Sudoku Challenge! Collection" by Play at Joe's.
|
||||
if (strs.Any(s => s.Contains("mfint.dll")))
|
||||
if (strs.Exists(s => s.Contains("mfint.dll")))
|
||||
return "Hexalock Autolock";
|
||||
}
|
||||
|
||||
@@ -68,7 +67,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -33,16 +33,18 @@ namespace BinaryObjectScanner.Protection
|
||||
return $"Stardock Product Activation {pex.GetInternalVersion()}";
|
||||
|
||||
// TODO: Check for CVP* instead?
|
||||
bool containsCheck = pex.Model.ExportTable?.ExportNameTable?.Strings?.Any(s => s?.StartsWith("CVPInitializeClient") ?? false) ?? false;
|
||||
bool containsCheck2 = false;
|
||||
bool containsCheck = false;
|
||||
if (pex.Model.ExportTable?.ExportNameTable?.Strings != null)
|
||||
containsCheck = Array.Exists(pex.Model.ExportTable.ExportNameTable.Strings, s => s?.StartsWith("CVPInitializeClient") ?? false);
|
||||
|
||||
// Get the .rdata section strings, if they exist
|
||||
bool containsCheck2 = false;
|
||||
var strs = pex.GetFirstSectionStrings(".rdata");
|
||||
if (strs != null)
|
||||
{
|
||||
containsCheck2 = strs.Any(s => s.EndsWith("ATTLIST"))
|
||||
&& strs.Any(s => s.Equals("ELEMENT"))
|
||||
&& strs.Any(s => s.StartsWith("NOTATION"));
|
||||
containsCheck2 = strs.Exists(s => s.EndsWith("ATTLIST"))
|
||||
&& strs.Exists(s => s.Equals("ELEMENT"))
|
||||
&& strs.Exists(s => s.StartsWith("NOTATION"));
|
||||
}
|
||||
|
||||
if (containsCheck && containsCheck2)
|
||||
@@ -54,7 +56,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace BinaryObjectScanner.Protection
|
||||
public class IndyVCD : IPathCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
// TODO: Verify if these are OR or AND
|
||||
var matchers = new List<PathMatchSet>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
@@ -30,8 +29,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
var fileNameResource = pex.FindGenericResource("NO NESTED PRMS SUPPORTED");
|
||||
if (fileNameResource.Any())
|
||||
if (pex.FindGenericResource("NO NESTED PRMS SUPPORTED").Count > 0)
|
||||
return "INTENIUM Trial & Buy Protection";
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Content;
|
||||
@@ -24,8 +24,8 @@ namespace BinaryObjectScanner.Protection
|
||||
// Get the .ext section, if it exists
|
||||
if (pex.ContainsSection(".ext ", exact: true))
|
||||
{
|
||||
bool importTableMatches = (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte?.Name == "kernel32.dll") ?? false)
|
||||
&& (pex.Model.ImportTable?.HintNameTable?.Any(s => s?.Name == "VirtualProtect") ?? false);
|
||||
bool importTableMatches = Array.Exists(pex.Model.ImportTable?.ImportDirectoryTable ?? [], idte => idte?.Name == "kernel32.dll")
|
||||
&& Array.Exists(pex.Model.ImportTable?.HintNameTable ?? [], s => s?.Name == "VirtualProtect");
|
||||
|
||||
// Get the .dcrtext section, if it exists
|
||||
if (pex.ContainsSection(".dcrtext") && importTableMatches)
|
||||
@@ -73,15 +73,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (fileContent == null)
|
||||
return null;
|
||||
|
||||
int position = positions[0];
|
||||
#if NET20 || NET35 || NET40
|
||||
byte[] versionBytes = new byte[8];
|
||||
Array.Copy(fileContent, position + 67, versionBytes, 0, 8);
|
||||
char[] version = versionBytes.Select(b => (char)b).ToArray();
|
||||
#else
|
||||
char[] version = new ArraySegment<byte>(fileContent, position + 67, 8).Select(b => (char)b).ToArray();
|
||||
#endif
|
||||
return new string(version);
|
||||
return Encoding.ASCII.GetString(fileContent, positions[0] + 67, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -49,7 +48,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "TFT.exe" in Redump entry 95617.
|
||||
if (strs.Any(s => s.Contains("@KalypsoLauncherXml")))
|
||||
if (strs.Exists(s => s.Contains("@KalypsoLauncherXml")))
|
||||
return "Kalypso Launcher";
|
||||
}
|
||||
|
||||
@@ -57,7 +56,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -10,23 +10,22 @@ namespace BinaryObjectScanner.Protection
|
||||
/// <inheritdoc/>
|
||||
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// Only allow during debug
|
||||
if (!includeDebug)
|
||||
return null;
|
||||
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
// KEY-LOCK COMMAND
|
||||
new(new byte?[]
|
||||
{
|
||||
// KEY-LOCK COMMAND
|
||||
new(new byte?[]
|
||||
{
|
||||
0x4B, 0x45, 0x59, 0x2D, 0x4C, 0x4F, 0x43, 0x4B,
|
||||
0x20, 0x43, 0x4F, 0x4D, 0x4D, 0x41, 0x4E, 0x44
|
||||
}, "Key-Lock (Dongle) (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
0x4B, 0x45, 0x59, 0x2D, 0x4C, 0x4F, 0x43, 0x4B,
|
||||
0x20, 0x43, 0x4F, 0x4D, 0x4D, 0x41, 0x4E, 0x44
|
||||
}, "Key-Lock (Dongle) (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
return null;
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
@@ -41,7 +40,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "START.EXE" (Redump entry 95010 and product ID SVWC-7185).
|
||||
if (strs.Any(s => s.Contains("LGCD2_LAUNCH")))
|
||||
if (strs.Exists(s => s.Contains("LGCD2_LAUNCH")))
|
||||
return "LabelGate CD2";
|
||||
}
|
||||
|
||||
@@ -49,7 +48,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -65,13 +66,13 @@ namespace BinaryObjectScanner.Protection
|
||||
];
|
||||
int endDosStub = (int)(pex.Model.Stub?.Header?.NewExeHeaderAddr ?? 0);
|
||||
int position = -1;
|
||||
bool containsCheck = pex.StubExecutableData?.FirstPosition(check, out position) ?? false;
|
||||
|
||||
// Check the executable tables
|
||||
bool containsCheck2 = (pex.Model.ImportTable?.HintNameTable?.Any(hnte => hnte?.Name == "GetModuleHandleA") ?? false)
|
||||
&& (pex.Model.ImportTable?.HintNameTable?.Any(hnte => hnte?.Name == "GetProcAddress") ?? false)
|
||||
&& (pex.Model.ImportTable?.HintNameTable?.Any(hnte => hnte?.Name == "LoadLibraryA") ?? false)
|
||||
&& (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte?.Name == "KERNEL32.dll") ?? false);
|
||||
bool containsCheck = pex.StubExecutableData?.FirstPosition(check, out position) ?? false;
|
||||
bool containsCheck2 = Array.Exists(pex.Model.ImportTable?.HintNameTable ?? [], hnte => hnte?.Name == "GetModuleHandleA")
|
||||
&& Array.Exists(pex.Model.ImportTable?.HintNameTable ?? [], hnte => hnte?.Name == "GetProcAddress")
|
||||
&& Array.Exists(pex.Model.ImportTable?.HintNameTable ?? [], hnte => hnte?.Name == "LoadLibraryA")
|
||||
&& Array.Exists(pex.Model.ImportTable?.ImportDirectoryTable ?? [], idte => idte?.Name == "KERNEL32.dll");
|
||||
|
||||
int position2 = -1;
|
||||
|
||||
@@ -111,7 +112,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
public List<string> CheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
@@ -165,49 +166,11 @@ namespace BinaryObjectScanner.Protection
|
||||
if (!sectionContent.FirstPosition(check, out int position))
|
||||
return "(Build unknown)";
|
||||
|
||||
string year, month, day;
|
||||
if (versionTwo)
|
||||
{
|
||||
int index = position + 14;
|
||||
#if NET20 || NET35 || NET40
|
||||
byte[] temp = new byte[2];
|
||||
Array.Copy(sectionContent, index, temp, 0, 2);
|
||||
day = new string(temp.Select(b => (char)b).ToArray());
|
||||
index += 3;
|
||||
Array.Copy(sectionContent, index, temp, 0, 2);
|
||||
month = new string(temp.Select(b => (char)b).ToArray());
|
||||
index += 3;
|
||||
Array.Copy(sectionContent, index, temp, 0, 2);
|
||||
year = "20" + new string(temp.Select(b => (char)b).ToArray());
|
||||
#else
|
||||
day = new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
|
||||
index += 3;
|
||||
month = new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
|
||||
index += 3;
|
||||
year = "20" + new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = position + 13;
|
||||
#if NET20 || NET35 || NET40
|
||||
byte[] temp = new byte[2];
|
||||
Array.Copy(sectionContent, index, temp, 0, 2);
|
||||
day = new string(temp.Select(b => (char)b).ToArray());
|
||||
index += 3;
|
||||
Array.Copy(sectionContent, index, temp, 0, 2);
|
||||
month = new string(temp.Select(b => (char)b).ToArray());
|
||||
index += 3;
|
||||
Array.Copy(sectionContent, index, temp, 0, 2);
|
||||
year = "20" + new string(temp.Select(b => (char)b).ToArray());
|
||||
#else
|
||||
day = new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
|
||||
index += 3;
|
||||
month = new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
|
||||
index += 3;
|
||||
year = "20" + new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
|
||||
#endif
|
||||
}
|
||||
int index = versionTwo ? position + 14 : position + 13;
|
||||
|
||||
string day = Encoding.ASCII.GetString(sectionContent, index + 0, 2);
|
||||
string month = Encoding.ASCII.GetString(sectionContent, index + 3, 2);
|
||||
string year = "20" + Encoding.ASCII.GetString(sectionContent, index + 6, 2);
|
||||
|
||||
return $"(Build {year}-{month}-{day})";
|
||||
}
|
||||
@@ -218,13 +181,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (sectionContent == null)
|
||||
return null;
|
||||
|
||||
#if NET20 || NET35 || NET40
|
||||
byte[] temp = new byte[4];
|
||||
Array.Copy(sectionContent, position + 76, temp, 0, 4);
|
||||
return new string(temp.Select(b => (char)b).ToArray());
|
||||
#else
|
||||
return new string(new ArraySegment<byte>(sectionContent, position + 76, 4).Select(b => (char)b).ToArray());
|
||||
#endif
|
||||
return Encoding.ASCII.GetString(sectionContent, position + 76, 4);
|
||||
}
|
||||
|
||||
public static string? GetVersion16Bit(string firstMatchedString, IEnumerable<string>? files)
|
||||
@@ -233,19 +190,12 @@ namespace BinaryObjectScanner.Protection
|
||||
return string.Empty;
|
||||
|
||||
using var fs = File.Open(firstMatchedString, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
using var br = new BinaryReader(fs);
|
||||
return GetVersion16Bit(br.ReadBytes((int)fs.Length));
|
||||
return GetVersion16Bit(fs.ReadBytes((int)fs.Length));
|
||||
}
|
||||
|
||||
private static string GetVersion16Bit(byte[] fileContent)
|
||||
{
|
||||
#if NET20 || NET35 || NET40
|
||||
byte[] temp = new byte[7];
|
||||
Array.Copy(fileContent, 71, temp, 0, 7);
|
||||
char[] version = temp.Select(b => (char)b).ToArray();
|
||||
#else
|
||||
char[] version = new ArraySegment<byte>(fileContent, 71, 7).Select(b => (char)b).ToArray();
|
||||
#endif
|
||||
string version = Encoding.ASCII.GetString(fileContent, 71, 7);
|
||||
if (char.IsNumber(version[0]) && char.IsNumber(version[2]) && char.IsNumber(version[3]))
|
||||
{
|
||||
if (char.IsNumber(version[5]) && char.IsNumber(version[6]))
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -22,13 +21,11 @@ namespace BinaryObjectScanner.Protection
|
||||
return $"MGI Registration {pex.GetInternalVersion()}";
|
||||
|
||||
// Found in "Register.dll" from "VideoWaveIII" in IA item "mgi-videowave-iii-version-3.00-mgi-software-2000".
|
||||
var resources = pex.FindStringTableByEntry("MGI Registration");
|
||||
if (resources.Any())
|
||||
if (pex.FindStringTableByEntry("MGI Registration").Count > 0)
|
||||
return "MGI Registration";
|
||||
|
||||
// Found in "Register.dll" in IA item "MGIPhotoSuite4.0AndPhotoVista2.02001".
|
||||
resources = pex.FindStringTableByEntry("Register@register.mgisoft.com");
|
||||
if (resources.Any())
|
||||
if (pex.FindStringTableByEntry("Register@register.mgisoft.com").Count > 0)
|
||||
return "MGI Registration";
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -35,7 +34,7 @@ namespace BinaryObjectScanner.Protection
|
||||
public partial class Macrovision
|
||||
{
|
||||
/// <inheritdoc cref="Interfaces.IExecutableCheck{T}.CheckExecutable(string, T, bool)"/>
|
||||
internal string? CDillaCheckExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
internal static string? CDillaCheckExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
// TODO: Implement NE checks for "CDILLA05", "CDILLA10", "CDILLA16", and "CDILLA40".
|
||||
|
||||
@@ -61,7 +60,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Interfaces.IExecutableCheck{T}.CheckExecutable(string, T, bool)"/>
|
||||
internal string? CDillaCheckExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
internal static string? CDillaCheckExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex.Model.SectionTable;
|
||||
@@ -101,36 +100,21 @@ namespace BinaryObjectScanner.Protection
|
||||
return $"C-Dilla License Management System Version {pex.ProductVersion}";
|
||||
|
||||
// Get string table resources
|
||||
var resource = pex.FindStringTableByEntry("C-Dilla Licence Management System");
|
||||
if (resource.Any())
|
||||
if (pex.FindStringTableByEntry("C-Dilla Licence Management System").Count > 0)
|
||||
return $"C-Dilla License Management System";
|
||||
|
||||
resource = pex.FindStringTableByEntry("C-DiIla Licence Management System");
|
||||
if (resource.Any())
|
||||
if (pex.FindStringTableByEntry("C-DiIla Licence Management System").Count > 0)
|
||||
return $"C-Dilla License Management System";
|
||||
|
||||
resource = pex.FindStringTableByEntry("C-DILLA_BITMAP_NAMES_TAG");
|
||||
if (resource.Any())
|
||||
if (pex.FindStringTableByEntry("C-DILLA_BITMAP_NAMES_TAG").Count > 0)
|
||||
return $"C-Dilla License Management System";
|
||||
|
||||
resource = pex.FindStringTableByEntry("C-DILLA_EDITABLE_STRINGS_TAG");
|
||||
if (resource.Any())
|
||||
if (pex.FindStringTableByEntry("C-DILLA_EDITABLE_STRINGS_TAG").Count > 0)
|
||||
return $"C-Dilla License Management System";
|
||||
|
||||
resource = pex.FindStringTableByEntry("CdaLMS.exe");
|
||||
if (resource.Any())
|
||||
if (pex.FindStringTableByEntry("CdaLMS.exe").Count > 0)
|
||||
return $"C-Dilla License Management System";
|
||||
|
||||
resource = pex.FindStringTableByEntry("cdilla51.dll");
|
||||
if (resource.Any())
|
||||
if (pex.FindStringTableByEntry("cdilla51.dll").Count > 0)
|
||||
return $"C-Dilla License Management System";
|
||||
|
||||
resource = pex.FindStringTableByEntry("cdilla52.dll");
|
||||
if (resource.Any())
|
||||
if (pex.FindStringTableByEntry("cdilla52.dll").Count > 0)
|
||||
return $"C-Dilla License Management System";
|
||||
|
||||
resource = pex.FindStringTableByEntry("http://www.c-dilla.com/support/lms.html");
|
||||
if (resource.Any())
|
||||
if (pex.FindStringTableByEntry("http://www.c-dilla.com/support/lms.html").Count > 0)
|
||||
return $"C-Dilla License Management System";
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
@@ -138,7 +122,7 @@ namespace BinaryObjectScanner.Protection
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "DJMixStation\DJMixStation.exe" in IA item "ejay_nestle_trial".
|
||||
if (strs.Any(s => s.Contains("SOFTWARE\\C-Dilla\\RTS")))
|
||||
if (strs.Exists(s => s.Contains("SOFTWARE\\C-Dilla\\RTS")))
|
||||
return "C-Dilla License Management System";
|
||||
}
|
||||
|
||||
@@ -147,8 +131,8 @@ namespace BinaryObjectScanner.Protection
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
|
||||
internal IEnumerable<string> CDillaCheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, List{string})"/>
|
||||
internal static List<string> CDillaCheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
@@ -191,7 +175,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
|
||||
internal string? CDillaCheckFilePath(string path)
|
||||
internal static string? CDillaCheckFilePath(string path)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace BinaryObjectScanner.Protection
|
||||
public partial class Macrovision
|
||||
{
|
||||
/// <inheritdoc cref="Interfaces.IExecutableCheck{T}.CheckExecutable(string, T, bool)"/>
|
||||
internal string? CactusDataShieldCheckExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
internal static string? CactusDataShieldCheckExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex.Model.SectionTable;
|
||||
@@ -42,17 +42,15 @@ namespace BinaryObjectScanner.Protection
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("\\*.CDS")))
|
||||
if (strs.Exists(s => s.Contains("\\*.CDS")))
|
||||
return "Cactus Data Shield 200";
|
||||
|
||||
if (strs.Any(s => s.Contains("DATA.CDS")))
|
||||
if (strs.Exists(s => s.Contains("DATA.CDS")))
|
||||
return "Cactus Data Shield 200";
|
||||
}
|
||||
|
||||
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]).
|
||||
// Modified version of the PlayJ Music Player specificaly for CDS, as indicated by the About page present when running the executable.
|
||||
var resources = pex.FindGenericResource("CactusPJ");
|
||||
if (resources != null && resources.Any())
|
||||
if (pex.FindGenericResource("CactusPJ").Count > 0)
|
||||
return "PlayJ Music Player (Cactus Data Shield 200)";
|
||||
|
||||
// Found in various files in "Les Paul & Friends" (Barcode 4 98806 834170).
|
||||
@@ -63,8 +61,8 @@ namespace BinaryObjectScanner.Protection
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
|
||||
internal IEnumerable<string> CactusDataShieldCheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, List{string})"/>
|
||||
internal static List<string> CactusDataShieldCheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
// TODO: Verify if these are OR or AND
|
||||
var matchers = new List<PathMatchSet>
|
||||
@@ -91,7 +89,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
|
||||
internal string? CactusDataShieldCheckFilePath(string path)
|
||||
internal static string? CactusDataShieldCheckFilePath(string path)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Paths;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -13,7 +12,7 @@ namespace BinaryObjectScanner.Protection
|
||||
public partial class Macrovision
|
||||
{
|
||||
/// <inheritdoc cref="Interfaces.IExecutableCheck{T}.CheckExecutable(string, T, bool)"/>
|
||||
internal string? FLEXnetCheckExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
internal static string? FLEXnetCheckExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex.Model.SectionTable;
|
||||
@@ -61,15 +60,15 @@ namespace BinaryObjectScanner.Protection
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "FLEXLM.CPL", "INSTALLS.EXE", "LMGR326B.DLL", "LMGRD.EXE", and "TAKEFIVE.EXE" in IA item "prog-17_202403".
|
||||
if (strs.Any(s => s.Contains("FLEXlm License Manager")))
|
||||
if (strs.Exists(s => s.Contains("FLEXlm License Manager")))
|
||||
return "FlexLM";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
|
||||
internal IEnumerable<string> FLEXNetCheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, List{string})"/>
|
||||
internal static List<string> FLEXNetCheckDirectoryPath(string path, List<string>? files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
@@ -89,7 +88,7 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
|
||||
internal string? FLEXNetCheckFilePath(string path)
|
||||
internal static string? FLEXNetCheckFilePath(string path)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user