mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-02-04 05:35:49 +00:00
Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
553703c30e | ||
|
|
3fd093f9b4 | ||
|
|
4946d4e7ff | ||
|
|
491fc0f71c | ||
|
|
fe6627f1ba | ||
|
|
edffa3c7cc | ||
|
|
a66d62bfbc | ||
|
|
9321b8f221 | ||
|
|
cd0863ac56 | ||
|
|
24a73e8bfd | ||
|
|
46eaa7db1e | ||
|
|
0eab7fd555 | ||
|
|
dba476d8bb | ||
|
|
b10b4d6658 | ||
|
|
2959fdbe9a | ||
|
|
9c0d100c2a | ||
|
|
03ca0faf2e | ||
|
|
cbaf004e25 | ||
|
|
bbe4fb610c | ||
|
|
650115f722 | ||
|
|
1afcbe3182 | ||
|
|
8aa90dbc49 | ||
|
|
0781524669 | ||
|
|
3b3cb7a862 | ||
|
|
810d20d95c | ||
|
|
de578511bf | ||
|
|
f1ec025950 | ||
|
|
0c58ecc548 | ||
|
|
d2a73a153b | ||
|
|
eae2e3366b | ||
|
|
afb04c99c0 | ||
|
|
1d3bd2f8b1 | ||
|
|
3f52c24713 | ||
|
|
ae1417a343 | ||
|
|
871a3e6366 | ||
|
|
3457b807cb | ||
|
|
027f295d21 | ||
|
|
63e6d1e285 | ||
|
|
2193095f70 | ||
|
|
074694298f | ||
|
|
ce4d32b053 | ||
|
|
a25af3940c | ||
|
|
9d1a2db45a | ||
|
|
5cdf269a3e | ||
|
|
b9d90ec35d | ||
|
|
5fc1d3254d | ||
|
|
d61bae8e61 | ||
|
|
f8f53869ae | ||
|
|
f5146a6e35 | ||
|
|
faf96b9375 | ||
|
|
2228e344f6 | ||
|
|
9955bdcab1 | ||
|
|
4586d49a3f | ||
|
|
1f4e24452a | ||
|
|
090bac4d59 | ||
|
|
59bedf5fce | ||
|
|
1bbc541957 | ||
|
|
1bb0107ceb | ||
|
|
10dad356cd | ||
|
|
22b6971e51 | ||
|
|
3203b56ef6 | ||
|
|
d6db84152f | ||
|
|
b7afad5a4a | ||
|
|
9d6c53f631 | ||
|
|
aa7b02dfc3 | ||
|
|
379ffaf61a | ||
|
|
1bdfccddbc | ||
|
|
c83cdd590c | ||
|
|
f4770374a7 | ||
|
|
72880e93bc | ||
|
|
6c9cd72948 | ||
|
|
2e71ef4635 | ||
|
|
04cd1098ea | ||
|
|
e76ce64568 | ||
|
|
8fe84abef3 | ||
|
|
1b1fa53547 | ||
|
|
5019407f35 | ||
|
|
83ba19eccb | ||
|
|
936bf38521 | ||
|
|
f54b0d2bbb |
43
.github/workflows/build_nupkg.yml
vendored
Normal file
43
.github/workflows/build_nupkg.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Nuget Pack
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Pack
|
||||
run: dotnet pack
|
||||
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 'Nuget Package'
|
||||
path: 'BinaryObjectScanner/bin/Release/*.nupkg'
|
||||
|
||||
- name: Upload to rolling
|
||||
uses: ncipollo/release-action@v1.14.0
|
||||
with:
|
||||
allowUpdates: True
|
||||
artifacts: 'BinaryObjectScanner/bin/Release/*.nupkg'
|
||||
body: 'Last built commit: ${{ github.sha }}'
|
||||
name: 'Rolling Release'
|
||||
prerelease: True
|
||||
replacesArtifacts: True
|
||||
tag: "rolling"
|
||||
updateOnlyUnreleased: True
|
||||
53
.github/workflows/build_test.yml
vendored
Normal file
53
.github/workflows/build_test.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
name: Build Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
project: [Test]
|
||||
runtime: [win-x86, win-x64, linux-x64, osx-x64] #[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]
|
||||
conf: [Release, Debug]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.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' || ''}}
|
||||
|
||||
- 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/
|
||||
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_${{ matrix.conf }}
|
||||
path: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_${{ matrix.conf }}.zip
|
||||
|
||||
- name: Upload to rolling
|
||||
uses: ncipollo/release-action@v1.14.0
|
||||
with:
|
||||
allowUpdates: True
|
||||
artifacts: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_${{ matrix.conf }}.zip
|
||||
body: 'Last built commit: ${{ github.sha }}'
|
||||
name: 'Rolling Release'
|
||||
prerelease: True
|
||||
replacesArtifacts: True
|
||||
tag: "rolling"
|
||||
updateOnlyUnreleased: True
|
||||
17
.github/workflows/check_pr.yml
vendored
Normal file
17
.github/workflows/check_pr.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
name: Build PR
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
|
||||
- name: Build
|
||||
run: dotnet build
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,3 +1,9 @@
|
||||
[submodule "BinaryObjectScanner/_EXTERNAL/stormlibsharp"]
|
||||
path = BinaryObjectScanner/_EXTERNAL/stormlibsharp
|
||||
url = https://github.com/robpaveza/stormlibsharp.git
|
||||
[submodule "BinaryObjectScanner/_EXTERNAL/libmspack4n"]
|
||||
path = BinaryObjectScanner/_EXTERNAL/libmspack4n
|
||||
url = https://github.com/activescott/libmspack4n.git
|
||||
[submodule "BinaryObjectScanner/_EXTERNAL/LessIO"]
|
||||
path = BinaryObjectScanner/_EXTERNAL/LessIO
|
||||
url = https://github.com/activescott/LessIO.git
|
||||
|
||||
2
.vscode/launch.json
vendored
2
.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}/Test/bin/Debug/net6.0/Test.dll",
|
||||
"program": "${workspaceFolder}/Test/bin/Debug/net8.0/Test.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/Test",
|
||||
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||
|
||||
@@ -12,7 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
Developer Guide.md = Developer Guide.md
|
||||
LICENSE = LICENSE
|
||||
publish-nix.sh = publish-nix.sh
|
||||
publish-win.bat = publish-win.bat
|
||||
publish-win.ps1 = publish-win.ps1
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
||||
@@ -3,19 +3,20 @@
|
||||
<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;osx-arm64</RuntimeIdentifiers>
|
||||
<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> --> <!-- Can't be enabled because of external code -->
|
||||
<Version>3.0.2</Version>
|
||||
<Version>3.1.4</Version>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Description>Protection scanning library</Description>
|
||||
<Copyright>Copyright (c)2018-2023 Matt Nadareski</Copyright>
|
||||
<Copyright>Copyright (c)2018-2024 Matt Nadareski</Copyright>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/SabreTools/BinaryObjectScanner</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
@@ -23,26 +24,34 @@
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Set a build flag for Windows specifically -->
|
||||
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x86'">
|
||||
<DefineConstants>$(DefineConstants);WIN</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Exclude certain parts of external modules for .NET Framework 4.5.2 and above -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
|
||||
<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, .NET Framework 4.0, .NET Core and modern .NET -->
|
||||
<PropertyGroup Condition="!$(TargetFramework.StartsWith(`net4`)) OR $(TargetFramework.StartsWith(`net40`))">
|
||||
<!-- Exclude all external modules for .NET Framework 2.0, .NET Framework 3.5, .NET Framework 4.0 or non-Windows builds -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`)) OR !$(RuntimeIdentifier.StartsWith(`win-`))">
|
||||
<DefaultItemExcludes>
|
||||
$(DefaultItemExcludes);
|
||||
_EXTERNAL\**;
|
||||
_EXTERNAL\**
|
||||
</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- These are needed for dealing with native Windows DLLs -->
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
|
||||
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`))">
|
||||
<Content Include="*.dll">
|
||||
<Pack>true</Pack>
|
||||
<PackagePath>contentFiles;content</PackagePath>
|
||||
@@ -57,16 +66,14 @@
|
||||
|
||||
<!-- Support for old .NET versions -->
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))">
|
||||
<PackageReference Include="MinThreadingBridge" Version="0.11.2" />
|
||||
<PackageReference Include="MinTasksExtensionsBridge" Version="0.3.2" />
|
||||
<PackageReference Include="MinThreadingBridge" Version="0.11.4" />
|
||||
<PackageReference Include="MinTasksExtensionsBridge" Version="0.3.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`))">
|
||||
<PackageReference Include="OpenMcdf" Version="2.3.0" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.7.1" />
|
||||
<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.34.2" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageReference Include="SharpCompress" Version="0.36.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
|
||||
@@ -74,12 +81,14 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.3.0" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.3.0" />
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.3.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.3.0" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.3.0" />
|
||||
<PackageReference Include="WiseUnpacker" Version="1.3.0" />
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.4.1" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.2.0" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.3.3" />
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.3.1" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.1" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.4.3" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.7.4" />
|
||||
<PackageReference Include="WiseUnpacker" Version="1.3.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Detect(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Detect(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace BinaryObjectScanner.FileType
|
||||
get
|
||||
{
|
||||
contentCheckClasses ??= InitCheckClasses<IContentCheck>();
|
||||
return contentCheckClasses ?? Enumerable.Empty<IContentCheck>();
|
||||
return contentCheckClasses ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace BinaryObjectScanner.FileType
|
||||
get
|
||||
{
|
||||
linearExecutableCheckClasses ??= InitCheckClasses<ILinearExecutableCheck>();
|
||||
return linearExecutableCheckClasses ?? Enumerable.Empty<ILinearExecutableCheck>();
|
||||
return linearExecutableCheckClasses ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace BinaryObjectScanner.FileType
|
||||
get
|
||||
{
|
||||
msdosExecutableCheckClasses ??= InitCheckClasses<IMSDOSExecutableCheck>();
|
||||
return msdosExecutableCheckClasses ?? Enumerable.Empty<IMSDOSExecutableCheck>();
|
||||
return msdosExecutableCheckClasses ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace BinaryObjectScanner.FileType
|
||||
get
|
||||
{
|
||||
newExecutableCheckClasses ??= InitCheckClasses<INewExecutableCheck>();
|
||||
return newExecutableCheckClasses ?? Enumerable.Empty<INewExecutableCheck>();
|
||||
return newExecutableCheckClasses ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace BinaryObjectScanner.FileType
|
||||
get
|
||||
{
|
||||
portableExecutableCheckClasses ??= InitCheckClasses<IPortableExecutableCheck>();
|
||||
return portableExecutableCheckClasses ?? Enumerable.Empty<IPortableExecutableCheck>();
|
||||
return portableExecutableCheckClasses ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Detect(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -529,7 +529,7 @@ namespace BinaryObjectScanner.FileType
|
||||
return protections;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Initializers
|
||||
|
||||
@@ -537,17 +537,40 @@ namespace BinaryObjectScanner.FileType
|
||||
/// Initialize all implementations of a type
|
||||
/// </summary>
|
||||
private static IEnumerable<T>? InitCheckClasses<T>() =>
|
||||
InitCheckClasses<T>(typeof(Handler).Assembly) ?? Enumerable.Empty<T>();
|
||||
InitCheckClasses<T>(Assembly.GetExecutingAssembly()) ?? [];
|
||||
|
||||
/// <summary>
|
||||
/// Initialize all implementations of a type
|
||||
/// </summary>
|
||||
private static IEnumerable<T>? InitCheckClasses<T>(Assembly assembly)
|
||||
{
|
||||
return assembly.GetTypes()?
|
||||
.Where(t => t.IsClass && t.GetInterface(typeof(T).Name) != null)?
|
||||
.Select(t => (T?)Activator.CreateInstance(t))
|
||||
.Cast<T>() ?? [];
|
||||
List<T> classTypes = [];
|
||||
|
||||
// If not all types can be loaded, use the ones that could be
|
||||
List<Type> assemblyTypes = [];
|
||||
try
|
||||
{
|
||||
assemblyTypes = assembly.GetTypes().ToList<Type>();
|
||||
}
|
||||
catch (ReflectionTypeLoadException rtle)
|
||||
{
|
||||
assemblyTypes = rtle.Types.Where(t => t != null)!.ToList<Type>();
|
||||
}
|
||||
|
||||
// Loop through all types
|
||||
foreach (Type type in assemblyTypes)
|
||||
{
|
||||
// If the type isn't a class or doesn't implement the interface
|
||||
if (!type.IsClass || type.GetInterface(typeof(T).Name) == null)
|
||||
continue;
|
||||
|
||||
// Try to create a concrete instance of the type
|
||||
var instance = (T?)Activator.CreateInstance(type);
|
||||
if (instance != null)
|
||||
classTypes.Add(instance);
|
||||
}
|
||||
|
||||
return classTypes;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using UnshieldSharp.Archive;
|
||||
#endif
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
{
|
||||
@@ -19,17 +17,13 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
{
|
||||
#if NET20 || NET35
|
||||
// Not supported for .NET Framework 2.0 or .NET Framework 3.5 due to library support
|
||||
return null;
|
||||
#else
|
||||
try
|
||||
{
|
||||
// Create a temp output directory
|
||||
@@ -68,7 +62,6 @@ namespace BinaryObjectScanner.FileType
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using UnshieldSharp.Cabinet;
|
||||
#endif
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
{
|
||||
@@ -19,17 +17,13 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
{
|
||||
#if NET20 || NET35
|
||||
// Not supported for .NET Framework 2.0 or .NET Framework 3.5 due to library support
|
||||
return null;
|
||||
#else
|
||||
// Get the name of the first cabinet file or header
|
||||
var directory = Path.GetDirectoryName(file);
|
||||
string noExtension = Path.GetFileNameWithoutExtension(file);
|
||||
@@ -102,7 +96,6 @@ namespace BinaryObjectScanner.FileType
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Detect(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
#if NETFRAMEWORK && !NET20 && !NET35 && !NET40
|
||||
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
|
||||
using StormLibSharp;
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -26,8 +26,9 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
{
|
||||
#if NET20 || NET35 || NET40 || NETCOREAPP || NET5_0_OR_GREATER
|
||||
// Not supported for .NET Core and modern .NET due to Windows DLL requirements
|
||||
#if NET20 || NET35 || NET40 || !WIN
|
||||
// Not supported for old .NET due to feature requirements
|
||||
// Not supported in non-Windows builds due to DLL requirements
|
||||
return null;
|
||||
#else
|
||||
try
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
|
||||
using LibMSPackN;
|
||||
#endif
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
{
|
||||
@@ -18,16 +21,50 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
{
|
||||
#if NET20 || NET35 || NET40 || !WIN
|
||||
// Not supported for old .NET due to feature requirements
|
||||
// Not supported in non-Windows builds due to DLL requirements
|
||||
return null;
|
||||
#else
|
||||
try
|
||||
{
|
||||
// Create a temp output directory
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
using (var cabArchive = new MSCabinet(file))
|
||||
{
|
||||
// Loop over each entry
|
||||
foreach (var compressedFile in cabArchive.GetFiles())
|
||||
{
|
||||
try
|
||||
{
|
||||
string tempFile = Path.Combine(tempPath, compressedFile.Filename);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
|
||||
compressedFile.ExtractTo(tempFile);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Detect(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Detect(fs, file, includeDebug);
|
||||
}
|
||||
@@ -48,7 +48,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
using ICSharpCode.SharpZipLib.Zip.Compression;
|
||||
#endif
|
||||
using SabreTools.Compression.zlib;
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
{
|
||||
@@ -20,7 +18,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -230,15 +228,26 @@ namespace BinaryObjectScanner.FileType
|
||||
}
|
||||
else
|
||||
{
|
||||
// Decompress the data
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
// Inflate the data into the buffer
|
||||
var zstream = new ZLib.z_stream_s();
|
||||
data = new byte[outputFileSize];
|
||||
Inflater inflater = new Inflater();
|
||||
inflater.SetInput(compressedData);
|
||||
inflater.Inflate(data);
|
||||
#else
|
||||
data = new byte[outputFileSize];
|
||||
#endif
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* payloadPtr = compressedData)
|
||||
fixed (byte* dataPtr = data)
|
||||
{
|
||||
zstream.next_in = payloadPtr;
|
||||
zstream.avail_in = (uint)compressedData.Length;
|
||||
zstream.total_in = (uint)compressedData.Length;
|
||||
zstream.next_out = dataPtr;
|
||||
zstream.avail_out = (uint)data.Length;
|
||||
zstream.total_out = 0;
|
||||
|
||||
ZLib.inflateInit_(zstream, ZLib.zlibVersion(), compressedData.Length);
|
||||
int zret = ZLib.inflate(zstream, 1);
|
||||
ZLib.inflateEnd(zstream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have an invalid output directory
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Detect(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,20 @@ namespace BinaryObjectScanner.FileType
|
||||
else if (fileContent.Contains("Please enter a valid registration number"))
|
||||
protections.Add("CD-Key / Serial");
|
||||
|
||||
// CopyKiller
|
||||
// Found in "autorun.dat" in CopyKiller versions 3.62 and 3.64.
|
||||
if (fileContent.Contains("CopyKiller CD-Protection V3.6x"))
|
||||
protections.Add("CopyKiller V3.62-V3.64");
|
||||
// Found in "autorun.dat" in CopyKiller versions 3.99 and 3.99a.
|
||||
else if (fileContent.Contains("CopyKiller V4 CD / DVD-Protection"))
|
||||
protections.Add("CopyKiller V3.99+");
|
||||
// Found in "engine.wzc" in CopyKiller versions 3.62 and 3.64.
|
||||
else if (fileContent.Contains("CopyKiller V3.6x Protection Engine"))
|
||||
protections.Add("CopyKiller V3.62-V3.64");
|
||||
// Found in "engine.wzc" in CopyKiller versions 3.99 and 3.99a.
|
||||
else if (fileContent.Contains("CopyKiller V3.99x Protection Engine"))
|
||||
protections.Add("CopyKiller V3.99+");
|
||||
|
||||
// Freelock
|
||||
// Found in "FILE_ID.DIZ" distributed with Freelock.
|
||||
if (fileContent.Contains("FREELOCK 1.0"))
|
||||
@@ -98,6 +112,28 @@ namespace BinaryObjectScanner.FileType
|
||||
if (fileContent.Contains("Sentinel Driver Disk"))
|
||||
protections.Add("Rainbow Sentinel");
|
||||
|
||||
// SafeDisc
|
||||
// TODO: Add better version parsing.
|
||||
// Found in "Info.plist" in Redump entries 23983, 42762, 72713, 73070, and 89603.
|
||||
if (fileContent.Contains("<string>com.europevisionmacro.SafeDiscDVD</string>"))
|
||||
{
|
||||
if (fileContent.Contains("<string>2.90.032</string>"))
|
||||
protections.Add("SafeDiscDVD for Macintosh 2.90.032");
|
||||
else
|
||||
protections.Add("SafeDiscDVD for Macintosh (Unknown Version - Please report to us on GitHub)");
|
||||
}
|
||||
|
||||
// Found in "Info.plist" in Redump entry 89649.
|
||||
if (fileContent.Contains("<string>com.macrovisioneurope.SafeDiscLT</string>"))
|
||||
{
|
||||
// TODO: Investigate why "CFBundleGetInfoString" and "CFBundleShortVersionString" say version 2.70.020, but "CFBundleVersion" says version 2.70.010.
|
||||
if (fileContent.Contains("<string>2.70.020</string"))
|
||||
protections.Add("SafeDiscLT for Macintosh 2.70.020");
|
||||
else
|
||||
protections.Add("SafeDiscLT for Macintosh (Unknown Version - Please report to us on GitHub)");
|
||||
}
|
||||
|
||||
|
||||
// The full line from a sample is as follows:
|
||||
//
|
||||
// The files securom_v7_01.dat and securom_v7_01.bak have been created during the installation of a SecuROM protected application.
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
@@ -124,7 +124,7 @@ namespace BinaryObjectScanner.FileType
|
||||
try
|
||||
{
|
||||
// Open the archive
|
||||
archiveStream = File.OpenRead(archiveFileName);
|
||||
archiveStream = File.Open(archiveFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
|
||||
// Seek to the data
|
||||
archiveStream.Seek(directoryItem.DirectoryEntry.EntryOffset, SeekOrigin.Begin);
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Utilities;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using static BinaryObjectScanner.Utilities.Dictionary;
|
||||
|
||||
namespace BinaryObjectScanner
|
||||
@@ -62,7 +63,7 @@ namespace BinaryObjectScanner
|
||||
#endif
|
||||
|
||||
// Preprocess the list of files
|
||||
files = files?.Select(f => f.Replace('\\', '/'))?.ToList();
|
||||
files = files?.Select(f => f.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar))?.ToList();
|
||||
|
||||
// Iterate through all checks
|
||||
#if NET20 || NET35
|
||||
@@ -108,7 +109,7 @@ namespace BinaryObjectScanner
|
||||
/// <summary>
|
||||
/// Handle files based on an IExtractable implementation
|
||||
/// </summary>
|
||||
/// <param name="impl">IDetectable class representing the file type</param>
|
||||
/// <param name="impl">IExtractable class representing the file type</param>
|
||||
/// <param name="fileName">Name of the source file of the stream, for tracking</param>
|
||||
/// <param name="stream">Stream to scan the contents of</param>
|
||||
/// <param name="scanner">Scanner object to use on extractable contents</param>
|
||||
@@ -153,6 +154,198 @@ namespace BinaryObjectScanner
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle files based on an IExtractableMSDOSExecutable implementation
|
||||
/// </summary>
|
||||
/// <param name="impl">IExtractableMSDOSExecutable class representing the file type</param>
|
||||
/// <param name="fileName">Name of the source file of the stream, for tracking</param>
|
||||
/// <param name="mz">MSDOS to scan the contents of</param>
|
||||
/// <param name="scanner">Scanner object to use on extractable contents</param>
|
||||
/// <returns>Set of protections in file, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
public static Dictionary<string, Queue<string>>? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner)
|
||||
#else
|
||||
public static ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner)
|
||||
#endif
|
||||
{
|
||||
// If the extractable file itself fails
|
||||
try
|
||||
{
|
||||
// Extract and get the output path
|
||||
var tempPath = impl.Extract(fileName, mz, scanner.IncludeDebug);
|
||||
if (tempPath == null)
|
||||
return null;
|
||||
|
||||
// Collect and format all found protections
|
||||
var subProtections = scanner.GetProtections(tempPath);
|
||||
|
||||
// If temp directory cleanup fails
|
||||
try
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Prepare the returned protections
|
||||
StripFromKeys(subProtections, tempPath);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
return subProtections;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle files based on an IExtractableLinearExecutable implementation
|
||||
/// </summary>
|
||||
/// <param name="impl">IExtractableLinearExecutable class representing the file type</param>
|
||||
/// <param name="fileName">Name of the source file of the stream, for tracking</param>
|
||||
/// <param name="lex">LinearExecutable to scan the contents of</param>
|
||||
/// <param name="scanner">Scanner object to use on extractable contents</param>
|
||||
/// <returns>Set of protections in file, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
public static Dictionary<string, Queue<string>>? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner)
|
||||
#else
|
||||
public static ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner)
|
||||
#endif
|
||||
{
|
||||
// If the extractable file itself fails
|
||||
try
|
||||
{
|
||||
// Extract and get the output path
|
||||
var tempPath = impl.Extract(fileName, lex, scanner.IncludeDebug);
|
||||
if (tempPath == null)
|
||||
return null;
|
||||
|
||||
// Collect and format all found protections
|
||||
var subProtections = scanner.GetProtections(tempPath);
|
||||
|
||||
// If temp directory cleanup fails
|
||||
try
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Prepare the returned protections
|
||||
StripFromKeys(subProtections, tempPath);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
return subProtections;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle files based on an IExtractableNewExecutable implementation
|
||||
/// </summary>
|
||||
/// <param name="impl">IExtractableNewExecutable class representing the file type</param>
|
||||
/// <param name="fileName">Name of the source file of the stream, for tracking</param>
|
||||
/// <param name="nex">NewExecutable to scan the contents of</param>
|
||||
/// <param name="scanner">Scanner object to use on extractable contents</param>
|
||||
/// <returns>Set of protections in file, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
public static Dictionary<string, Queue<string>>? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner)
|
||||
#else
|
||||
public static ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner)
|
||||
#endif
|
||||
{
|
||||
// If the extractable file itself fails
|
||||
try
|
||||
{
|
||||
// Extract and get the output path
|
||||
var tempPath = impl.Extract(fileName, nex, scanner.IncludeDebug);
|
||||
if (tempPath == null)
|
||||
return null;
|
||||
|
||||
// Collect and format all found protections
|
||||
var subProtections = scanner.GetProtections(tempPath);
|
||||
|
||||
// If temp directory cleanup fails
|
||||
try
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Prepare the returned protections
|
||||
StripFromKeys(subProtections, tempPath);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
return subProtections;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle files based on an IExtractablePortableExecutable implementation
|
||||
/// </summary>
|
||||
/// <param name="impl">IExtractablePortableExecutable class representing the file type</param>
|
||||
/// <param name="fileName">Name of the source file of the stream, for tracking</param>
|
||||
/// <param name="pex">PortableExecutable to scan the contents of</param>
|
||||
/// <param name="scanner">Scanner object to use on extractable contents</param>
|
||||
/// <returns>Set of protections in file, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
public static Dictionary<string, Queue<string>>? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner)
|
||||
#else
|
||||
public static ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner)
|
||||
#endif
|
||||
{
|
||||
// If the extractable file itself fails
|
||||
try
|
||||
{
|
||||
// Extract and get the output path
|
||||
var tempPath = impl.Extract(fileName, pex, scanner.IncludeDebug);
|
||||
if (tempPath == null)
|
||||
return null;
|
||||
|
||||
// Collect and format all found protections
|
||||
var subProtections = scanner.GetProtections(tempPath);
|
||||
|
||||
// If temp directory cleanup fails
|
||||
try
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Prepare the returned protections
|
||||
StripFromKeys(subProtections, tempPath);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
return subProtections;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle files based on an IPathCheck implementation
|
||||
/// </summary>
|
||||
@@ -204,16 +397,40 @@ namespace BinaryObjectScanner
|
||||
/// Initialize all implementations of a type
|
||||
/// </summary>
|
||||
private static IEnumerable<T?> InitCheckClasses<T>() =>
|
||||
InitCheckClasses<T>(typeof(Handler).Assembly);
|
||||
InitCheckClasses<T>(Assembly.GetExecutingAssembly());
|
||||
|
||||
/// <summary>
|
||||
/// Initialize all implementations of a type
|
||||
/// </summary>
|
||||
private static IEnumerable<T?> InitCheckClasses<T>(Assembly assembly)
|
||||
{
|
||||
return assembly.GetTypes()?
|
||||
.Where(t => t.IsClass && t.GetInterface(typeof(T).Name) != null)?
|
||||
.Select(t => (T?)Activator.CreateInstance(t)) ?? [];
|
||||
List<T?> classTypes = [];
|
||||
|
||||
// If not all types can be loaded, use the ones that could be
|
||||
List<Type> assemblyTypes = [];
|
||||
try
|
||||
{
|
||||
assemblyTypes = assembly.GetTypes().ToList<Type>();
|
||||
}
|
||||
catch (ReflectionTypeLoadException rtle)
|
||||
{
|
||||
assemblyTypes = rtle.Types.Where(t => t != null)!.ToList<Type>();
|
||||
}
|
||||
|
||||
// Loop through all types
|
||||
foreach (Type type in assemblyTypes)
|
||||
{
|
||||
// If the type isn't a class or doesn't implement the interface
|
||||
if (!type.IsClass || type.GetInterface(typeof(T).Name) == null)
|
||||
continue;
|
||||
|
||||
// Try to create a concrete instance of the type
|
||||
var instance = (T?)Activator.CreateInstance(type);
|
||||
if (instance != null)
|
||||
classTypes.Add(instance);
|
||||
}
|
||||
|
||||
return classTypes;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Mark a LinearExecutable type as being able to be extracted
|
||||
/// </summary>
|
||||
public interface IExtractableLinearExecutable
|
||||
{
|
||||
/// <summary>
|
||||
/// Extract a LinearExecutable to a temporary path, if possible
|
||||
/// </summary>
|
||||
/// <param name="file">Path to the input file</param>
|
||||
/// <param name="lex">LinearExecutable representing the read-in file</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>Path to extracted files, null on error</returns>
|
||||
string? Extract(string file, LinearExecutable lex, bool includeDebug);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Mark a MSDOS type as being able to be extracted
|
||||
/// </summary>
|
||||
public interface IExtractableMSDOSExecutable
|
||||
{
|
||||
/// <summary>
|
||||
/// Extract a MSDOS to a temporary path, if possible
|
||||
/// </summary>
|
||||
/// <param name="file">Path to the input file</param>
|
||||
/// <param name="mz">MSDOS representing the read-in file</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>Path to extracted files, null on error</returns>
|
||||
string? Extract(string file, MSDOS mz, bool includeDebug);
|
||||
}
|
||||
}
|
||||
19
BinaryObjectScanner/Interfaces/IExtractableNewExecutable.cs
Normal file
19
BinaryObjectScanner/Interfaces/IExtractableNewExecutable.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Mark a NewExecutable type as being able to be extracted
|
||||
/// </summary>
|
||||
public interface IExtractableNewExecutable
|
||||
{
|
||||
/// <summary>
|
||||
/// Extract a NewExecutable to a temporary path, if possible
|
||||
/// </summary>
|
||||
/// <param name="file">Path to the input file</param>
|
||||
/// <param name="nex">NewExecutable representing the read-in file</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>Path to extracted files, null on error</returns>
|
||||
string? Extract(string file, NewExecutable nex, bool includeDebug);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Mark a PortableExecutable type as being able to be extracted
|
||||
/// </summary>
|
||||
public interface IExtractablePortableExecutable
|
||||
{
|
||||
/// <summary>
|
||||
/// Extract a PortableExecutable to a temporary path, if possible
|
||||
/// </summary>
|
||||
/// <param name="file">Path to the input file</param>
|
||||
/// <param name="pex">PortableExecutable representing the read-in file</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>Path to extracted files, null on error</returns>
|
||||
string? Extract(string file, PortableExecutable pex, bool includeDebug);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
@@ -8,7 +7,7 @@ using SabreTools.Serialization.Wrappers;
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class ASPack : IExtractable, IPortableExecutableCheck
|
||||
public class ASPack : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -51,19 +50,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -8,7 +6,7 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// TODO: Verify that all versions are detected
|
||||
public class AdvancedInstaller : IExtractable, IPortableExecutableCheck
|
||||
public class AdvancedInstaller : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -30,19 +28,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -8,7 +7,7 @@ namespace BinaryObjectScanner.Packer
|
||||
// TODO: Add extraction
|
||||
// TODO: Add version checking, if possible
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class Armadillo : IExtractable, IPortableExecutableCheck
|
||||
public class Armadillo : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -42,19 +41,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -8,7 +7,7 @@ namespace BinaryObjectScanner.Packer
|
||||
// Created by IndigoRose (creators of Setup Factory), primarily to be used to create autorun menus for various media.
|
||||
// Official website: https://www.autoplay.org/
|
||||
// TODO: Add extraction
|
||||
public class AutoPlayMediaStudio : IExtractable, IPortableExecutableCheck
|
||||
public class AutoPlayMediaStudio : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -34,19 +33,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
using ICSharpCode.SharpZipLib.Zip.Compression;
|
||||
#endif
|
||||
using SabreTools.Compression.zlib;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -14,7 +12,7 @@ namespace BinaryObjectScanner.Packer
|
||||
// The official website for CExe also includes the source code (which does have to be retrieved by the Wayback Machine)
|
||||
// http://www.scottlu.com/Content/CExe.html
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class CExe : IExtractable, IPortableExecutableCheck
|
||||
public class CExe : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -52,25 +50,10 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse into an executable again for easier extraction
|
||||
var pex = PortableExecutable.Create(stream);
|
||||
if (pex == null)
|
||||
return null;
|
||||
|
||||
// Get the first resource of type 99 with index 2
|
||||
var payload = pex.FindResourceByNamedType("99, 2").FirstOrDefault();
|
||||
if (payload == null || payload.Length == 0)
|
||||
@@ -88,16 +71,34 @@ namespace BinaryObjectScanner.Packer
|
||||
try
|
||||
{
|
||||
// Inflate the data into the buffer
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
Inflater inflater = new Inflater();
|
||||
inflater.SetInput(payload);
|
||||
var zstream = new ZLib.z_stream_s();
|
||||
data = new byte[payload.Length * 4];
|
||||
int read = inflater.Inflate(data);
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* payloadPtr = payload)
|
||||
fixed (byte* dataPtr = data)
|
||||
{
|
||||
zstream.next_in = payloadPtr;
|
||||
zstream.avail_in = (uint)payload.Length;
|
||||
zstream.total_in = (uint)payload.Length;
|
||||
zstream.next_out = dataPtr;
|
||||
zstream.avail_out = (uint)data.Length;
|
||||
zstream.total_out = 0;
|
||||
|
||||
ZLib.inflateInit_(zstream, ZLib.zlibVersion(), payload.Length);
|
||||
int zret = ZLib.inflate(zstream, 1);
|
||||
ZLib.inflateEnd(zstream);
|
||||
}
|
||||
}
|
||||
|
||||
// Trim the buffer to the proper size
|
||||
data = new ReadOnlySpan<byte>(data, 0, read).ToArray();
|
||||
uint read = zstream.total_out;
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
data = new ReadOnlySpan<byte>(data, 0, (int)read).ToArray();
|
||||
#else
|
||||
data = null;
|
||||
var temp = new byte[read];
|
||||
Array.Copy(data, 0, temp, 0, read);
|
||||
data = temp;
|
||||
#endif
|
||||
}
|
||||
catch
|
||||
@@ -107,7 +108,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, LZ is used via the Windows API
|
||||
// Otherwise, LZ is used
|
||||
else
|
||||
{
|
||||
try
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -10,7 +9,7 @@ namespace BinaryObjectScanner.Packer
|
||||
// TODO: Detect 3.15 and up (maybe looking for `Metamorphism`)
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class EXEStealth : IContentCheck, IExtractable, IPortableExecutableCheck
|
||||
public class EXEStealth : IContentCheck, IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
@@ -75,19 +74,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace BinaryObjectScanner.Packer
|
||||
/// Though not technically a packer, this detection is for any executables that include
|
||||
/// others in their resources in some uncompressed manner to be used at runtime.
|
||||
/// </summary>
|
||||
public class EmbeddedExecutable : IExtractable, IPortableExecutableCheck
|
||||
public class EmbeddedExecutable : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -29,27 +29,10 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse into an executable again for easier extraction
|
||||
var pex = PortableExecutable.Create(stream);
|
||||
if (pex?.ResourceData == null)
|
||||
return null;
|
||||
|
||||
// Get the resources that have an executable signature
|
||||
var resources = pex.ResourceData
|
||||
.Where(kvp => kvp.Value != null && kvp.Value is byte[])
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -8,7 +6,7 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class GenteeInstaller : IExtractable, IPortableExecutableCheck
|
||||
public class GenteeInstaller : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -33,19 +31,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -10,7 +9,7 @@ namespace BinaryObjectScanner.Packer
|
||||
// https://www.reddit.com/r/riseofincarnates/comments/m3vbnm/subreddit_revival_does_anyone_still_have_rise_of/
|
||||
// https://steamcommunity.com/app/310950/discussions/0/4224890554455490819/
|
||||
// https://github.com/horsicq/Detect-It-Easy/blob/63a1aa8bb23ca02d8a7fd5936db8dbc5c5d52dea/db/PE/HyperTech%20Crackproof.2.sg
|
||||
public class HyperTechCrackProof : IExtractable, IPortableExecutableCheck
|
||||
public class HyperTechCrackProof : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -32,19 +31,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
@@ -9,7 +8,7 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction - https://github.com/dscharrer/InnoExtract
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class InnoSetup : IExtractable, INewExecutableCheck, IPortableExecutableCheck
|
||||
public class InnoSetup : IExtractablePortableExecutable, INewExecutableCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
@@ -54,19 +53,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -7,7 +6,7 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction, which may be possible with the current libraries but needs to be investigated further.
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class InstallAnywhere : IExtractable, IPortableExecutableCheck
|
||||
public class InstallAnywhere : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -29,19 +28,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -8,7 +6,7 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction - https://github.com/Bioruebe/UniExtract2
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class InstallerVISE : IExtractable, IPortableExecutableCheck
|
||||
public class InstallerVISE : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
//TODO: Add exact version detection for Windows builds, make sure versions before 3.X are detected as well, and detect the Mac builds.
|
||||
/// <inheritdoc/>
|
||||
@@ -31,19 +29,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction, seems to primarily use MSZip compression.
|
||||
public class IntelInstallationFramework : IExtractable, IPortableExecutableCheck
|
||||
public class IntelInstallationFramework : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -34,19 +33,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -8,7 +7,7 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction, which should be possible with LibMSPackN, but it refuses to extract due to SFX files lacking the typical CAB identifiers.
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class MicrosoftCABSFX : IExtractable, IPortableExecutableCheck
|
||||
public class MicrosoftCABSFX : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -48,23 +47,11 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
// Check the internal versions
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -7,7 +5,7 @@ using SabreTools.Serialization.Wrappers;
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class NSIS : IExtractable, IPortableExecutableCheck
|
||||
public class NSIS : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -33,19 +31,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace BinaryObjectScanner.Packer
|
||||
/// PEiD scanning definitions that include NeoLite: https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
/// Website listing various packers, including NeoLite: http://protools.narod.ru/packers.htm
|
||||
/// </summary>
|
||||
public class NeoLite : IExtractable, IPortableExecutableCheck
|
||||
public class NeoLite : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
// TODO: Find samples of NeoLite 1.X.
|
||||
/// <inheritdoc/>
|
||||
@@ -37,20 +37,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
// TODO: Add extraction
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Better version detection - https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
// TODO: Add extraction
|
||||
public class PECompact : IExtractable, IPortableExecutableCheck
|
||||
public class PECompact : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -42,19 +41,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class PEtite : IExtractable, IPortableExecutableCheck
|
||||
public class PEtite : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -25,19 +24,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -8,7 +7,7 @@ namespace BinaryObjectScanner.Packer
|
||||
// TODO: Add extraction, which is possible but the only tools available that can
|
||||
// do this seem to be Universal Extractor 2 and InstallExplorer (https://totalcmd.net/plugring/InstallExplorer.html)
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class SetupFactory : IExtractable, IPortableExecutableCheck
|
||||
public class SetupFactory : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -39,23 +38,11 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
// Check the product version explicitly
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -6,7 +5,7 @@ using SabreTools.Serialization.Wrappers;
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class SevenZipSFX : IExtractable, IPortableExecutableCheck
|
||||
public class SevenZipSFX : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -46,19 +45,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -6,7 +5,7 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class Shrinker : IExtractable, IPortableExecutableCheck
|
||||
public class Shrinker : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -26,19 +25,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -10,7 +9,7 @@ namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class UPX : IExtractable, IPortableExecutableCheck
|
||||
public class UPX : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
private static readonly Regex _oldUpxVersionMatch = new Regex(@"\$Id: UPX (.*?) Copyright \(C\)", RegexOptions.Compiled);
|
||||
|
||||
@@ -64,19 +63,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ using SharpCompress.Readers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
public class WinRARSFX : IExtractable, IPortableExecutableCheck
|
||||
public class WinRARSFX : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -33,17 +33,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
try
|
||||
|
||||
@@ -11,7 +11,7 @@ using SharpCompress.Archives.Zip;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
public class WinZipSFX : IExtractable, INewExecutableCheck, IPortableExecutableCheck
|
||||
public class WinZipSFX : IExtractableNewExecutable, IExtractablePortableExecutable, INewExecutableCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
@@ -63,17 +63,17 @@ namespace BinaryObjectScanner.Packer
|
||||
// TODO: Find a way to generically detect 2.X versions and improve exact version detection for SFX PE versions bundled with WinZip 11+
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
public string? Extract(string file, NewExecutable nex, bool includeDebug)
|
||||
=> Extract(file, includeDebug);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
=> Extract(file, includeDebug);
|
||||
|
||||
/// <summary>
|
||||
/// Handle common extraction between executable types
|
||||
/// </summary>
|
||||
private static string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
try
|
||||
@@ -122,7 +122,7 @@ namespace BinaryObjectScanner.Packer
|
||||
/// </summary>
|
||||
/// TODO: Reduce the checks to only the ones that differ between versions
|
||||
/// TODO: Research to see if the versions are embedded elsewhere in these files
|
||||
private string? GetNEHeaderVersion(NewExecutable nex)
|
||||
private static string? GetNEHeaderVersion(NewExecutable nex)
|
||||
{
|
||||
#region 2.0 Variants
|
||||
|
||||
@@ -680,7 +680,7 @@ namespace BinaryObjectScanner.Packer
|
||||
/// Get the version from the PE export directory table value combinations
|
||||
/// </summary>
|
||||
/// TODO: Research to see if the versions are embedded elsewhere in these files
|
||||
private string? GetPEExportDirectoryVersion(PortableExecutable pex)
|
||||
private static string? GetPEExportDirectoryVersion(PortableExecutable pex)
|
||||
{
|
||||
string sfxFileName = pex.Model.ExportTable?.ExportDirectoryTable?.Name ?? string.Empty;
|
||||
uint sfxTimeDateStamp = pex.Model.ExportTable?.ExportDirectoryTable?.TimeDateStamp ?? uint.MaxValue;
|
||||
|
||||
@@ -11,7 +11,7 @@ using Wise = WiseUnpacker.WiseUnpacker;
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class WiseInstaller : IExtractable, INewExecutableCheck, IPortableExecutableCheck
|
||||
public class WiseInstaller : IExtractableNewExecutable, IExtractablePortableExecutable, INewExecutableCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
@@ -73,33 +73,140 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
public string? Extract(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
try
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
// TODO: Try to find where the file data lives and how to get it
|
||||
var unpacker = new Wise();
|
||||
if (!unpacker.ExtractTo(file, tempPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try to parse as a New Executable
|
||||
var nex = NewExecutable.Create(stream);
|
||||
if (nex != null)
|
||||
return ExtractNewExecutable(nex, file, includeDebug);
|
||||
// Get the matching PE format
|
||||
var format = GetPEFormat(pex);
|
||||
if (format == null)
|
||||
return null;
|
||||
|
||||
// Try to parse as a Portable Executable
|
||||
var pex = PortableExecutable.Create(stream);
|
||||
if (pex != null)
|
||||
return ExtractPortableExecutable(pex, file, includeDebug);
|
||||
// Get the overlay data for easier reading
|
||||
int overlayOffset = 0, dataStart = 0;
|
||||
var overlayData = pex.OverlayData;
|
||||
if (overlayData == null)
|
||||
return null;
|
||||
|
||||
return null;
|
||||
// Skip over the additional DLL name, if we expect it
|
||||
if (format.Dll)
|
||||
{
|
||||
// Read the name length
|
||||
byte dllNameLength = overlayData.ReadByte(ref overlayOffset);
|
||||
dataStart++;
|
||||
|
||||
// Read the name, if it exists
|
||||
if (dllNameLength != 0)
|
||||
{
|
||||
// Ignore the name for now
|
||||
_ = overlayData.ReadBytes(ref overlayOffset, dllNameLength);
|
||||
dataStart += dllNameLength;
|
||||
|
||||
// Named DLLs also have a DLL length that we ignore
|
||||
_ = overlayData.ReadUInt32(ref overlayOffset);
|
||||
dataStart += 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if flags are consistent
|
||||
if (!format.NoCrc)
|
||||
{
|
||||
// Unlike WiseUnpacker, we ignore the flag value here
|
||||
_ = overlayData.ReadUInt32(ref overlayOffset);
|
||||
}
|
||||
|
||||
// Ensure that we have an archive end
|
||||
if (format.ArchiveEnd > 0)
|
||||
{
|
||||
overlayOffset = dataStart + format.ArchiveEnd;
|
||||
int archiveEndLoaded = overlayData.ReadInt32(ref overlayOffset);
|
||||
if (archiveEndLoaded != 0)
|
||||
format.ArchiveEnd = archiveEndLoaded;
|
||||
}
|
||||
|
||||
// Skip to the start of the archive
|
||||
overlayOffset = dataStart + format.ArchiveStart;
|
||||
|
||||
// Skip over the initialization text, if we expect it
|
||||
if (format.InitText)
|
||||
{
|
||||
int initTextLength = overlayData.ReadByte(ref overlayOffset);
|
||||
_ = overlayData.ReadBytes(ref overlayOffset, initTextLength);
|
||||
}
|
||||
|
||||
// Cache the current offset in the overlay as the "start of data"
|
||||
int offsetReal = overlayOffset;
|
||||
|
||||
// If the first entry is PKZIP, we assume it's an embedded zipfile
|
||||
var magic = overlayData.ReadBytes(ref overlayOffset, 4); overlayOffset -= 4;
|
||||
bool pkzip = magic?.StartsWith(new byte?[] { (byte)'P', (byte)'K' }) ?? false;
|
||||
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
// If we have PKZIP
|
||||
if (pkzip)
|
||||
{
|
||||
string tempFile = Path.Combine(tempPath, "WISEDATA.zip");
|
||||
using (Stream tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
|
||||
{
|
||||
tempStream.Write(overlayData, overlayOffset, overlayData.Length - overlayOffset);
|
||||
}
|
||||
}
|
||||
|
||||
// If we have DEFLATE -- TODO: Port implementation here or use DeflateStream
|
||||
else
|
||||
{
|
||||
Wise unpacker = new Wise();
|
||||
if (!unpacker.ExtractTo(file, tempPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -210,165 +317,10 @@ namespace BinaryObjectScanner.Packer
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to extract Wise data from a New Executable
|
||||
/// </summary>
|
||||
/// <param name="nex">New executable to check</param>
|
||||
/// <param name="file">Path to the input file</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if it matches a known version, false otherwise</returns>
|
||||
private string? ExtractNewExecutable(NewExecutable nex, string file, bool includeDebug)
|
||||
{
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
try
|
||||
{
|
||||
// TODO: Try to find where the file data lives and how to get it
|
||||
Wise unpacker = new Wise();
|
||||
if (!unpacker.ExtractTo(file, tempPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to extract Wise data from a Portable Executable
|
||||
/// </summary>
|
||||
/// <param name="pex">Portable executable to check</param>
|
||||
/// <param name="file">Path to the input file</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if it matches a known version, false otherwise</returns>
|
||||
private string? ExtractPortableExecutable(PortableExecutable pex, string file, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the matching PE format
|
||||
var format = GetPEFormat(pex);
|
||||
if (format == null)
|
||||
return null;
|
||||
|
||||
// Get the overlay data for easier reading
|
||||
int overlayOffset = 0, dataStart = 0;
|
||||
var overlayData = pex.OverlayData;
|
||||
if (overlayData == null)
|
||||
return null;
|
||||
|
||||
// Skip over the additional DLL name, if we expect it
|
||||
if (format.Dll)
|
||||
{
|
||||
// Read the name length
|
||||
byte dllNameLength = overlayData.ReadByte(ref overlayOffset);
|
||||
dataStart++;
|
||||
|
||||
// Read the name, if it exists
|
||||
if (dllNameLength != 0)
|
||||
{
|
||||
// Ignore the name for now
|
||||
_ = overlayData.ReadBytes(ref overlayOffset, dllNameLength);
|
||||
dataStart += dllNameLength;
|
||||
|
||||
// Named DLLs also have a DLL length that we ignore
|
||||
_ = overlayData.ReadUInt32(ref overlayOffset);
|
||||
dataStart += 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if flags are consistent
|
||||
if (!format.NoCrc)
|
||||
{
|
||||
// Unlike WiseUnpacker, we ignore the flag value here
|
||||
_ = overlayData.ReadUInt32(ref overlayOffset);
|
||||
}
|
||||
|
||||
// Ensure that we have an archive end
|
||||
if (format.ArchiveEnd > 0)
|
||||
{
|
||||
overlayOffset = dataStart + format.ArchiveEnd;
|
||||
int archiveEndLoaded = overlayData.ReadInt32(ref overlayOffset);
|
||||
if (archiveEndLoaded != 0)
|
||||
format.ArchiveEnd = archiveEndLoaded;
|
||||
}
|
||||
|
||||
// Skip to the start of the archive
|
||||
overlayOffset = dataStart + format.ArchiveStart;
|
||||
|
||||
// Skip over the initialization text, if we expect it
|
||||
if (format.InitText)
|
||||
{
|
||||
int initTextLength = overlayData.ReadByte(ref overlayOffset);
|
||||
_ = overlayData.ReadBytes(ref overlayOffset, initTextLength);
|
||||
}
|
||||
|
||||
// Cache the current offset in the overlay as the "start of data"
|
||||
int offsetReal = overlayOffset;
|
||||
|
||||
// If the first entry is PKZIP, we assume it's an embedded zipfile
|
||||
var magic = overlayData.ReadBytes(ref overlayOffset, 4); overlayOffset -= 4;
|
||||
bool pkzip = magic?.StartsWith(new byte?[] { (byte)'P', (byte)'K' }) ?? false;
|
||||
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
// If we have PKZIP
|
||||
if (pkzip)
|
||||
{
|
||||
string tempFile = Path.Combine(tempPath, "WISEDATA.zip");
|
||||
using (Stream tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
|
||||
{
|
||||
tempStream.Write(overlayData, overlayOffset, overlayData.Length - overlayOffset);
|
||||
}
|
||||
}
|
||||
|
||||
// If we have DEFLATE -- TODO: Port implementation here or use DeflateStream
|
||||
else
|
||||
{
|
||||
Wise unpacker = new Wise();
|
||||
if (!unpacker.ExtractTo(file, tempPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class representing the properties of each recognized Wise installer format
|
||||
/// </summary>
|
||||
/// <see href="https://github.com/mnadareski/WiseUnpacker/blob/master/WiseUnpacker/FormatProperty.cs"/>
|
||||
/// TODO: Requires all fields to be writable in package before replacement
|
||||
private class FormatProperty
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class dotFuscator : IExtractable, IPortableExecutableCheck
|
||||
public class dotFuscator : IExtractablePortableExecutable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -29,19 +27,7 @@ namespace BinaryObjectScanner.Packer
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Extract(Stream? stream, string file, bool includeDebug)
|
||||
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ using SabreTools.Matching;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
// Nothing is currently known about this DRM. One program may possibly have included it, as it has been listed as including these files in the installion directory (https://www.advanceduninstaller.com/Visit-Gallery-2-90896afd3151ed9660dddc23b892863f-application.htm).
|
||||
// Unfortunately, this program and developer are so obscure, I'm not able to find any relevant further information on them whatsoever.
|
||||
// The only source of valuable information currently known is a forum post about a user attempting to crack this DRM (https://forum.p30world.com/showthread.php?t=413264).
|
||||
// Every attachment, upload, or photo from the forum thread are offline and unarchived.
|
||||
public class CDX : IPathCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -1,32 +1,38 @@
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Collections.Concurrent;
|
||||
#endif
|
||||
using System.Collections.Generic;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
public class CopyKiller : IContentCheck, IPathCheck
|
||||
/// <summary>
|
||||
/// CopyKiller was a program made by WebStylerZone that allowed users to copy-protect their burned discs.
|
||||
/// It worked by having users copy files with byte patterns that would create weak sectors to their discs to burn, and relied on drives with buggy firmwares to create bad burns of the discs.
|
||||
/// This would result in discs having intentional bad sectors, making them harder to copy. There was also an optional autorun available that would check for the original CopyKiller files on the disc.
|
||||
/// <see href="https://github.com/TheRogueArchivist/DRML/blob/main/entries/CopyKiller/CopyKiller.md"/>
|
||||
/// TODO: Add support for the developer's EXE obfuscator, "EXEShield Deluxe". Most, if not all, EXEShield protected files are currently detected as "EXE Stealth" by BOS.
|
||||
/// Samples include CopyKiller (Versions 3.64 & 3.99a) and SafeDiscScanner (Version 0.16) (https://archive.org/details/safediscscanner-0.16-webstylerzone-from-unofficial-source).
|
||||
/// </summary>
|
||||
public class CopyKiller : IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
{
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
// Tom Commander
|
||||
new(new byte?[]
|
||||
{
|
||||
0x54, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x6D, 0x6D,
|
||||
0x61, 0x6E, 0x64, 0x65, 0x72
|
||||
}, "CopyKiller"),
|
||||
};
|
||||
// TODO: Figure out how to differentiate between V3.99 and V3.99a.
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex.Model.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
// TODO: Figure out why this check doesn't work.
|
||||
// Found in "autorun.exe" in CopyKiller V3.64, V3.99, and V3.99a.
|
||||
var name = pex.ProductName;
|
||||
if (name?.StartsWith("CopyKiller", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return "CopyKiller V3.64+";
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -38,11 +44,43 @@ namespace BinaryObjectScanner.Protection
|
||||
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
#endif
|
||||
{
|
||||
// TODO: The following checks are overly broad and should be refined
|
||||
// TODO: Look into .PFF files as an indicator. At least one disc has those oversized 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.
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
//new(new PathMatch("Autorun.dat", useEndsWith: true), "CopyKiller"),
|
||||
new(new FilePathMatch("CopyKillerV3"), "CopyKiller V3.62-3.64"),
|
||||
new(new FilePathMatch("CopyKillerV4"), "CopyKiller V3.99-3.99a"),
|
||||
|
||||
new(new List<PathMatch>
|
||||
{
|
||||
new FilePathMatch("ACK3900.ckt"),
|
||||
new FilePathMatch("ACK3999.ckt"),
|
||||
new FilePathMatch("CK100.wzc"),
|
||||
new FilePathMatch("CK2500.ck"),
|
||||
new FilePathMatch("CK3600.tcwz"),
|
||||
new FilePathMatch("Engine.wzc"),
|
||||
new FilePathMatch("P261XP.tcck"),
|
||||
new FilePathMatch("WZ200.rwzc"),
|
||||
new FilePathMatch("XCK3900.ck2"),
|
||||
}, "CopyKiller V3.99+"),
|
||||
|
||||
new(new List<PathMatch>
|
||||
{
|
||||
new FilePathMatch("ACK3900.ckt"),
|
||||
new FilePathMatch("CK100.wzc"),
|
||||
new FilePathMatch("CK2500.ck"),
|
||||
new FilePathMatch("CK3600.tcwz"),
|
||||
new FilePathMatch("Engine.wzc"),
|
||||
new FilePathMatch("P261XP.tcck"),
|
||||
new FilePathMatch("WZ200.rwzc"),
|
||||
new FilePathMatch("XCK3900.ck2"),
|
||||
}, "CopyKiller V3.64+"),
|
||||
|
||||
new(new List<PathMatch>
|
||||
{
|
||||
new FilePathMatch("CK100.wzc"),
|
||||
new FilePathMatch("Engine.wzc"),
|
||||
}, "CopyKiller V3.62+"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -51,11 +89,12 @@ namespace BinaryObjectScanner.Protection
|
||||
/// <inheritdoc/>
|
||||
public string? CheckFilePath(string path)
|
||||
{
|
||||
// TODO: The following checks are overly broad and should be refined
|
||||
// TODO: Look into .PFF files as an indicator. At least one disc has those oversized 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.
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
//new(new PathMatch("Autorun.dat", useEndsWith: true), "CopyKiller"),
|
||||
new(new FilePathMatch("CopyKillerV3"), "CopyKiller V3.62-3.64"),
|
||||
new(new FilePathMatch("CopyKillerV4"), "CopyKiller V3.99-3.99a"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Collections.Concurrent;
|
||||
#endif
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
@@ -7,7 +13,7 @@ namespace BinaryObjectScanner.Protection
|
||||
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/CrypKey%20Installer.1.sg
|
||||
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/CrypKey.2.sg
|
||||
// https://github.com/wolfram77web/app-peid/blob/master/userdb.txt
|
||||
public class CrypKey : IPortableExecutableCheck
|
||||
public class CrypKey : IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
@@ -17,6 +23,26 @@ namespace BinaryObjectScanner.Protection
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the code/CODE section strings, if they exist
|
||||
var strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE");
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "NECRO95.EXE" in IA item "NBECRORV11".
|
||||
// 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")))
|
||||
return "CrypKey Instant 2.0";
|
||||
|
||||
// Generic check to catch unknown CrypKey Instant versions.
|
||||
if (strs.Any(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")))
|
||||
return "CrypKey (Unknown version - Please report to us on GitHub)";
|
||||
}
|
||||
|
||||
// Get the CrypKey version from the VersionInfo, if it exists
|
||||
string version = pex.GetVersionInfoString("CrypKey Version") ?? string.Empty;
|
||||
|
||||
@@ -24,9 +50,14 @@ namespace BinaryObjectScanner.Protection
|
||||
var name = pex.CompanyName;
|
||||
if (name?.StartsWith("CrypKey") == true)
|
||||
return $"CrypKey {version}".TrimEnd();
|
||||
|
||||
name = pex.FileDescription;
|
||||
|
||||
// Found in "CKSEC_32.DLL" in IA item "NBECRORV11".
|
||||
if (name?.StartsWith("CrypKey Instant security library") == true)
|
||||
return $"CrypKey Instant {pex.GetInternalVersion()}";
|
||||
|
||||
// Found in 'cki32k.dll'
|
||||
name = pex.FileDescription;
|
||||
if (name?.StartsWith("CrypKey") == true)
|
||||
return $"CrypKey {version}".TrimEnd();
|
||||
|
||||
@@ -43,5 +74,41 @@ namespace BinaryObjectScanner.Protection
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
#if NET20 || NET35
|
||||
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
#else
|
||||
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
#endif
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found in IA item "NBECRORV11".
|
||||
new(new FilePathMatch("CKLICENS.HLP"), "CrypKey"),
|
||||
new(new FilePathMatch("CKSEC_32.DLL"), "CrypKey"),
|
||||
new(new FilePathMatch("CRYP95.DLL"), "CrypKey"),
|
||||
new(new FilePathMatch("CRYP9516.DLL"), "CrypKey"),
|
||||
new(new FilePathMatch("CRYPKEY.HLP"), "CrypKey"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? CheckFilePath(string path)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found in IA item "NBECRORV11".
|
||||
new(new FilePathMatch("CKLICENS.HLP"), "CrypKey"),
|
||||
new(new FilePathMatch("CKSEC_32.DLL"), "CrypKey"),
|
||||
new(new FilePathMatch("CRYP95.DLL"), "CrypKey"),
|
||||
new(new FilePathMatch("CRYP9516.DLL"), "CrypKey"),
|
||||
new(new FilePathMatch("CRYPKEY.HLP"), "CrypKey"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
public class DBB
|
||||
{
|
||||
// TODO: Implement - http://web.archive.org/web/20040604233815/www.wkit.com/sites/wkit/setup/eng/index.asp
|
||||
}
|
||||
}
|
||||
@@ -51,10 +51,18 @@ namespace BinaryObjectScanner.Protection
|
||||
if (name?.Equals("Denuvo Anti-Cheat Update Service", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Denuvo Anti-Cheat";
|
||||
|
||||
// Found in "denuvo-anti-cheat-update-service-launcher.dll".
|
||||
if (name?.Equals("Denuvo Anti-Cheat Update Service Launcher", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Denuvo Anti-Cheat";
|
||||
|
||||
// Found in "denuvo-anti-cheat-runtime.dll".
|
||||
if (name?.Equals("Denuvo Anti-Cheat Runtime", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Denuvo Anti-Cheat";
|
||||
|
||||
// Found in "denuvo-anti-cheat-crash-report.exe".
|
||||
if (name?.Equals("Denuvo Anti-Cheat Crash Report Tool", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Denuvo Anti-Cheat";
|
||||
|
||||
// Data sourced from:
|
||||
// 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
|
||||
@@ -274,6 +282,15 @@ namespace BinaryObjectScanner.Protection
|
||||
|
||||
// This file is a renamed copy of "denuvo-anti-cheat-update-service.exe" which is only seen in the folder of the main game executable after it has been run, but before Denuvo Anti-Cheat is finished installing.
|
||||
new(new PathMatch("Denuvo Anti-Cheat Installer.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
|
||||
// Found in the Denuvo Anti-Cheat installer on their support website. (https://web.archive.org/web/20240130142033/https://support.codefusion.technology/anti-cheat/?l=ja&s=ac&e=2009)
|
||||
new(new PathMatch("denuvo-anti-cheat-installer.zip", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
|
||||
// Found in "denuvo-anti-cheat-installer.zip".
|
||||
new(new PathMatch("Denuvo-Anti-Cheat_install_run_as_Admin.bat", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
new(new PathMatch("denuvo-anti-cheat-crash-report.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
new(new PathMatch("denuvo-anti-cheat-crash-report.exe.config", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
new(new PathMatch("denuvo-anti-cheat-update-service-launcher.dll", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: false);
|
||||
@@ -293,6 +310,15 @@ namespace BinaryObjectScanner.Protection
|
||||
|
||||
// This file is a renamed copy of "denuvo-anti-cheat-update-service.exe" which is only seen in the folder of the main game executable after it has been run, but before Denuvo Anti-Cheat is finished installing.
|
||||
new(new PathMatch("Denuvo Anti-Cheat Installer.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
|
||||
// Found in the Denuvo Anti-Cheat installer on their support website. (https://web.archive.org/web/20240130142033/https://support.codefusion.technology/anti-cheat/?l=ja&s=ac&e=2009)
|
||||
new(new PathMatch("denuvo-anti-cheat-installer.zip", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
|
||||
// Found in "denuvo-anti-cheat-installer.zip".
|
||||
new(new PathMatch("Denuvo-Anti-Cheat_install_run_as_Admin.bat", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
new(new PathMatch("denuvo-anti-cheat-crash-report.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
new(new PathMatch("denuvo-anti-cheat-crash-report.exe.config", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
new(new PathMatch("denuvo-anti-cheat-update-service-launcher.dll", useEndsWith: true), "Denuvo Anti-Cheat"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
@@ -113,9 +113,6 @@ namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found to be the default name used in HexaLock AutoLock 4.5.
|
||||
new(new FilePathMatch("Start_Here.exe"), "HexaLock AutoLock 4.5"),
|
||||
|
||||
// Found to be contained in HexaLock AutoLock 4.5 and 4.7.
|
||||
new(new FilePathMatch("MFINT.DLL"), "HexaLock AutoLock"),
|
||||
new(new FilePathMatch("MFIMP.DLL"), "HexaLock AutoLock"),
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
using System;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Collections.Concurrent;
|
||||
#endif
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
@@ -16,12 +23,96 @@ namespace BinaryObjectScanner.Protection
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Found in "IsSvcInstDanceEJay7.dll" in IA item "computer200709dvd" (Dance eJay 7).
|
||||
var name = pex.ProductName;
|
||||
|
||||
// Found in "IsSvcInstDanceEJay7.dll" in IA item "computer200709dvd" (Dance eJay 7).
|
||||
if (name?.Equals("FLEXnet Activation Toolkit", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"FLEXnet";
|
||||
return "FLEXnet";
|
||||
|
||||
// Found in "INSTALLS.EXE", "LMGR326B.DLL", "LMGRD.EXE", and "TAKEFIVE.EXE" in IA item "prog-17_202403".
|
||||
if (name?.Equals("Globetrotter Software Inc lmgr326b Flexlm", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"FlexLM {pex.ProductVersion}";
|
||||
|
||||
// Generic case to catch unknown versions.
|
||||
if (name?.Contains("Flexlm") == true)
|
||||
return "FlexLM (Unknown Version - Please report to us on GitHub)";
|
||||
|
||||
name = pex.FileDescription;
|
||||
|
||||
// Found in "INSTALLS.EXE", "LMGR326B.DLL", "LMGRD.EXE", and "TAKEFIVE.EXE" in IA item "prog-17_202403".
|
||||
if (name?.Equals("lmgr326b", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"FlexLM {pex.ProductVersion}";
|
||||
|
||||
name = pex.LegalTrademarks;
|
||||
|
||||
// Found in "INSTALLS.EXE", "LMGR326B.DLL", "LMGRD.EXE", and "TAKEFIVE.EXE" in IA item "prog-17_202403".
|
||||
if (name?.Equals("Flexible License Manager,FLEXlm,Globetrotter,FLEXID", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"FlexLM {pex.ProductVersion}";
|
||||
|
||||
if (name?.Contains("FLEXlm") == true)
|
||||
return $"FlexLM {pex.ProductVersion}";
|
||||
|
||||
name = pex.OriginalFilename;
|
||||
|
||||
// Found in "INSTALLS.EXE", "LMGR326B.DLL", "LMGRD.EXE", and "TAKEFIVE.EXE" in IA item "prog-17_202403".
|
||||
// It isn't known why these various executables have the same original filename.
|
||||
if (name?.Equals("lmgr326b.dll", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"FlexLM {pex.ProductVersion}";
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
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")))
|
||||
return "FlexLM";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
|
||||
#if NET20 || NET35
|
||||
internal Queue<string> FLEXNetCheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
#else
|
||||
internal ConcurrentQueue<string> FLEXNetDirectoryPath(string path, IEnumerable<string>? files)
|
||||
#endif
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found in IA item "prog-17_202403".
|
||||
new(new PathMatch("FlexLM-6.1F", useEndsWith: true), "FlexLM 6.1f"),
|
||||
new(new PathMatch("FlexLM", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("FLexLM_Licensing.wri", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("LMGR326B.DLL", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("FLEXLM.CPL", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("LMGRD.EXE", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("LMGRD95.EXE", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("LMUTIL.EXE", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("READFLEX.WRI", useEndsWith: true), "FlexLM"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
|
||||
internal string? FLEXNetCheckFilePath(string path)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found in IA item "prog-17_202403".
|
||||
new(new PathMatch("FlexLM-6.1F", useEndsWith: true), "FlexLM 6.1f"),
|
||||
new(new PathMatch("FlexLM", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("FLexLM_Licensing.wri", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("LMGR326B.DLL", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("FLEXLM.CPL", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("LMGRD.EXE", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("LMGRD95.EXE", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("LMUTIL.EXE", useEndsWith: true), "FlexLM"),
|
||||
new(new PathMatch("READFLEX.WRI", useEndsWith: true), "FlexLM"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ using System.Collections.Concurrent;
|
||||
#endif
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SabreTools.Hashing;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using static BinaryObjectScanner.Utilities.Hashing;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
@@ -47,8 +47,8 @@ namespace BinaryObjectScanner.Protection
|
||||
// So far, every seemingly-randomly named EXE on RipGuard discs have a consistent hash.
|
||||
if (fi.Length == 49_152)
|
||||
{
|
||||
var sha1 = GetFileSHA1(file);
|
||||
if (sha1 == "6A7B8545800E0AB252773A8CD0A2185CA2497938")
|
||||
var sha1 = HashTool.GetFileHash(file, HashType.SHA1);
|
||||
if (string.Equals(sha1, "6A7B8545800E0AB252773A8CD0A2185CA2497938", StringComparison.OrdinalIgnoreCase))
|
||||
return "RipGuard";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Hashing;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using static BinaryObjectScanner.Utilities.Hashing;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
@@ -128,6 +128,14 @@ namespace BinaryObjectScanner.Protection
|
||||
new(".icd", useEndsWith: true),
|
||||
}, "SafeDisc 1/Lite"),
|
||||
|
||||
// Check for the original filename used for the SafeDisc splash-screens, new file names are used in later versions.
|
||||
new(new List<PathMatch>
|
||||
{
|
||||
new FilePathMatch("00000001.TMP"),
|
||||
new FilePathMatch("SPLSH16.BMP"),
|
||||
new FilePathMatch("SPLSH256.BMP"),
|
||||
}, "SafeDisc 1.00.025-1.01.044"),
|
||||
|
||||
new(new List<PathMatch>
|
||||
{
|
||||
new FilePathMatch("00000001.TMP"),
|
||||
@@ -154,10 +162,21 @@ namespace BinaryObjectScanner.Protection
|
||||
new FilePathMatch("secdrv.sys"),
|
||||
}, "SafeDisc 1.45.011-1.50.020"),
|
||||
|
||||
// TODO: Research "splash16.bmp" and "splash256.bmp".
|
||||
// Search for the splash screen files known to sometimes contain a generic SafeDisc splash-screen.
|
||||
new(new FilePathMatch("00000000.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000000.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("0000040c.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("0000040c.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000407.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000407.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000409.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000409.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000809.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000809.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00001009.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00001009.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
|
||||
// Found to be present in every version of SafeDisc, possibly every single release.
|
||||
//new(new FilePathMatch("00000001.TMP"), GetSafeDisc00000001TMPVersion, "SafeDisc"),
|
||||
// The file "00000001.TMP" is found in most, if not all, SafeDisc protected programs and is detected within the general Macrovision checks due to being used in other Macrovision DRM.
|
||||
|
||||
// Found in many versions of SafeDisc, beginning in 2.05.030 and being used all the way until the final version 4.90.010. It is not always present, even in versions it has been used in. Found in Redump entries 56319 and 72195.
|
||||
new(new FilePathMatch("00000002.TMP"), "SafeDisc 2+"),
|
||||
@@ -215,8 +234,20 @@ namespace BinaryObjectScanner.Protection
|
||||
new(new FilePathMatch("00000001.LT1"), "SafeDisc Lite"),
|
||||
new(new FilePathMatch("LTDLL.DLL"), "SafeDisc Lite"),
|
||||
|
||||
// Found on Redump entry 42762.
|
||||
new(".SafeDiscDVD.bundle", "SafeDisc for Macintosh"),
|
||||
// Found in Redump entries 23983, 42762, 72713, 73070, and 89603.
|
||||
new(new FilePathMatch(".SafeDiscDVD.bundle"), "SafeDiscDVD for Macintosh"),
|
||||
new(new FilePathMatch("SafeDiscDVD"), "SafeDiscDVD for Macintosh"),
|
||||
|
||||
// Found in Redump entries 42762 and 73070.
|
||||
// These files, along with "00000001.TMP" as found in the same version of SafeDiscDVD, appear to be likely encrypted game executables and are multiple GB in size.
|
||||
new(new FilePathMatch("00000001I.TMP"), "SafeDiscDVD for Macintosh"),
|
||||
new(new FilePathMatch("00000001P.TMP"), "SafeDiscDVD for Macintosh"),
|
||||
|
||||
// Found in Redump entry 89649.
|
||||
new(new FilePathMatch("SafeDiscLT.bundle"), "SafeDiscLT for Macintosh"),
|
||||
new(new FilePathMatch("SafeDiscLT"), "SafeDiscLT for Macintosh"),
|
||||
|
||||
// TODO: Add SafeDisc detection for Redump entry 63769 once Mac executables are supported for scanning. It appears to contain the same "BoG_" string and version detection logic.
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: false);
|
||||
@@ -231,10 +262,25 @@ namespace BinaryObjectScanner.Protection
|
||||
new(new FilePathMatch("CLCD32.DLL"), GetSafeDiscCLCD32Version, "SafeDisc"),
|
||||
new(new FilePathMatch("CLOKSPL.EXE"), GetSafeDiscCLOKSPLVersion, "SafeDisc"),
|
||||
|
||||
//new(new FilePathMatch("00000001.TMP"), GetSafeDisc00000001TMPVersion, "SafeDisc"),
|
||||
// The file "00000001.TMP" is found in most, if not all, SafeDisc protected programs and is detected within the general Macrovision checks due to being used in other Macrovision DRM.
|
||||
|
||||
// Found in many versions of SafeDisc, beginning in 2.05.030 and being used all the way until the final version 4.90.010. It is not always present, even in versions it has been used in. Found in Redump entries 56319 and 72195.
|
||||
new(new FilePathMatch("00000002.TMP"), "SafeDisc 2+"),
|
||||
|
||||
// TODO: Research "splash16.bmp" and "splash256.bmp".
|
||||
// Search for the splash screen files known to sometimes contain a generic SafeDisc splash-screen.
|
||||
new(new FilePathMatch("00000000.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000000.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("0000040c.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("0000040c.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000407.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000407.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000409.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000409.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000809.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00000809.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00001009.016"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("00001009.256"), GetSafeDiscSplshVersion, "SafeDisc"),
|
||||
|
||||
|
||||
new(new FilePathMatch("DPLAYERX.DLL"), GetSafeDiscDPlayerXVersion, "SafeDisc"),
|
||||
new(new FilePathMatch("drvmgt.dll"), GetSafeDiscDrvmgtVersion, "SafeDisc"),
|
||||
@@ -292,8 +338,20 @@ namespace BinaryObjectScanner.Protection
|
||||
new(new FilePathMatch("00000001.LT1"), "SafeDisc Lite"),
|
||||
new(new FilePathMatch("LTDLL.DLL"), "SafeDisc Lite"),
|
||||
|
||||
// Found in Redump entry 42762.
|
||||
new(".SafeDiscDVD.bundle", "SafeDisc for Macintosh"),
|
||||
// Found in Redump entries 23983, 42762, 72713, 73070, and 89603.
|
||||
new(new FilePathMatch(".SafeDiscDVD.bundle"), "SafeDiscDVD for Macintosh"),
|
||||
new(new FilePathMatch("SafeDiscDVD"), "SafeDiscDVD for Macintosh"),
|
||||
|
||||
// Found in Redump entries 42762 and 73070.
|
||||
// These files, along with "00000001.TMP" as found in the same version of SafeDiscDVD, appear to be likely encrypted game executables and are multiple GB in size.
|
||||
new(new FilePathMatch("00000001I.TMP"), "SafeDiscDVD for Macintosh"),
|
||||
new(new FilePathMatch("00000001P.TMP"), "SafeDiscDVD for Macintosh"),
|
||||
|
||||
// Found in Redump entry 89649.
|
||||
new(new FilePathMatch("SafeDiscLT.bundle"), "SafeDiscLT for Macintosh"),
|
||||
new(new FilePathMatch("SafeDiscLT"), "SafeDiscLT for Macintosh"),
|
||||
|
||||
// TODO: Add SafeDisc detection for Redump entry 63769 once Mac executables are supported for scanning. It appears to contain the same "BoG_" string and version detection logic.
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
@@ -305,8 +363,8 @@ namespace BinaryObjectScanner.Protection
|
||||
return string.Empty;
|
||||
|
||||
// The hash of the file CLCD16.dll is able to provide a broad version range that appears to be consistent, but it seems it was rarely updated so these checks are quite broad.
|
||||
var sha1 = GetFileSHA1(firstMatchedString);
|
||||
return sha1 switch
|
||||
var sha1 = HashTool.GetFileHash(firstMatchedString, HashType.SHA1);
|
||||
return sha1?.ToUpperInvariant() switch
|
||||
{
|
||||
// Found in Redump entries 61731 and 66005.
|
||||
"C13493AB753891B8BEE9E4E014896B026C01AC92" => "1.00.025-1.01.044",
|
||||
@@ -328,8 +386,8 @@ namespace BinaryObjectScanner.Protection
|
||||
return string.Empty;
|
||||
|
||||
// The hash of the file CLCD32.dll so far appears to be a solid indicator of version for versions it was used with. It appears to have been updated with every release, unlike its counterpart, CLCD16.dll.
|
||||
var sha1 = GetFileSHA1(firstMatchedString);
|
||||
return sha1 switch
|
||||
var sha1 = HashTool.GetFileHash(firstMatchedString, HashType.SHA1);
|
||||
return sha1?.ToUpperInvariant() switch
|
||||
{
|
||||
// Found in Redump entry 66005.
|
||||
"BAD49BA0DEA041E85EF1CABAA9F0ECD822CE1376" => "1.00.025",
|
||||
@@ -427,8 +485,8 @@ namespace BinaryObjectScanner.Protection
|
||||
|
||||
|
||||
// The hash of every "CLOKSPL.EXE" correlates directly to a specific SafeDisc version.
|
||||
var sha1 = GetFileSHA1(firstMatchedString);
|
||||
return sha1 switch
|
||||
var sha1 = HashTool.GetFileHash(firstMatchedString, HashType.SHA1);
|
||||
return sha1?.ToUpperInvariant() switch
|
||||
{
|
||||
// Found in Redump entry 66005.
|
||||
"DD131A7B988065764E2A0F20B66C89049B20A7DE" => "1.00.025",
|
||||
@@ -542,7 +600,7 @@ namespace BinaryObjectScanner.Protection
|
||||
// Found in Redump entries 9718, 12885, and 37523.
|
||||
156_160 => "1.07.000-1.11.000",
|
||||
|
||||
// File size checks for versions 1.2X+ are superceded by executable string checks, which are more accurate. For reference, the previously used file sizes are kept as comments.
|
||||
// File size checks for versions 1.2X+ are superseded by executable string checks, which are more accurate. For reference, the previously used file sizes are kept as comments.
|
||||
// 157,184 bytes corresponds to SafeDisc 1.20.000-1.20.001 (Redump entries 21154 and 37920).
|
||||
// 163,382 bytes corresponds to SafeDisc 1.30.010 (Redump entries 31526 and 55080).
|
||||
// 165,888 bytes corresponds to SafeDisc 1.35.000 (Redump entries 9617 and 49552).
|
||||
@@ -552,6 +610,16 @@ namespace BinaryObjectScanner.Protection
|
||||
// 138,752 bytes corresponds to SafeDisc 1.50.020 (Redump entries 28810 and 62935).
|
||||
|
||||
_ => "1",
|
||||
|
||||
// Hashes have not been found to be a reliable indicator for these files, and likely differ on a game-to-game basis. Some hashes were previously collected and are collected below:
|
||||
// Found in Redump entry 41923.
|
||||
// F7A57F83BDC29040E20FD37CD0C6D7E6B2984180" => "1.00.030",
|
||||
// Found in Redump entries 3569 and 3570.
|
||||
// "A8ED1613D47D1B5064300FF070484528EBB20A3B" => "1.11.000",
|
||||
// It is not known which games these files are from.
|
||||
// "ED680E9A13F593E7A80A69EE1035D956AB62212B" => "1.3x",
|
||||
// "66D8589343E00FA3E11BBF462E38C6F502515BEA" => "1.30.010",
|
||||
// "5751AE2EE805D31227CFE7680F3C8BE4AB8945A3" => "1.40",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -564,12 +632,15 @@ namespace BinaryObjectScanner.Protection
|
||||
// There are occasionaly inconsistencies, even within the well detected version range. This seems to me to mostly happen with later (3.20+) games, and seems to me to be an example of the SafeDisc distribution becoming more disorganized with time.
|
||||
// Particularly interesting inconsistencies will be noted below:
|
||||
// Redump entry 73786 has an EXE with a scrubbed version, a DIAG.exe with a version of 4.60.000, and a copy of drvmgt.dll belonging to version 3.10.020. This seems like an accidental(?) distribution of older drivers, as this game was released 3 years after the use of 3.10.020.
|
||||
var sha1 = GetFileSHA1(firstMatchedString);
|
||||
return sha1 switch
|
||||
var sha1 = HashTool.GetFileHash(firstMatchedString, HashType.SHA1);
|
||||
return sha1?.ToUpperInvariant() switch
|
||||
{
|
||||
// Found in Redump entry 102979.
|
||||
"B858CB282617FB0956D960215C8E84D1CCF909C6" => "(Empty File)",
|
||||
|
||||
// Found in Redump entry 63488.
|
||||
"DA39A3EE5E6B4B0D3255BFEF95601890AFD80709" => "(Empty File)",
|
||||
|
||||
// Found in Redump entries 29073 and 31149.
|
||||
"33434590D7DE4EEE2C35FCC98B0BF141F422B26D" => "1.06.000",
|
||||
|
||||
@@ -655,7 +726,8 @@ namespace BinaryObjectScanner.Protection
|
||||
"B824ED257946EEE93F438B25C855E9DDE7A3671A" => "2.90.010-2.90.040",
|
||||
|
||||
// Found in Redump entries 13230 and 68204.
|
||||
"CDA56FD150C9E9A19D7AF484621352122431F029" => "3.10.020",
|
||||
// SafeDisc 4+ is known to sometimes use old versions of drivers, such as in Redump entry 101261.
|
||||
"CDA56FD150C9E9A19D7AF484621352122431F029" => "3.10.020/4+",
|
||||
|
||||
// Found in Redump entries 36511 and 74338.
|
||||
"E5504C4C31561D38C1F626C851A8D06212EA13E0" => "3.15.010",
|
||||
@@ -701,33 +773,148 @@ namespace BinaryObjectScanner.Protection
|
||||
};
|
||||
}
|
||||
|
||||
private string? GetVersionFromSHA1Hash(string sha1Hash)
|
||||
internal static string? GetSafeDiscSplshVersion(string firstMatchedString, IEnumerable<string>? files)
|
||||
{
|
||||
return sha1Hash.ToLowerInvariant() switch
|
||||
// Special thanks to TheMechasaur for combing through known SafeDisc games and cataloging the splash-screens used in them, making these detections possible.
|
||||
|
||||
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
|
||||
return string.Empty;
|
||||
|
||||
var sha1 = HashTool.GetFileHash(firstMatchedString, HashType.SHA1);
|
||||
switch (sha1?.ToUpperInvariant())
|
||||
{
|
||||
// dplayerx.dll
|
||||
"f7a57f83bdc29040e20fd37cd0c6d7e6b2984180" => "1.00.030",
|
||||
"a8ed1613d47d1b5064300ff070484528ebb20a3b" => "1.11.000",
|
||||
"ed680e9a13f593e7a80a69ee1035d956ab62212b" => "1.3x",
|
||||
"66d8589343e00fa3e11bbf462e38c6f502515bea" => "1.30.010",
|
||||
"5751ae2ee805d31227cfe7680f3c8be4ab8945a3" => "1.40",
|
||||
// Found in Redump entry 63488.
|
||||
case "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709":
|
||||
return "(Empty File)";
|
||||
|
||||
// secdrv.sys
|
||||
"b64ad3ec82f2eb9fb854512cb59c25a771322181" => "1.11.000",
|
||||
"ebf69b0a96adfc903b7e486708474dc864cc0c7c" => "1.40.004",
|
||||
"f68a1370660f8b94f896bbba8dc6e47644d19092" => "2.30",
|
||||
"60bc8c3222081bf76466c521474d63714afd43cd" => "2.40",
|
||||
"08ceca66432278d8c4e0f448436b77583c3c61c8" => "2.50",
|
||||
"10080eb46bf76ac9cf9ea74372cfa4313727f0ca" => "2.51",
|
||||
"832d359a6de191c788b0e61e33f3d01f8d793d3c" => "2.70",
|
||||
"afcfaac945a5b47712719a5e6a7eb69e36a5a6e0" or "cb24fbe8aa23a49e95f3c83fb15123ffb01f43f4" => "2.80",
|
||||
"0383b69f98d0a9c0383c8130d52d6b431c79ac48" => "2.90",
|
||||
"d7c9213cc78ff57f2f655b050c4d5ac065661aa9" => "3.20",
|
||||
"fc6fedacc21a7244975b8f410ff8673285374cc2" => "4.00.002",// Also 4.60.000, might be a fluke
|
||||
"2d9f54f35f5bacb8959ef3affdc3e4209a4629cb" => "1-4",
|
||||
// First known generic SafeDisc splash-screen.
|
||||
// 4-bit (16 color) version, found in Redump entries 43321, 45040, 45202, 66586, 68206, 75501, 79272, and 110603.
|
||||
case "D8A8CF761DD7C04F635385E4C4589E5F26C6171E":
|
||||
return "1.11.000-2.40.011";
|
||||
// 8-bit (256 color) version, found in Redump entries 43321, 45040, 45202, 66586, 68206, 75501, 79272, and 110603.
|
||||
case "0C9E45BF3EBE1382A3593994328C22BCB9A55456":
|
||||
return "1.11.000-2.40.011";
|
||||
|
||||
_ => null,
|
||||
};
|
||||
// Second known generic SafeDisc splash-screen.
|
||||
// 4-bit (16 color), found in Redump entries 46339 and 75897.
|
||||
case "9B80F524D45041ED8CE1613AD5BDE94BFDBB2814":
|
||||
return "2.70.030-2.80.010";
|
||||
// 8-bit (256 color) version, found in Redump entries 46339 and 75897.
|
||||
case "827AE9A32906CBE9098C9101184E0BE74CEA2744":
|
||||
return "2.70.030-2.80.010";
|
||||
|
||||
// Third known generic SafeDisc splash-screen.
|
||||
// 4-bit (16 color), found in Redump entries 74338, 75782, 84985, and 91552.
|
||||
case "814ED63FD619655650E271D1B8B46BBE39C3655A":
|
||||
return "3.15.010-3.20.022";
|
||||
// 8-bit (256 color) version, found in Redump entries 31824, 74338, 75782, 84985, 91552, and 104053.
|
||||
case "40C7ACEDB6C41AB067285090373E886EFB4F4AC4":
|
||||
return "3.15.010-4.60.000";
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
// There appear to be a few distinct generations of file names used for SafeDisc splash-screens.
|
||||
// The first are the files named "SPLSH16.BMP"/"SPLSH256.BMP", which were typically used in SafeDisc versions 1.00.025-1.01.044.
|
||||
// The next are the files named "000004XX", "000008XX", "00000cXX", and "00001XXX". When one of these is present, they seemingly always come in pairs of 2 with the extensions ".016" and ".256". They're typically present in SafeDisc versions 1.06.000-2.51.021.
|
||||
// Next come the files simply named "0000000X", which still come in pairs with the extensions ".016" and ".256", starting in SafeDisc version 2.60.052 up until version 4.85.000. After this point, there doesn't seem to be any consistent SafeDisc splash-screen used at all.
|
||||
// Starting SafeDisc version 4.00.000, the files with the ".016" extension seem to mostly disappear, with the ".256" files still being present.
|
||||
// Exceptions:
|
||||
// The files "00000409.016" and "00000409.256" are present in Redump entry 39273, despite it being SafeDisc 2.80.011. This may be because this disc contains some form of SafeDisc Lite as well, which tends to more closely resemble SafeDisc 1.
|
||||
// Redump entry 51597 contains "00000000.016" and "00000000.256", breaking the trend of SafeDisc 4 not having any files with the ".016" extension. This may be due to this being a rerelease, so the splash-screen may have already been present in the original game files and carried over.
|
||||
|
||||
// TODO: Investigate "/409/splash.bmp" and "/0x0409.ini" files in Redump entry 45469.
|
||||
|
||||
// Known SafeDisc splash-screen file names (case-insensitive):
|
||||
// "00000000.016": Found in SafeDisc version 2.60.052-4.00.003 (Redump entries 2064, 9621, 11639, 13230, 32783, 35385, 35512, 39273, 52606, 51597, 63813, 74338, 76775, and 84586).
|
||||
// "00000000.256": Found in SafeDisc version 2.60.052-4.85.000 (Redump entries 2064, 9621, 11639, 13230, 32783, 34783, 35382, 35385, 35512, 39273, 46765, 52606, 51597, 63813, 68551, 71646, 74338, 74366, 76775, 76813, 79113, 83017, 84586, and 98589).
|
||||
// "00000001.016": Found in SafeDisc version 2.72.000-3.20.024 (Redump entries 9621, 76775, and 86177).
|
||||
// "00000001.256": Found in SafeDisc version 2.72.000-4.50.000 (Redump entries 9621, 71646, 76775, 76813, and 86177).
|
||||
// "00000002.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000002.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000003.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000003.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000004.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000004.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000005.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000005.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000006.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000006.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000007.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000007.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000008.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000008.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000009.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000009.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000010.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000010.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000011.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000011.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000a.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000a.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000b.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000b.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000c.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000c.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000d.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000d.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000e.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000e.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000f.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "0000000f.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
|
||||
// "00000404.016": Found in SafeDisc versions 1.40.004-1.50.020 (IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000404.256": Found in SafeDisc versions 1.40.004-1.50.020 (IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000406.016": Found in SafeDisc versions 1.41.000-2.51.021 (Redump entries 61047 and 66852).
|
||||
// "00000406.256": Found in SafeDisc versions 1.41.000-2.51.021 (Redump entries 61047 and 66852).
|
||||
// "00000407.016": Found in SafeDisc versions 1.07.000-2.51.021 (Redump entries 43321, 44350, 46756, 48863, 49552, 66586, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000407.256": Found in SafeDisc versions 1.07.000-2.51.021 (Redump entries 43321, 44350, 46756, 48863, 49552, 66586, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000408.016": Found in SafeDisc version 2.51.021 (Redump entry 38589).
|
||||
// "00000408.256": Found in SafeDisc version 2.51.021 (Redump entry 38589).
|
||||
// "00000409.016": Found in SafeDisc versions 1.06.000-2.80.011 (Redump entries 2022, 2595, 9718, 9819, 9846, 12885, 23786, 29073, 30022, 30555, 31526, 31666, 37832, 37920, 37982, 39273, 48863, 49552, 59462, 62935, and 63323).
|
||||
// "00000409.256": Found in SafeDisc versions 1.06.000-2.80.011 (Redump entries 2022, 2595, 9718, 9819, 9846, 12885, 23786, 29073, 30022, 30555, 31526, 31666, 37982, 37920, 37832, 39273, 48863, 49552, 59462, 62935, and 63323).
|
||||
// "0000040A.016": Found in SafeDisc versions 1.06.000-2.51.021 (Redump entries 29073, 43321, 49552, and 66852).
|
||||
// "0000040A.256": Found in SafeDisc versions 1.06.000-2.51.021 (Redump entries 29073, 43321, 49552 and 66852).
|
||||
// "0000040c.016": Found in SafeDisc versions 1.30.010-2.51.021 (Redump entries 43321, 48863, 49552, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "0000040c.256": Found in SafeDisc versions 1.30.010-2.51.021 (Redump entries 43321, 48863, 49552, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "0000040d.016": Found in SafeDisc version 2.51.021 (Redump entry 38589).
|
||||
// "0000040d.256": Found in SafeDisc version 2.51.021 (Redump entry 38589).
|
||||
// "0000040f.016": Found in SafeDisc version 1.41.000 (Redump entry 61047).
|
||||
// "0000040f.256": Found in SafeDisc version 1.41.000 (Redump entry 61047).
|
||||
// "00000410.016": Found in SafeDisc versions 1.35.000-2.51.021 (Redump entries 9617, 48863, 49552, 66852, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000410.256": Found in SafeDisc versions 1.35.000-2.51.021 (Redump entries 9617, 48863, 49552, 66852, and 79476, IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000411.016": Found in SafeDisc versions 1.40.004-2.51.031 (Redump entries 38589, 53659 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000411.256": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entries 38589, 53659 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000412.016": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entry 38589 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000412.256": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entry 38589 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000413.016": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entries 66852 and 72195 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000413.256": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entries 66852 and 72195 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000415.016": Found in SafeDisc versions 1.40.004-2.10.030 (Redump entry 38541 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000415.256": Found in SafeDisc versions 1.40.004-2.10.030 (Redump entry 38541 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000416.016": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entry 38589 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000416.256": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entry 38589 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000419.016": Found in SafeDisc version 1.41.000 (Redump entry 61047).
|
||||
// "00000419.256": Found in SafeDisc version 1.41.000 (Redump entry 61047).
|
||||
// "0000041d.016": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entries 55823, 66852, and 72195, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "0000041d.256": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entries 55823, 66852, and 72195, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "0000041e.016": Found in SafeDisc version 1.40.004 (IA item the-sims-thai-english-electronic-arts-2000).
|
||||
// "0000041e.256": Found in SafeDisc version 1.40.004 (IA item the-sims-thai-english-electronic-arts-2000).
|
||||
// "00000429.016": Found in SafeDisc version 1.41.000 (Redump entry 61047).
|
||||
// "00000429.256": Found in SafeDisc version 1.41.000 (Redump entry 61047).
|
||||
// "00000804.016": Found in SafeDisc versions 1.40.004-1.50.020 (IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000804.256": Found in SafeDisc versions 1.40.004-1.50.020 (IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000809.016": Found in SafeDisc versions 1.06.000-2.51.021 (Redump entries 9617, 31149, 37478, 37523, 37832, 43321, 48863, 53659, 59462, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000, the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000, and "primal-3d-interactive-series-professional-edition-2002-english" items "Interactive Hand CD", "Interactive Hip CD", and "Interactive Spine CD").
|
||||
// "00000809.256": Found in SafeDisc versions 1.06.000-2.51.021 (Redump entries 9617, 31149, 37478, 37523, 37832, 43321, 48863, 53659, 59462, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000, the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000, and "primal-3d-interactive-series-professional-edition-2002-english" items "Interactive Hand CD", "Interactive Hip CD", and "Interactive Spine CD").
|
||||
// "00000814.016": Found in SafeDisc version 1.41.000 (Redump entry 61047).
|
||||
// "00000814.256": Found in SafeDisc version 1.41.000 (Redump entry 61047).
|
||||
// "00000816.016": Found in SafeDisc version 1.41.000 (Redump entry 61047).
|
||||
// "00000816.256": Found in SafeDisc version 1.41.000 (Redump entry 61047).
|
||||
// "00000c0a.016": Found in SafeDisc versions 1.11.000-2.30.031 (Redump entry 3569, 48863, 55078, 55080, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00000c0a.256": Found in SafeDisc versions 1.11.000-2.30.031 (Redump entry 3569, 48863, 55078, 55080, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
|
||||
// "00001009.016": Found in SafeDisc version 2.30.030 (Redump entry 45040).
|
||||
// "00001009.256": Found in SafeDisc version 2.30.030 (Redump entry 45040).
|
||||
// "SPLSH16.BMP": Found in SafeDisc versions 1.00.025-1.01.044 (Redump entries 66005 and 81619).
|
||||
// "SPLSH256.BMP": Found in SafeDisc versions 1.00.025-1.01.044 (Redump entries 66005 and 81619).
|
||||
}
|
||||
|
||||
private string GetSafeDiscDiagExecutableVersion(PortableExecutable pex)
|
||||
|
||||
@@ -342,6 +342,9 @@ namespace BinaryObjectScanner.Protection
|
||||
var fi = new FileInfo(firstMatchedString);
|
||||
return fi.Length switch
|
||||
{
|
||||
// Found in Redump entry 63488.
|
||||
0 => "(Empty File)",
|
||||
|
||||
// Found in Redump entry 102979.
|
||||
1 => "(Empty File)",
|
||||
|
||||
@@ -388,7 +391,8 @@ namespace BinaryObjectScanner.Protection
|
||||
12_400 => "3.18.000 / SafeDisc 2.90.010-2.90.040",
|
||||
|
||||
// Found in Redump entries 13230, 15383, and 36511.
|
||||
12_528 => "3.19.000 / SafeDisc 3.10.020-3.15.011",
|
||||
// SafeDisc 4+ is known to sometimes use old versions of drivers, such as in Redump entry 101261.
|
||||
12_528 => "3.19.000 / SafeDisc 3.10.020-3.15.011/4+",
|
||||
|
||||
// Found in Redump entries 58625 and 84586.
|
||||
11_973 => "3.22.000 / SafeDisc 3.20.020-3.20.022",
|
||||
@@ -396,8 +400,8 @@ namespace BinaryObjectScanner.Protection
|
||||
// Found in Redump entries 15614, 42034, 45686, 56320, 60021, 79729, and 80776.
|
||||
163_644 => "4.00.060 / SafeDisc 4.00.000-4.70.000",
|
||||
|
||||
// Found distributed online, but so far not in a game release. TODO: Discover original source.
|
||||
// Can be found at https://github.com/ericwj/PsSecDrv/blob/master/tools/SECDRV/SECDRV.sys, and the file is confirmed to be distributed officialy by Microsoft: https://www.virustotal.com/gui/file/34bbb0459c96b3de94ccb0d73461562935c583d7bf93828da4e20a6bc9b7301d/.
|
||||
// Found distributed online, but so far not in a game release. May be a final driver version never released with a game. TODO: Discover original source.
|
||||
// Can be found at https://github.com/ericwj/PsSecDrv/blob/master/tools/SECDRV/SECDRV.sys, and the file is confirmed to be distributed officially by Microsoft: https://www.virustotal.com/gui/file/34bbb0459c96b3de94ccb0d73461562935c583d7bf93828da4e20a6bc9b7301d/.
|
||||
23_040 => "4.03.086 / Product Unknown",
|
||||
|
||||
// Found in https://web.archive.org/web/20010417215205/http://www.macrovision.com:80/demos/Trialware.exe.
|
||||
@@ -405,6 +409,22 @@ namespace BinaryObjectScanner.Protection
|
||||
|
||||
// This file is not currently known to be used in versions past 4.70.000.
|
||||
_ => "/ Product Unknown (Report this to us on GitHub)",
|
||||
|
||||
// Hashes have not been found to be a reliable indicator for these files, and likely differ on a game-to-game basis. Some hashes were previously collected and are collected below:
|
||||
// Found in Redump entries 3569 and 3570.
|
||||
// "B64AD3EC82F2EB9FB854512CB59C25A771322181" => "1.11.000",
|
||||
// It is not known which games these files are from.
|
||||
// "EBF69B0A96ADFC903B7E486708474DC864CC0C7C" => "1.40.004",
|
||||
// "F68A1370660F8B94F896BBBA8DC6E47644D19092" => "2.30",
|
||||
// "60BC8C3222081BF76466C521474D63714AFD43CD" => "2.40",
|
||||
// "08CECA66432278D8C4E0F448436B77583C3C61C8" => "2.50",
|
||||
// "10080EB46BF76AC9CF9EA74372CFA4313727F0CA" => "2.51",
|
||||
// "832D359A6DE191C788B0E61E33F3D01F8D793D3C" => "2.70",
|
||||
// "AFCFAAC945A5B47712719A5E6A7EB69E36A5A6E0" or "CB24FBE8AA23A49E95F3C83FB15123FFB01F43F4" => "2.80",
|
||||
// "0383B69F98D0A9C0383C8130D52D6B431C79AC48" => "2.90",
|
||||
// "D7C9213CC78FF57F2F655B050C4D5AC065661AA9" => "3.20",
|
||||
// "FC6FEDACC21A7244975B8F410FF8673285374CC2" => "4.00.002",// Also 4.60.000, might be a fluke
|
||||
// "2D9F54F35F5BACB8959EF3AFFDC3E4209A4629CB" => "1-4",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -427,8 +447,9 @@ namespace BinaryObjectScanner.Protection
|
||||
"3.18.000" => "3.18.000 / SafeDisc 2.90.010-2.90.040",
|
||||
|
||||
// Found in Redump entries 13230, 15383, and 36511.
|
||||
// SafeDisc 4+ is known to sometimes use old versions of drivers, such as in Redump entry 101261.
|
||||
// The product version is "3.19.000 Windows NT/2K/XP 2003/03/19".
|
||||
"3.19.000" => "3.19.000 / SafeDisc 3.10.020-3.15.011",
|
||||
"3.19.000" => "3.19.000 / SafeDisc 3.10.020-3.15.011/4+",
|
||||
|
||||
// Found in Redump entries 58625 and 84586.
|
||||
// The product version is "SECURITY Driver 3.22.000 2004/01/16".
|
||||
|
||||
@@ -8,6 +8,7 @@ using SabreTools.Serialization.Wrappers;
|
||||
namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
// This protection was called VOB ProtectCD / ProtectDVD in versions prior to 6
|
||||
// ProtectDISC 9/10 checks for the presence of CSS on the disc to run, but don't encrypt any sectors or check for keys. Confirmed in Redump entries 78367 and 110095.
|
||||
public class ProtectDISC : IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Concurrent;
|
||||
#endif
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -15,16 +16,122 @@ namespace BinaryObjectScanner.Protection
|
||||
/// Rainbow Sentinel SuperPro: https://www.rainbow.com.my/superpro.php
|
||||
/// TODO: Investigate other versions/products.
|
||||
/// TODO: See if this is at all related to https://cpl.thalesgroup.com/software-monetization/all-products/sentinel-hl.
|
||||
/// TODO: Investigate the possible integration between FlexLM and Rainbow Sentinel in IA item "prog-17_202403".
|
||||
/// TODO: Investigate the "NetSentinel Protection System" found in "NSRVOM.EXE" and "NSRVGX.EXE" in IA item "czchip199707cd".
|
||||
/// TODO: Investigate "sntnlusb.sys" (https://www.rainbow.com.my/document/endusertroubleshooting.pdf).
|
||||
///
|
||||
/// Versions:
|
||||
/// Rainbow Sentinel PD-5.1: IA items "pcwkcd-1296" and "CHIPTRMart97".
|
||||
/// Rainbow Sentinel PD-5.1e (Beta): IA item "CHIPTRMart97".
|
||||
/// Rainbow Sentinel PD-5.39: IA item "chip-cds-2001-08".
|
||||
/// Rainbow Sentinel PD-15: IA items "ASMEsMechanicalEngineeringToolkit1997December" and "aplicaciones-windows".
|
||||
/// Rainbow Sentinel PD-17: IA item "czchip199707cd".
|
||||
/// Rainbow Sentinel PD-30: BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and IA item "auto-cad-r14-cdrom".
|
||||
/// Rainbow Sentinel PD-31: BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and IA item "auto-cad-r14-cdrom".
|
||||
///
|
||||
/// Rainbow Sentinel SuperPro 5.0: IA items "chip-cds-2001-08".
|
||||
/// Rainbow Sentinel SuperPro 5.1: IA items "ASMEsMechanicalEngineeringToolkit1997December" and "aplicaciones-windows".
|
||||
///
|
||||
/// Rainbow SentinelPro 5.1: IA item "pcwkcd-1296".
|
||||
///
|
||||
/// Rainbow NetSentinel: IA item "czchip199707cd".
|
||||
/// </summary>
|
||||
public class RainbowSentinel : IPathCheck, IPortableExecutableCheck
|
||||
public class RainbowSentinel : IPathCheck, INewExecutableCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
// TODO: Don't read entire file
|
||||
var data = nex.ReadArbitraryRange();
|
||||
if (data == null)
|
||||
return null;
|
||||
|
||||
// TODO: Figure out what NE section this lives in
|
||||
var neMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
// SentinelPro Windows Driver DLL
|
||||
// Found in "SSWIN.dll" in IA item "pcwkcd-1296".
|
||||
new(new byte?[]
|
||||
{
|
||||
0x53, 0x65, 0x6E, 0x74, 0x69, 0x6E, 0x65, 0x6C,
|
||||
0x50, 0x72, 0x6F, 0x20, 0x57, 0x69, 0x6E, 0x64,
|
||||
0x6F, 0x77, 0x73, 0x20, 0x44, 0x72, 0x69, 0x76,
|
||||
0x65, 0x72, 0x20, 0x44, 0x4C, 0x4C
|
||||
}, "Rainbow SentinelPro"),
|
||||
|
||||
// Sentinel Device Driver Version <20>PD-5.17
|
||||
// Found in "SENTINEL.SYS" in IA item "czchip199707cd".
|
||||
new(new byte?[]
|
||||
{
|
||||
0x53, 0x65, 0x6E, 0x74, 0x69, 0x6E, 0x65, 0x6C,
|
||||
0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20,
|
||||
0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x20, 0x56,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x00,
|
||||
0x50, 0x44, 0x2D, 0x35, 0x2E, 0x31, 0x37
|
||||
}, "Rainbow Sentinel PD-5.17"),
|
||||
|
||||
// NetSentinel OS/2 security server
|
||||
// Found in "NSRVOM.EXE" in IA item "czchip199707cd".
|
||||
new(new byte?[]
|
||||
{
|
||||
0x4E, 0x65, 0x74, 0x53, 0x65, 0x6E, 0x74, 0x69,
|
||||
0x6E, 0x65, 0x6C, 0x20, 0x4F, 0x53, 0x2F, 0x32,
|
||||
0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72
|
||||
}, "Rainbow NetSentinel Server for OS/2"),
|
||||
|
||||
// NetSentinel Monitor
|
||||
// Found in "OS2MON.EXE" in IA item "czchip199707cd".
|
||||
new(new byte?[]
|
||||
{
|
||||
0x4E, 0x65, 0x74, 0x53, 0x65, 0x6E, 0x74, 0x69,
|
||||
0x6E, 0x65, 0x6C, 0x20, 0x20, 0x4D, 0x6F, 0x6E,
|
||||
0x69, 0x74, 0x6F, 0x72
|
||||
}, "Rainbow NetSentinel Monitor"),
|
||||
|
||||
// Sentinel Device Driver
|
||||
// Generic case to catch unknown versions.
|
||||
// TODO: Add version parsing for this check.
|
||||
new (new byte?[]
|
||||
{
|
||||
0x53, 0x65, 0x6E, 0x74, 0x69, 0x6E, 0x65, 0x6C,
|
||||
0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20,
|
||||
0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x20, 0x56,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x00,
|
||||
0x50, 0x44, 0x2D, 0x35, 0x2E, 0x31, 0x37
|
||||
}, "Rainbow Sentinel (Unknown Version - Please report this to us on GitHub)"),
|
||||
};
|
||||
|
||||
var match = MatchUtil.GetFirstMatch(file, data, neMatchSets, includeDebug);
|
||||
if (!string.IsNullOrEmpty(match))
|
||||
return match;
|
||||
|
||||
// Check the nonresident-name table
|
||||
// Found in "SSWIN.dll" in IA item "pcwkcd-1296".
|
||||
bool nonresidentNameTableEntries = nex.Model.NonResidentNameTable?
|
||||
.Select(nrnte => nrnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(nrnte.NameString))
|
||||
.Any(s => s.Contains("SentinelPro Windows Driver DLL")) ?? false;
|
||||
if (nonresidentNameTableEntries)
|
||||
return "Rainbow SentinelPro";
|
||||
|
||||
// Found in "INSTALL.EXE" in IA item "czchip199707cd".
|
||||
nonresidentNameTableEntries = nex.Model.NonResidentNameTable?
|
||||
.Select(nrnte => nrnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(nrnte.NameString))
|
||||
.Any(s => s.Contains("Rainbow Technologies Installation Program")) ?? false;
|
||||
if (nonresidentNameTableEntries)
|
||||
return "Rainbow Sentinel";
|
||||
|
||||
// Found in "WNCEDITD.EXE" and "WNCEDITO.EXE" in IA item "czchip199707cd".
|
||||
nonresidentNameTableEntries = nex.Model.NonResidentNameTable?
|
||||
.Select(nrnte => nrnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(nrnte.NameString))
|
||||
.Any(s => s.Contains("NetSentinel-C Editor for Windows")) ?? false;
|
||||
if (nonresidentNameTableEntries)
|
||||
return "NetSentinel-C Editor for Windows";
|
||||
|
||||
// TODO: Investigate "SentinelScribe Windows Driver DLL" found in "NKWIN.DLL" in IA item "czchip199707cd".
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
@@ -33,30 +140,6 @@ namespace BinaryObjectScanner.Protection
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "ADESKSYS.DLL"/"WINADMIN.EXE"/"WINQUERY.EXE" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]", folder "\netsetup\SUPPORT\IPX".
|
||||
if (strs.Any(s => s.Contains("Rainbow SentinelSuperPro")))
|
||||
return "Rainbow Sentinel SuperPro";
|
||||
}
|
||||
|
||||
// Get the .text section strings, if they exist
|
||||
strs = pex.GetFirstSectionStrings(".text");
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "ACLT.HWL" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]", folder "\aclt\DRV\W95LOCK".
|
||||
// Found in "ACAD.HWL" in BA entry "Autodesk AutoCAD r14 (1997)" and IA item "auto-cad-r14-cdrom".
|
||||
if (strs.Any(s => s.Contains("SENTINEL.VXD")))
|
||||
return "Rainbow Sentinel SuperPro";
|
||||
|
||||
// Found in "ADESKSYS.DLL" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]", folder "\netsetup\SUPPORT\IPX".
|
||||
// TODO: Investigate "Elan License Manager" mentioned here.
|
||||
if (strs.Any(s => s.Contains("Rainbow SentinelSuperPro")))
|
||||
return "Rainbow Sentinel SuperPro";
|
||||
}
|
||||
|
||||
// TODO: Figure out why resources for "RNBOVTMP.DLL", "SENTTEMP.DLL", "SNTI386.DLL", and "SX32W.DL_"/"SX32W.DLL" aren't getting read properly, causing checks for these files to not work.
|
||||
|
||||
var name = pex.FileDescription;
|
||||
@@ -81,6 +164,14 @@ namespace BinaryObjectScanner.Protection
|
||||
if (name?.Equals("Rainbow Technologies SentinelSuperPro WIN32 DLL", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Rainbow Sentinel SuperPro {pex.ProductVersion}";
|
||||
|
||||
// Found in "SP32W.DLL" in IA item "pcwkcd-1296".
|
||||
if (name?.Equals("Rainbow Technologies SentinelPro WIN32 DLL", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Rainbow SentinelPro {pex.ProductVersion}";
|
||||
|
||||
// Found in "NSRVGX.EXE" in IA item "czchip199707cd".
|
||||
if (name?.Equals("NetSentinel Server for WIN 32", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return "Rainbow NetSentinel Server for Win32";
|
||||
|
||||
name = pex.ProductName;
|
||||
|
||||
// Found in multiple files in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]", including "RNBOVTMP.DLL", "SENTTEMP.DLL", and "SNTI386.DLL".
|
||||
@@ -95,6 +186,93 @@ namespace BinaryObjectScanner.Protection
|
||||
if (name?.Equals("Rainbow Technologies SentinelSuperPro WIN32 DLL", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Rainbow Sentinel SuperPro {pex.ProductVersion}";
|
||||
|
||||
// Found in "SP32W.DLL" in IA item "pcwkcd-1296".
|
||||
if (name?.Equals("Rainbow Technologies SentinelPro WIN32 DLL", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Rainbow SentinelPro {pex.ProductVersion}";
|
||||
|
||||
// Found in "F481_SetupSysDriver.exe.B391C18A_6953_11D4_82CB_00D0B72E1DB9"/"SetupSysDriver.exe" in IA item "chip-cds-2001-08".
|
||||
if (name?.Equals("Sentinel System Driver", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Rainbow Sentinel {pex.ProductVersion}";
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "ADESKSYS.DLL"/"WINADMIN.EXE"/"WINQUERY.EXE" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]", folder "\netsetup\SUPPORT\IPX".
|
||||
if (strs.Any(s => s.Contains("Rainbow SentinelSuperPro")))
|
||||
return "Rainbow Sentinel SuperPro";
|
||||
|
||||
// Found in "SETUPAXP.EXE", "SETUPMPS.EXE", and "SETUPPPC.EXE" in IA item "czchip199707cd".
|
||||
if (strs.Any(s => s.Contains("Sentinel Driver Setup Program")))
|
||||
return "Rainbow Sentinel";
|
||||
}
|
||||
|
||||
// Get the .rdata section strings, if they exist
|
||||
strs = pex.GetFirstSectionStrings(".rdata");
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "SP32W.DLL" in IA item "pcwkcd-1296".
|
||||
if (strs.Any(s => s.Contains("SentinelPro WIN32 DLL")))
|
||||
return "Rainbow SentinelPro";
|
||||
|
||||
// Found in "NKWIN32.DLL" in IA item "czchip199707cd".
|
||||
if (strs.Any(s => s.Contains("NetSentinel-C Windows NT Driver DLL")))
|
||||
return "Rainbow NetSentinel-C Windows NT Driver";
|
||||
|
||||
// Found in "NSLMS32.DLL" in IA item "czchip199707cd".
|
||||
if (strs.Any(s => s.Contains("NetSentinel 32-Bit Windows DLL")))
|
||||
return "Rainbow NetSentinel Win32 Driver";
|
||||
|
||||
// Found in "W32EDITD.EXE" and "W32EDITO.EXE" in IA item "czchip199707cd".
|
||||
if (strs.Any(s => s.Contains("NetSentinel-C Editor for Windows")))
|
||||
return "NetSentinel-C Editor for Win32";
|
||||
|
||||
// Generic case to catch undetected versions.
|
||||
if (strs.Any(s => s.Contains("SentinelPro")))
|
||||
return "Rainbow SentinelPro (Unknown Version - Please report to us on GitHub)";
|
||||
}
|
||||
|
||||
// Get the .rsrc section strings, if they exist
|
||||
strs = pex.GetFirstSectionStrings(".rsrc");
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "WINMON.exe" in IA item "czchip199707cd".
|
||||
if (strs.Any(s => s.Contains("NetSentinel Monitor")))
|
||||
return "Rainbow NetSentinel Monitor";
|
||||
}
|
||||
|
||||
// Get the .text section strings, if they exist
|
||||
strs = pex.GetFirstSectionStrings(".text");
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "ACLT.HWL" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]", folder "\aclt\DRV\W95LOCK".
|
||||
// Found in "ACAD.HWL" in BA entry "Autodesk AutoCAD r14 (1997)" and IA item "auto-cad-r14-cdrom".
|
||||
if (strs.Any(s => s.Contains("\\\\.\\SENTINEL.VXD")))
|
||||
return "Rainbow Sentinel";
|
||||
|
||||
// Found in "ADESKSYS.DLL" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]", folder "\netsetup\SUPPORT\IPX".
|
||||
// TODO: Investigate "Elan License Manager" mentioned here.
|
||||
if (strs.Any(s => s.Contains("Rainbow SentinelSuperPro")))
|
||||
return "Rainbow Sentinel SuperPro";
|
||||
|
||||
// Found in "F1321_dorapro.exe" in IA item "chip-cds-2001-08".
|
||||
if (strs.Any(s => s.Contains("modSentinelSuperPro")))
|
||||
return "Rainbow Sentinel SuperPro";
|
||||
|
||||
// Found in "F1321_dorapro.exe" in IA item "chip-cds-2001-08".
|
||||
if (strs.Any(s => s.Contains("clsSentinelSuperPro")))
|
||||
return "Rainbow Sentinel SuperPro";
|
||||
|
||||
// Found in "SENTSTRT.EXE" in IA item "czchip199707cd".
|
||||
if (strs.Any(s => s.Contains("Sentinel Driver Startup Program")))
|
||||
return "Rainbow Sentinel";
|
||||
|
||||
// Found in "SETUPX86.EXE" in IA item "czchip199707cd".
|
||||
if (strs.Any(s => s.Contains("Sentinel Windows NT Driver Setup")))
|
||||
return "Rainbow Sentinel";
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -107,8 +285,11 @@ namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// The Parallel Port driver for Rainbow Sentinel on Win9x (https://www.rainbow.com.my/document/endusertroubleshooting.pdf).
|
||||
// Unfortunately, the file name overlaps with a file used by Clam Sentinel (https://clamsentinel.sourceforge.net/).
|
||||
// new(new FilePathMatch("SENTINEL.VXD"), "Rainbow Sentinel"),
|
||||
|
||||
// Found in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and IA item "auto-cad-r14-cdrom".
|
||||
new(new FilePathMatch("SENTINEL.VXD"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SENTSTRT.EXE"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SENTW95.DLL"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SENTW95.EXE"), "Rainbow Sentinel"),
|
||||
@@ -127,9 +308,69 @@ namespace BinaryObjectScanner.Protection
|
||||
new(new FilePathMatch("RAINBNT.Z"), "Rainbow Sentinel"),
|
||||
|
||||
// Found in "wd126.zip/WDSHARE.EXE" in IA item "ASMEsMechanicalEngineeringToolkit1997December" and "WDSHARE.ZIP/WDSHARE.EXE/SX32W.DL_" in IA item "aplicaciones-windows".
|
||||
new(new FilePathMatch("RainbowSentinel.386"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SX32W.DL_"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SX32W.DLL"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("RainbowSentinel.386"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SX32W.DL_"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SX32W.DLL"), "Rainbow Sentinel"),
|
||||
|
||||
// Found in IA item "pcwkcd-1296".
|
||||
new(new FilePathMatch("SP32W.DLL"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SSWIN.DLL"), "Rainbow Sentinel"),
|
||||
|
||||
// Found in IA item "czchip199707cd".
|
||||
new(new FilePathMatch("SENTINEL.DPP"), "Rainbow Sentinel OS/2 Installation Script"),
|
||||
new(new FilePathMatch("SENTDOS.SYS"), "Rainbow Sentinel DOS Driver"),
|
||||
new(new FilePathMatch("SENTINEL.386"), "Rainbow Sentinel Windows 3.1 Driver"),
|
||||
new(new FilePathMatch("SNTALPHA.DLL"), "Rainbow Sentinel Windows NT Alpha Platform Driver"),
|
||||
new(new FilePathMatch("SNTI386.DLL"), "Rainbow Sentinel Windows NT Intel Platform Driver"),
|
||||
new(new FilePathMatch("SNTMIPS.DLL"), "Rainbow Sentinel Windows NT MIPS Platform Driver"),
|
||||
new(new FilePathMatch("SNTPPC.DLL"), "Rainbow Sentinel Windows NT PowerPC Platform Driver"),
|
||||
new(new FilePathMatch("NSRVDI.EXE"), "Rainbow NetSentinel Server for DOS"),
|
||||
new(new FilePathMatch("NSRVDN.EXE"), "Rainbow NetSentinel Server for DOS"),
|
||||
new(new FilePathMatch("NSRVNI.NLM"), "Rainbow NetSentinel Server for Novell NetWare"),
|
||||
new(new FilePathMatch("NSRVOM.EXE"), "Rainbow NetSentinel Server for OS/2"),
|
||||
new(new FilePathMatch("NSRVGX.EXE"), "Rainbow NetSentinel Server for Win32"),
|
||||
|
||||
// Found in IA item "czchip199707cd".
|
||||
new(new List<PathMatch>
|
||||
{
|
||||
new FilePathMatch("DOSMON.EXE"),
|
||||
new FilePathMatch("FIND.EXE"),
|
||||
new FilePathMatch("NCEDIT.EXE"),
|
||||
new FilePathMatch("NETEVAL.EXE"),
|
||||
}, "Rainbow NetSentinel Monitor for DOS"),
|
||||
|
||||
// Found in IA item "czchip199707cd".
|
||||
new(new List<PathMatch>
|
||||
{
|
||||
new FilePathMatch("OS2MON.EXE"),
|
||||
new FilePathMatch("RHPANELP.DLL"),
|
||||
}, "Rainbow NetSentinel Monitor for OS/2"),
|
||||
|
||||
// Found in IA item "czchip199707cd".
|
||||
new(new List<PathMatch>
|
||||
{
|
||||
new FilePathMatch("MAPFILE.TXT"),
|
||||
new FilePathMatch("NKWIN32.DLL"),
|
||||
new FilePathMatch("NSLMS32.DLL"),
|
||||
new FilePathMatch("W32EDITD.EXE"),
|
||||
new FilePathMatch("W32EDITO.EXE"),
|
||||
new FilePathMatch("WINMON.DOC"),
|
||||
new FilePathMatch("WINMON.EXE"),
|
||||
new FilePathMatch("WINMON.HLP"),
|
||||
new FilePathMatch("WMON_DOC.EXE"),
|
||||
}, "Rainbow NetSentinel Monitor for Win32"),
|
||||
|
||||
// Found in IA item "chip-cds-2001-08".
|
||||
// File names for Rainbow Sentinel files sometimes found in ".cab" files.
|
||||
new(new FilePathMatch("F194_rnbovdd.dll.B391C188_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F195_sentinel.sys.B391C188_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F225_sentinel.hlp.B391C18A_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F227_snti386.dll.B391C18A_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F288_sentinel.vxd.B391C188_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F317_sentstrt.exe.B391C188_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F344_sentw9x.hlp.B391C18A_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F481_SetupSysDriver.exe.B391C18A_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F766_SentinelDriverInstall_Start.htm.B391C18A_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -140,8 +381,12 @@ namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// The Parallel Port driver for Rainbow Sentinel (https://www.rainbow.com.my/document/endusertroubleshooting.pdf).
|
||||
// Unforutnately, the file name overlaps with a file used by Clam Sentinel (https://clamsentinel.sourceforge.net/).
|
||||
// TODO: Add LE check for "SENTINEL.VXD" once LE checks are implemented.
|
||||
// new(new FilePathMatch("SENTINEL.VXD"), "Rainbow Sentinel"),
|
||||
|
||||
// Found in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and IA item "auto-cad-r14-cdrom".
|
||||
new(new FilePathMatch("SENTINEL.VXD"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SENTSTRT.EXE"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SENTW95.DLL"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SENTW95.EXE"), "Rainbow Sentinel"),
|
||||
@@ -163,6 +408,31 @@ namespace BinaryObjectScanner.Protection
|
||||
new(new FilePathMatch("RainbowSentinel.386"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SX32W.DL_"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SX32W.DLL"), "Rainbow Sentinel"),
|
||||
|
||||
// Found in IA item "pcwkcd-1296".
|
||||
new(new FilePathMatch("SP32W.DLL"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("SSWIN.DLL"), "Rainbow Sentinel"),
|
||||
|
||||
// Found in IA item "czchip199707cd".
|
||||
new(new FilePathMatch("SENTINEL.DPP"), "Rainbow Sentinel OS/2 Installation Script"),
|
||||
new(new FilePathMatch("SENTDOS.SYS"), "Rainbow Sentinel DOS Driver"),
|
||||
new(new FilePathMatch("SENTINEL.386"), "Rainbow Sentinel Windows 3.1 Driver"),
|
||||
new(new FilePathMatch("SNTALPHA.DLL"), "Rainbow Sentinel Windows NT Alpha Platform Driver"),
|
||||
new(new FilePathMatch("SNTI386.DLL"), "Rainbow Sentinel Windows NT Intel Platform Driver"),
|
||||
new(new FilePathMatch("SNTMIPS.DLL"), "Rainbow Sentinel Windows NT MIPS Platform Driver"),
|
||||
new(new FilePathMatch("SNTPPC.DLL"), "Rainbow Sentinel Windows NT PowerPC Platform Driver"),
|
||||
|
||||
// Found in IA item "chip-cds-2001-08".
|
||||
// File names for Rainbow Sentinel files sometimes found in ".cab" files.
|
||||
new(new FilePathMatch("F194_rnbovdd.dll.B391C188_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F195_sentinel.sys.B391C188_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F225_sentinel.hlp.B391C18A_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F227_snti386.dll.B391C18A_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F288_sentinel.vxd.B391C188_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F317_sentstrt.exe.B391C188_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F344_sentw9x.hlp.B391C18A_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F481_SetupSysDriver.exe.B391C18A_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
new(new FilePathMatch("F766_SentinelDriverInstall_Start.htm.B391C18A_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
83
BinaryObjectScanner/Protection/Roxxe.cs
Normal file
83
BinaryObjectScanner/Protection/Roxxe.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Collections.Concurrent;
|
||||
#endif
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Protection
|
||||
{
|
||||
/// <summary>
|
||||
/// Roxxe was a Czech DRM. It appears to have been a simple disc check that also relied on unusual disc manufacturing and dummy files to attempt to prevent copying.
|
||||
///
|
||||
/// DRML: https://github.com/TheRogueArchivist/DRML/blob/main/entries/Roxxe/Roxxe.md
|
||||
/// </summary>
|
||||
public class Roxxe : IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? CheckPortableExecutable(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 code/CODE section strings, if they exist
|
||||
var strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE");
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "Owar.exe" in IA item "game4u-22-cd".
|
||||
if (strs.Any(s => s.Contains("TRCHANGER.INI")))
|
||||
return "Roxxe";
|
||||
}
|
||||
|
||||
// Get the .rsrc section strings, if they exist
|
||||
// TODO: Check for these strings specifically within the application-defined resource that they're found in, not just the generic resource section.
|
||||
strs = pex.GetFirstSectionStrings(".rsrc");
|
||||
if (strs != null)
|
||||
{
|
||||
// Found in "Owar.exe" in IA items "game4u-22-cd" and "original-war".
|
||||
// These checks are less reliable, as they are still found in a version of the game that appears to have patched out Roxxe (the version present in IA item "original-war").
|
||||
if (strs.Any(s => s.Contains("PRRT01")))
|
||||
return "Roxxe (Possibly remnants)";
|
||||
|
||||
if (strs.Any(s => s.Contains("CommonPRRT")))
|
||||
return "Roxxe (Possibly remnants)";
|
||||
|
||||
if (strs.Any(s => s.Contains("roxe")))
|
||||
return "Roxxe (Possibly remnants)";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
#if NET20 || NET35
|
||||
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
#else
|
||||
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
|
||||
#endif
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Files such as "TRCHANGER.INI" may be present, but haven't been found yet.
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? CheckFilePath(string path)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Files such as "TRCHANGER.INI" may be present, but haven't been found yet.
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,7 +266,7 @@ namespace BinaryObjectScanner
|
||||
// Open the file and begin scanning
|
||||
try
|
||||
{
|
||||
using FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return GetInternalProtections(file, fs);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -457,7 +457,7 @@ namespace BinaryObjectScanner
|
||||
AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, stream);
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, mz);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
}
|
||||
@@ -471,7 +471,7 @@ namespace BinaryObjectScanner
|
||||
AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, stream);
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, lex);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
}
|
||||
@@ -485,7 +485,7 @@ namespace BinaryObjectScanner
|
||||
AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, stream);
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, nex);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
}
|
||||
@@ -499,7 +499,7 @@ namespace BinaryObjectScanner
|
||||
AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, stream);
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, pex);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
}
|
||||
@@ -512,12 +512,12 @@ namespace BinaryObjectScanner
|
||||
/// </summary>
|
||||
/// <param name="classes">Set of classes returned from Exectuable scans</param>
|
||||
/// <param name="fileName">Name of the source file of the stream, for tracking</param>
|
||||
/// <param name="stream">Stream to scan the contents of</param>
|
||||
/// <param name="mz">MSDOS to scan the contents of</param>
|
||||
/// <returns>Set of protections found from extraction, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, Stream stream)
|
||||
private Dictionary<string, Queue<string>>? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, MSDOS mz)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, Stream stream)
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, MSDOS mz)
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid set of classes
|
||||
@@ -532,7 +532,7 @@ namespace BinaryObjectScanner
|
||||
#endif
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractables = classes.Where(c => c is IExtractable).Select(c => c as IExtractable);
|
||||
var extractables = classes.Where(c => c is IExtractableMSDOSExecutable).Select(c => c as IExtractableMSDOSExecutable);
|
||||
#if NET20 || NET35
|
||||
foreach (var extractable in extractables)
|
||||
#else
|
||||
@@ -548,7 +548,166 @@ namespace BinaryObjectScanner
|
||||
#endif
|
||||
|
||||
// Get the protection for the class, if possible
|
||||
var extractedProtections = Handler.HandleExtractable(extractable, fileName, stream, this);
|
||||
var extractedProtections = Handler.HandleExtractable(extractable, fileName, mz, this);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
#if NET20 || NET35
|
||||
}
|
||||
#else
|
||||
});
|
||||
#endif
|
||||
|
||||
return protections;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle extractable protections, such as executable packers
|
||||
/// </summary>
|
||||
/// <param name="classes">Set of classes returned from Exectuable scans</param>
|
||||
/// <param name="fileName">Name of the source file of the stream, for tracking</param>
|
||||
/// <param name="lex">LinearExecutable to scan the contents of</param>
|
||||
/// <returns>Set of protections found from extraction, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, LinearExecutable lex)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, LinearExecutable lex)
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid set of classes
|
||||
if (classes == null || !classes.Any())
|
||||
return null;
|
||||
|
||||
// Create the output dictionary
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractables = classes.Where(c => c is IExtractableLinearExecutable).Select(c => c as IExtractableLinearExecutable);
|
||||
#if NET20 || NET35
|
||||
foreach (var extractable in extractables)
|
||||
#else
|
||||
Parallel.ForEach(extractables, extractable =>
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid extractable somehow
|
||||
if (extractable == null)
|
||||
#if NET20 || NET35
|
||||
continue;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Get the protection for the class, if possible
|
||||
var extractedProtections = Handler.HandleExtractable(extractable, fileName, lex, this);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
#if NET20 || NET35
|
||||
}
|
||||
#else
|
||||
});
|
||||
#endif
|
||||
|
||||
return protections;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle extractable protections, such as executable packers
|
||||
/// </summary>
|
||||
/// <param name="classes">Set of classes returned from Exectuable scans</param>
|
||||
/// <param name="fileName">Name of the source file of the stream, for tracking</param>
|
||||
/// <param name="nex">NewExecutable to scan the contents of</param>
|
||||
/// <returns>Set of protections found from extraction, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, NewExecutable nex)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, NewExecutable nex)
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid set of classes
|
||||
if (classes == null || !classes.Any())
|
||||
return null;
|
||||
|
||||
// Create the output dictionary
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractables = classes.Where(c => c is IExtractableNewExecutable).Select(c => c as IExtractableNewExecutable);
|
||||
#if NET20 || NET35
|
||||
foreach (var extractable in extractables)
|
||||
#else
|
||||
Parallel.ForEach(extractables, extractable =>
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid extractable somehow
|
||||
if (extractable == null)
|
||||
#if NET20 || NET35
|
||||
continue;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Get the protection for the class, if possible
|
||||
var extractedProtections = Handler.HandleExtractable(extractable, fileName, nex, this);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
#if NET20 || NET35
|
||||
}
|
||||
#else
|
||||
});
|
||||
#endif
|
||||
|
||||
return protections;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle extractable protections, such as executable packers
|
||||
/// </summary>
|
||||
/// <param name="classes">Set of classes returned from Exectuable scans</param>
|
||||
/// <param name="fileName">Name of the source file of the stream, for tracking</param>
|
||||
/// <param name="pex">PortableExecutable to scan the contents of</param>
|
||||
/// <returns>Set of protections found from extraction, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, PortableExecutable pex)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, PortableExecutable pex)
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid set of classes
|
||||
if (classes == null || !classes.Any())
|
||||
return null;
|
||||
|
||||
// Create the output dictionary
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractables = classes.Where(c => c is IExtractablePortableExecutable).Select(c => c as IExtractablePortableExecutable);
|
||||
#if NET20 || NET35
|
||||
foreach (var extractable in extractables)
|
||||
#else
|
||||
Parallel.ForEach(extractables, extractable =>
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid extractable somehow
|
||||
if (extractable == null)
|
||||
#if NET20 || NET35
|
||||
continue;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Get the protection for the class, if possible
|
||||
var extractedProtections = Handler.HandleExtractable(extractable, fileName, pex, this);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
#if NET20 || NET35
|
||||
|
||||
@@ -60,7 +60,8 @@ namespace BinaryObjectScanner.Utilities
|
||||
|
||||
// Add the key if needed and then append the lists
|
||||
#if NET20 || NET35
|
||||
original[key] ??= new Queue<string>();
|
||||
if (!original.ContainsKey(key))
|
||||
original[key] = new Queue<string>();
|
||||
#else
|
||||
original.TryAdd(key, new ConcurrentQueue<string>());
|
||||
#endif
|
||||
@@ -88,7 +89,8 @@ namespace BinaryObjectScanner.Utilities
|
||||
|
||||
// Add the key if needed and then append the lists
|
||||
#if NET20 || NET35
|
||||
original[key] ??= new Queue<string>();
|
||||
if (!original.ContainsKey(key))
|
||||
original[key] = new Queue<string>();
|
||||
#else
|
||||
original.TryAdd(key, new ConcurrentQueue<string>());
|
||||
#endif
|
||||
@@ -114,7 +116,8 @@ namespace BinaryObjectScanner.Utilities
|
||||
foreach (string key in addition.Keys)
|
||||
{
|
||||
#if NET20 || NET35
|
||||
original[key] ??= new Queue<string>();
|
||||
if (!original.ContainsKey(key))
|
||||
original[key] = new Queue<string>();
|
||||
#else
|
||||
original.TryAdd(key, new ConcurrentQueue<string>());
|
||||
#endif
|
||||
|
||||
@@ -319,6 +319,11 @@ namespace BinaryObjectScanner.Utilities
|
||||
if (magic.StartsWith(new byte?[] { 0x3F, 0x5F, 0x03, 0x00 }))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// XML
|
||||
// "<?xml"
|
||||
if (magic.StartsWith(new byte?[] { 0x3C, 0x3F, 0x78, 0x6D, 0x6C }))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
#endregion
|
||||
|
||||
#region VBSP
|
||||
@@ -720,6 +725,10 @@ namespace BinaryObjectScanner.Utilities
|
||||
if (extension.Equals("doc", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Property list
|
||||
if (extension.Equals("plist", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Rich Text File
|
||||
if (extension.Equals("rtf", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
@@ -732,10 +741,16 @@ namespace BinaryObjectScanner.Utilities
|
||||
if (extension.Equals("hlp", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// WZC
|
||||
if (extension.Equals("wzc", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// XML
|
||||
if (extension.Equals("xml", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region VBSP
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace BinaryObjectScanner.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Data hashing methods
|
||||
/// </summary>
|
||||
public static class Hashing
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the SHA1 hash of a file, if possible
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file to be hashed</param>
|
||||
/// <returns>SHA1 hash as a string on success, null on error</returns>
|
||||
public static string? GetFileSHA1(string? path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
var sha1 = SHA1.Create();
|
||||
using (Stream fileStream = File.OpenRead(path))
|
||||
{
|
||||
byte[] buffer = new byte[32768];
|
||||
while (true)
|
||||
{
|
||||
int bytesRead = fileStream.Read(buffer, 0, 32768);
|
||||
if (bytesRead == 32768)
|
||||
{
|
||||
sha1.TransformBlock(buffer, 0, bytesRead, null, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
sha1.TransformFinalBlock(buffer, 0, bytesRead);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string hash = BitConverter.ToString(sha1.Hash!);
|
||||
hash = hash.Replace("-", string.Empty);
|
||||
return hash;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
BinaryObjectScanner/_EXTERNAL/LessIO
Submodule
1
BinaryObjectScanner/_EXTERNAL/LessIO
Submodule
Submodule BinaryObjectScanner/_EXTERNAL/LessIO added at 3dcf2c147b
@@ -4,4 +4,6 @@ This directory contains multiple external libraries. Here is the status of each:
|
||||
|
||||
| Directory | Library | Status |
|
||||
| --------- | ------- | ------ |
|
||||
| stormlibsharp | [stormlibsharp](https://github.com/robpaveza/stormlibsharp) | External submodule |
|
||||
| LessIO | [LessIO](https://github.com/activescott/LessIO) | External submodule |
|
||||
| libmspack4n | [libmspack4n](https://github.com/activescott/libmspack4n) | External submodule |
|
||||
| stormlibsharp | [stormlibsharp](https://github.com/robpaveza/stormlibsharp) | External submodule |
|
||||
|
||||
1
BinaryObjectScanner/_EXTERNAL/libmspack4n
Submodule
1
BinaryObjectScanner/_EXTERNAL/libmspack4n
Submodule
Submodule BinaryObjectScanner/_EXTERNAL/libmspack4n added at 7213a361f8
BIN
BinaryObjectScanner/mspack.dll
Normal file
BIN
BinaryObjectScanner/mspack.dll
Normal file
Binary file not shown.
16
README.md
16
README.md
@@ -1,15 +1,18 @@
|
||||
# BinaryObjectScanner
|
||||
# Binary Object Scanner
|
||||
|
||||
[](https://ci.appveyor.com/project/mnadareski/BinaryObjectScanner)
|
||||
[](https://github.com/SabreTools/BinaryObjectScanner/actions/workflows/build_test.yml)
|
||||
[](https://github.com/SabreTools/BinaryObjectScanner/actions/workflows/build_nupkg.yml)
|
||||
|
||||
C# protection, packer, and archive scanning library. This currently compiles as a library so it can be used in any C# application. A reference application called `Test` is also included to demonstrate the abilities of the library. For an example of a program implementing the library, see [MPF](https://github.com/SabreTools/MPF).
|
||||
|
||||
The following libraries (or ports thereof) are used for file handling:
|
||||
The following non-project libraries (or ports thereof) are used for file handling:
|
||||
|
||||
- [LessIO](https://github.com/activescott/LessIO) - Used by libmspack4n for IO handling
|
||||
- [libmspack4n](https://github.com/activescott/libmspack4n) MS-CAB extraction [Unused in .NET Frawework 2.0/3.5/4.0 and non-Windows builds due to Windows-specific libraries]
|
||||
- [openmcdf](https://github.com/ironfede/openmcdf) - MSI extraction
|
||||
- [SharpCompress](https://github.com/adamhathcock/sharpcompress) - Common archive format extraction
|
||||
- [SharpZipLib](https://github.com/icsharpcode/SharpZipLib) - zlib-based extraction
|
||||
- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in .NET 6, .NET 7, or .NET 8 builds due to Windows-specific libraries]
|
||||
- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in .NET Frawework 2.0/3.5/4.0 and non-Windows builds due to Windows-specific libraries]
|
||||
- [UnshieldSharp](https://github.com/mnadareski/UnshieldSharp) - InstallShield CAB extraction
|
||||
- [WiseUnpacker](https://github.com/mnadareski/WiseUnpacker) - Wise Installer extraction
|
||||
|
||||
@@ -47,9 +50,9 @@ Below is a list of protections detected by BinaryObjectScanner. The two columns
|
||||
| CDSHiELD SE | True | False | |
|
||||
| Cenga ProtectDVD | True | True | |
|
||||
| ChosenBytes CodeLock | True | True | Partially unconfirmed² |
|
||||
| CopyKiller | True | True | Unconfirmed¹ |
|
||||
| CopyKiller | True | True | |
|
||||
| CopyLok/CodeLok | True | False | |
|
||||
| CrypKey | True | False | |
|
||||
| CrypKey | True | True | |
|
||||
| Cucko (EA Custom) | True | False | Does not detect all known cases |
|
||||
| Denuvo Anti-Cheat/Anti-Tamper| True | True | |
|
||||
| DigiGuard | True | True | |
|
||||
@@ -91,6 +94,7 @@ Below is a list of protections detected by BinaryObjectScanner. The two columns
|
||||
| Rainbow Sentinel | True | True | |
|
||||
| Ring PROTECH / ProRing | True | True | Partially unconfirmed² |
|
||||
| RipGuard | True | True | Partially unconfirmed² |
|
||||
| Roxxe | True | False | |
|
||||
| SafeDisc / SafeCast | True | True | Can't distinguish between some versions of SafeDisc and SafeCast |
|
||||
| SafeLock | False | True | |
|
||||
| SecuROM | True | True | v8.x and White Label detected partially² |
|
||||
|
||||
@@ -19,10 +19,8 @@ using SharpCompress.Compressors;
|
||||
using SharpCompress.Compressors.BZip2;
|
||||
using SharpCompress.Compressors.Xz;
|
||||
#endif
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using UnshieldSharp.Archive;
|
||||
using UnshieldSharp.Cabinet;
|
||||
#endif
|
||||
|
||||
namespace Test
|
||||
{
|
||||
@@ -65,7 +63,7 @@ namespace Test
|
||||
private static void ExtractFile(string file, string outputDirectory)
|
||||
{
|
||||
Console.WriteLine($"Attempting to extract all files from {file}");
|
||||
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
|
||||
// Read the first 8 bytes
|
||||
byte[]? magic = stream.ReadBytes(8);
|
||||
@@ -320,7 +318,6 @@ namespace Test
|
||||
Console.WriteLine("Extracting InstallShield Archive V3 contents");
|
||||
Console.WriteLine();
|
||||
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
// If the cab file itself fails
|
||||
try
|
||||
{
|
||||
@@ -357,7 +354,6 @@ namespace Test
|
||||
Console.WriteLine($"Something went wrong extracting InstallShield Archive V3: {ex}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// IS-CAB archive
|
||||
@@ -367,10 +363,6 @@ namespace Test
|
||||
Console.WriteLine("Extracting IS-CAB contents");
|
||||
Console.WriteLine();
|
||||
|
||||
#if NET20 || NET35 || NET40
|
||||
Console.WriteLine("Extraction is not supported for this framework!");
|
||||
Console.WriteLine();
|
||||
#else
|
||||
// If the cab file itself fails
|
||||
try
|
||||
{
|
||||
@@ -405,9 +397,9 @@ namespace Test
|
||||
Console.WriteLine($"Something went wrong extracting IS-CAB: {ex}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
|
||||
// Microsoft Cabinet archive
|
||||
else if (ft == SupportedFileType.MicrosoftCAB)
|
||||
{
|
||||
@@ -415,7 +407,7 @@ namespace Test
|
||||
Console.WriteLine("Extracting MS-CAB contents");
|
||||
Console.WriteLine();
|
||||
|
||||
var cabinet = MicrosoftCabinet.Create(stream);
|
||||
var cabinet = new LibMSPackN.MSCabinet(file);
|
||||
if (cabinet == null)
|
||||
{
|
||||
Console.WriteLine("Something went wrong parsing MS-CAB archive");
|
||||
@@ -425,7 +417,24 @@ namespace Test
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine("MS-CAB extraction is disabled");
|
||||
// Extract the MS-CAB contents to the directory
|
||||
foreach (var compressedFile in cabinet.GetFiles())
|
||||
{
|
||||
try
|
||||
{
|
||||
string tempFile = Path.Combine(outputDirectory, compressedFile.Filename);
|
||||
string? directoryName = Path.GetDirectoryName(tempFile);
|
||||
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
|
||||
Directory.CreateDirectory(directoryName);
|
||||
|
||||
compressedFile.ExtractTo(tempFile);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Something went wrong extracting Microsoft Cabinet entry {compressedFile.Filename}: {ex}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -433,6 +442,7 @@ namespace Test
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Microsoft LZ / LZ32
|
||||
else if (ft == SupportedFileType.MicrosoftLZ)
|
||||
@@ -474,7 +484,7 @@ namespace Test
|
||||
}
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK && !NET20 && !NET35 && !NET40
|
||||
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
|
||||
// MoPaQ (MPQ) archive
|
||||
else if (ft == SupportedFileType.MPQ)
|
||||
{
|
||||
@@ -514,7 +524,10 @@ namespace Test
|
||||
try
|
||||
{
|
||||
string tempFile = Path.Combine(outputDirectory, sub);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
|
||||
string? directoryName = Path.GetDirectoryName(tempFile);
|
||||
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
|
||||
Directory.CreateDirectory(directoryName);
|
||||
|
||||
mpqArchive.ExtractFile(sub, tempFile);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace Test
|
||||
#if NET6_0_OR_GREATER
|
||||
options.Json = true;
|
||||
#else
|
||||
Console.WriteLine("JSON output not available in .NET Framework 4.8");
|
||||
Console.WriteLine("JSON output not available in .NET Framework");
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Test
|
||||
{
|
||||
Console.WriteLine($"Attempting to print info for {file}");
|
||||
|
||||
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
|
||||
// Read the first 8 bytes
|
||||
byte[]? magic = stream.ReadBytes(8);
|
||||
|
||||
@@ -2,32 +2,38 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<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;osx-arm64</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
<OutputType>Exe</OutputType>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Set a build flag for Windows specifically -->
|
||||
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x86'">
|
||||
<DefineConstants>$(DefineConstants);WIN</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BinaryObjectScanner\BinaryObjectScanner.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Support for old .NET versions -->
|
||||
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`))">
|
||||
<PackageReference Include="OpenMcdf" Version="2.3.0" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.7.1" />
|
||||
<PackageReference Include="OpenMcdf" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.3.0" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.3.0" />
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.3.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.3.0" />
|
||||
<PackageReference Include="SabreTools.Printing" Version="1.3.0" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.3.0" />
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.4.1" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.3.3" />
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.3.1" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.1" />
|
||||
<PackageReference Include="SabreTools.Printing" Version="1.3.4" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.4.3" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.7.4" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
45
appveyor.yml
45
appveyor.yml
@@ -1,5 +1,5 @@
|
||||
# version format
|
||||
version: 3.0.0-{build}
|
||||
version: 3.1.0-{build}
|
||||
|
||||
# pull request template
|
||||
pull_requests:
|
||||
@@ -15,35 +15,7 @@ install:
|
||||
|
||||
# build step
|
||||
build_script:
|
||||
- dotnet restore
|
||||
|
||||
# Debug
|
||||
- dotnet publish Test\Test.csproj -f net6.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
- dotnet publish Test\Test.csproj -f net6.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
- dotnet publish Test\Test.csproj -f net6.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
- dotnet publish Test\Test.csproj -f net8.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
- dotnet publish Test\Test.csproj -f net8.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
- dotnet publish Test\Test.csproj -f net8.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
|
||||
# Release
|
||||
- dotnet publish Test\Test.csproj -f net6.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
|
||||
- dotnet publish Test\Test.csproj -f net6.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
|
||||
- dotnet publish Test\Test.csproj -f net6.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
|
||||
- dotnet publish Test\Test.csproj -f net8.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
|
||||
- dotnet publish Test\Test.csproj -f net8.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
|
||||
- dotnet publish Test\Test.csproj -f net8.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
|
||||
|
||||
# Nuget Package
|
||||
- dotnet pack BinaryObjectScanner\BinaryObjectScanner.csproj --output %APPVEYOR_BUILD_FOLDER%
|
||||
|
||||
# post-build script
|
||||
after_build:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\Test\bin\Debug\net8.0\win-x64\publish\
|
||||
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_win-x64.zip *
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\Test\bin\Debug\net8.0\linux-x64\publish\
|
||||
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_linux-x64.zip *
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\Test\bin\Debug\net8.0\osx-x64\publish\
|
||||
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_osx-x64.zip *
|
||||
- dotnet build
|
||||
|
||||
# success/failure tracking
|
||||
on_success:
|
||||
@@ -51,15 +23,4 @@ on_success:
|
||||
- ps: ./send.ps1 success $env:WEBHOOK_URL
|
||||
on_failure:
|
||||
- ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
|
||||
- ps: ./send.ps1 failure $env:WEBHOOK_URL
|
||||
|
||||
# artifact linking
|
||||
artifacts:
|
||||
- path: BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_win-x64.zip
|
||||
name: BinaryObjectScanner (.NET 8.0, Windows x64)
|
||||
- path: BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_linux-x64.zip
|
||||
name: BinaryObjectScanner (.NET 8.0, Linux x64)
|
||||
- path: BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_osx-x64.zip
|
||||
name: BinaryObjectScanner (.NET 8.0, OSX x64)
|
||||
- path: '*.nupkg'
|
||||
name: Nuget Packages
|
||||
- ps: ./send.ps1 failure $env:WEBHOOK_URL
|
||||
158
publish-nix.sh
158
publish-nix.sh
@@ -3,67 +3,123 @@
|
||||
# This batch file assumes the following:
|
||||
# - .NET 8.0 (or newer) SDK is installed and in PATH
|
||||
# - zip is installed and in PATH
|
||||
# - The relevant commandline programs are already downloaded
|
||||
# and put into their respective folders
|
||||
# - Git is installed and in PATH
|
||||
#
|
||||
# If any of these are not satisfied, the operation may fail
|
||||
# in an unpredictable way and result in an incomplete output.
|
||||
|
||||
# Optional parameters
|
||||
USE_ALL=false
|
||||
NO_BUILD=false
|
||||
NO_ARCHIVE=false
|
||||
while getopts "uba" OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
u)
|
||||
USE_ALL=true
|
||||
;;
|
||||
b)
|
||||
NO_BUILD=true
|
||||
;;
|
||||
a)
|
||||
NO_ARCHIVE=true
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option provided"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Set the current directory as a variable
|
||||
BUILD_FOLDER=$PWD
|
||||
|
||||
# Restore Nuget packages for all builds
|
||||
echo "Restoring Nuget packages"
|
||||
dotnet restore
|
||||
# Set the current commit hash
|
||||
COMMIT=`git log --pretty=%H -1`
|
||||
|
||||
# .NET 6.0 Debug
|
||||
echo "Building .NET 6.0 debug"
|
||||
dotnet publish Test/Test.csproj -f net6.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
dotnet publish Test/Test.csproj -f net6.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
dotnet publish Test/Test.csproj -f net6.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
# Create the build matrix arrays
|
||||
FRAMEWORKS=("net8.0")
|
||||
RUNTIMES=("win-x86" "win-x64" "linux-x64" "osx-x64")
|
||||
|
||||
# .NET 6.0 Release
|
||||
echo "Building .NET 6.0 release"
|
||||
dotnet publish Test/Test.csproj -f net6.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
|
||||
dotnet publish Test/Test.csproj -f net6.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
|
||||
dotnet publish Test/Test.csproj -f net6.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
|
||||
# Use expanded lists, if requested
|
||||
if [ $USE_ALL = true ]
|
||||
then
|
||||
FRAMEWORKS=("net20" "net35" "net40" "net452" "net462" "net472" "net48" "netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0")
|
||||
RUNTIMES=("win-x86" "win-x64" "win-arm64" "linux-x64" "linux-arm64" "osx-x64")
|
||||
fi
|
||||
|
||||
# .NET 8.0 Debug
|
||||
echo "Building .NET 8.0 debug"
|
||||
dotnet publish Test/Test.csproj -f net8.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
dotnet publish Test/Test.csproj -f net8.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
dotnet publish Test/Test.csproj -f net8.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
# Create the filter arrays
|
||||
SINGLE_FILE_CAPABLE=("net5.0" "net6.0" "net7.0" "net8.0")
|
||||
VALID_CROSS_PLATFORM_FRAMEWORKS=("netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0")
|
||||
VALID_CROSS_PLATFORM_RUNTIMES=("win-arm64" "linux-x64" "linux-arm64" "osx-x64")
|
||||
NON_DLL_FRAMEWORKS=("net20" "net35" "net40")
|
||||
NON_DLL_RUNTIMES=("win-x64" "win-arm64" "linux-x64" "linux-arm64" "osx-x64")
|
||||
|
||||
# .NET 8.0 Release
|
||||
echo "Building .NET 8.0 release"
|
||||
dotnet publish Test/Test.csproj -f net8.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
|
||||
dotnet publish Test/Test.csproj -f net8.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
|
||||
dotnet publish Test/Test.csproj -f net8.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
|
||||
# Only build if requested
|
||||
if [ $NO_BUILD = false ]
|
||||
then
|
||||
# Restore Nuget packages for all builds
|
||||
echo "Restoring Nuget packages"
|
||||
dotnet restore
|
||||
|
||||
# Create Test Debug archives
|
||||
cd $BUILD_FOLDER/Test/bin/Debug/net6.0/win-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_win-x64_debug.zip .
|
||||
cd $BUILD_FOLDER/Test/bin/Debug/net6.0/linux-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_linux-x64_debug.zip .
|
||||
cd $BUILD_FOLDER/Test/bin/Debug/net6.0/osx-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_osx-x64_debug.zip .
|
||||
cd $BUILD_FOLDER/Test/bin/Debug/net8.0/win-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_win-x64_debug.zip .
|
||||
cd $BUILD_FOLDER/Test/bin/Debug/net8.0/linux-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_linux-x64_debug.zip .
|
||||
cd $BUILD_FOLDER/Test/bin/Debug/net8.0/osx-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_osx-x64_debug.zip .
|
||||
# Create Nuget Package
|
||||
dotnet pack BinaryObjectScanner/BinaryObjectScanner.csproj --output $BUILD_FOLDER
|
||||
|
||||
# Create Test Release archives
|
||||
cd $BUILD_FOLDER/Test/bin/Release/net6.0/win-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_win-x64_release.zip .
|
||||
cd $BUILD_FOLDER/Test/bin/Release/net6.0/linux-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_linux-x64_release.zip .
|
||||
cd $BUILD_FOLDER/Test/bin/Release/net6.0/osx-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_osx-x64_release.zip .
|
||||
cd $BUILD_FOLDER/Test/bin/Release/net8.0/win-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_win-x64_release.zip .
|
||||
cd $BUILD_FOLDER/Test/bin/Release/net8.0/linux-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_linux-x64_release.zip .
|
||||
cd $BUILD_FOLDER/Test/bin/Release/net8.0/osx-x64/publish/
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_osx-x64_release.zip .
|
||||
# Build Test
|
||||
for FRAMEWORK in "${FRAMEWORKS[@]}"
|
||||
do
|
||||
for RUNTIME in "${RUNTIMES[@]}"
|
||||
do
|
||||
# If we have an invalid combination of framework and runtime
|
||||
if [ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ] && [ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Only .NET 5 and above can publish to a single file
|
||||
if [[ $(echo ${SINGLE_FILE_CAPABLE[@]} | fgrep -w $FRAMEWORK) ]]
|
||||
then
|
||||
dotnet publish Test/Test.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
|
||||
dotnet publish Test/Test.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
||||
else
|
||||
dotnet publish Test/Test.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
|
||||
dotnet publish Test/Test.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
# Only create archives if requested
|
||||
if [ $NO_ARCHIVE = false ]
|
||||
then
|
||||
# Create Test archives
|
||||
for FRAMEWORK in "${FRAMEWORKS[@]}"
|
||||
do
|
||||
for RUNTIME in "${RUNTIMES[@]}"
|
||||
do
|
||||
# If we have an invalid combination of framework and runtime
|
||||
if [ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ] && [ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
|
||||
cd $BUILD_FOLDER/Test/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/
|
||||
if [ $(echo ${NON_DLL_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ] || [ $(echo ${NON_DLL_RUNTIMES[@]} | fgrep -w $RUNTIME) ]
|
||||
then
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_debug.zip . -x 'CascLib.dll' -x 'mspack.dll' -x 'StormLib.dll'
|
||||
else
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_debug.zip .
|
||||
fi
|
||||
cd $BUILD_FOLDER/Test/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/
|
||||
if [ $(echo ${NON_DLL_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ] || [ $(echo ${NON_DLL_RUNTIMES[@]} | fgrep -w $RUNTIME) ]
|
||||
then
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_release.zip . -x 'CascLib.dll' -x 'mspack.dll' -x 'StormLib.dll'
|
||||
else
|
||||
zip -r $BUILD_FOLDER/BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_release.zip .
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# Reset the directory
|
||||
cd $BUILD_FOLDER
|
||||
fi
|
||||
@@ -1,63 +0,0 @@
|
||||
@echo OFF
|
||||
|
||||
REM This batch file assumes the following:
|
||||
REM - .NET 8.0 (or newer) SDK is installed and in PATH
|
||||
REM - 7-zip commandline (7z.exe) is installed and in PATH
|
||||
REM - The relevant commandline programs are already downloaded
|
||||
REM and put into their respective folders
|
||||
REM
|
||||
REM If any of these are not satisfied, the operation may fail
|
||||
REM in an unpredictable way and result in an incomplete output.
|
||||
|
||||
REM Set the current directory as a variable
|
||||
set BUILD_FOLDER=%~dp0
|
||||
|
||||
REM Restore Nuget packages for all builds
|
||||
echo Restoring Nuget packages
|
||||
dotnet restore
|
||||
|
||||
REM Debug
|
||||
echo Building debug
|
||||
dotnet publish Test\Test.csproj -f net6.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
dotnet publish Test\Test.csproj -f net6.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
dotnet publish Test\Test.csproj -f net6.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
dotnet publish Test\Test.csproj -f net8.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
dotnet publish Test\Test.csproj -f net8.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
dotnet publish Test\Test.csproj -f net8.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
|
||||
|
||||
REM Release
|
||||
echo Building release
|
||||
dotnet publish Test\Test.csproj -f net6.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
||||
dotnet publish Test\Test.csproj -f net6.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
||||
dotnet publish Test\Test.csproj -f net6.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
||||
dotnet publish Test\Test.csproj -f net8.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
||||
dotnet publish Test\Test.csproj -f net8.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
||||
dotnet publish Test\Test.csproj -f net8.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
||||
|
||||
REM Create Test Debug archives
|
||||
cd %BUILD_FOLDER%\Test\bin\Debug\net6.0\win-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_win-x64_debug.zip *
|
||||
cd %BUILD_FOLDER%\Test\bin\Debug\net6.0\linux-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_linux-x64_debug.zip *
|
||||
cd %BUILD_FOLDER%\Test\bin\Debug\net6.0\osx-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_osx-x64_debug.zip *
|
||||
cd %BUILD_FOLDER%\Test\bin\Debug\net8.0\win-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_win-x64_debug.zip *
|
||||
cd %BUILD_FOLDER%\Test\bin\Debug\net8.0\linux-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_linux-x64_debug.zip *
|
||||
cd %BUILD_FOLDER%\Test\bin\Debug\net8.0\osx-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_osx-x64_debug.zip *
|
||||
|
||||
REM Create Test Release archives
|
||||
cd %BUILD_FOLDER%\Test\bin\Release\net6.0\win-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_win-x64_release.zip *
|
||||
cd %BUILD_FOLDER%\Test\bin\Release\net6.0\linux-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_linux-x64_release.zip *
|
||||
cd %BUILD_FOLDER%\Test\bin\Release\net6.0\osx-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_osx-x64_release.zip *
|
||||
cd %BUILD_FOLDER%\Test\bin\Release\net8.0\win-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_win-x64_release.zip *
|
||||
cd %BUILD_FOLDER%\Test\bin\Release\net8.0\linux-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_linux-x64_release.zip *
|
||||
cd %BUILD_FOLDER%\Test\bin\Release\net8.0\osx-x64\publish\
|
||||
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_osx-x64_release.zip *
|
||||
121
publish-win.ps1
Normal file
121
publish-win.ps1
Normal file
@@ -0,0 +1,121 @@
|
||||
# This batch file assumes the following:
|
||||
# - .NET 8.0 (or newer) SDK is installed and in PATH
|
||||
# - 7-zip commandline (7z.exe) is installed and in PATH
|
||||
# - Git for Windows is installed and in PATH
|
||||
#
|
||||
# If any of these are not satisfied, the operation may fail
|
||||
# in an unpredictable way and result in an incomplete output.
|
||||
|
||||
# Optional parameters
|
||||
param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[Alias("UseAll")]
|
||||
[switch]$USE_ALL,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[Alias("NoBuild")]
|
||||
[switch]$NO_BUILD,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[Alias("NoArchive")]
|
||||
[switch]$NO_ARCHIVE
|
||||
)
|
||||
|
||||
# Set the current directory as a variable
|
||||
$BUILD_FOLDER = $PSScriptRoot
|
||||
|
||||
# Set the current commit hash
|
||||
$COMMIT = git log --pretty=format:"%H" -1
|
||||
|
||||
# Create the build matrix arrays
|
||||
$FRAMEWORKS = @('net8.0')
|
||||
$RUNTIMES = @('win-x86', 'win-x64', 'linux-x64', 'osx-x64')
|
||||
|
||||
# Use expanded lists, if requested
|
||||
if ($USE_ALL.IsPresent)
|
||||
{
|
||||
$FRAMEWORKS = @('net20', 'net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0')
|
||||
$RUNTIMES = @('win-x86', 'win-x64', 'win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64')
|
||||
}
|
||||
|
||||
# Create the filter arrays
|
||||
$SINGLE_FILE_CAPABLE = @('net5.0', 'net6.0', 'net7.0', 'net8.0')
|
||||
$VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0')
|
||||
$VALID_CROSS_PLATFORM_RUNTIMES = @('win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64')
|
||||
$NON_DLL_FRAMEWORKS = @('net20', 'net35', 'net40')
|
||||
$NON_DLL_RUNTIMES = @('win-x64', 'win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64')
|
||||
|
||||
# Only build if requested
|
||||
if (!$NO_BUILD.IsPresent)
|
||||
{
|
||||
# Restore Nuget packages for all builds
|
||||
Write-Host "Restoring Nuget packages"
|
||||
dotnet restore
|
||||
|
||||
# Create Nuget Package
|
||||
dotnet pack BinaryObjectScanner\BinaryObjectScanner.csproj --output $BUILD_FOLDER
|
||||
|
||||
# Build Test
|
||||
foreach ($FRAMEWORK in $FRAMEWORKS)
|
||||
{
|
||||
foreach ($RUNTIME in $RUNTIMES)
|
||||
{
|
||||
# If we have an invalid combination of framework and runtime
|
||||
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME)
|
||||
{
|
||||
continue
|
||||
}
|
||||
|
||||
# Only .NET 5 and above can publish to a single file
|
||||
if ($SINGLE_FILE_CAPABLE -contains $FRAMEWORK)
|
||||
{
|
||||
dotnet publish Test\Test.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
|
||||
dotnet publish Test\Test.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
||||
}
|
||||
else
|
||||
{
|
||||
dotnet publish Test\Test.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
|
||||
dotnet publish Test\Test.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Only create archives if requested
|
||||
if (!$NO_ARCHIVE.IsPresent)
|
||||
{
|
||||
# Create Test archives
|
||||
foreach ($FRAMEWORK in $FRAMEWORKS)
|
||||
{
|
||||
foreach ($RUNTIME in $RUNTIMES)
|
||||
{
|
||||
# If we have an invalid combination of framework and runtime
|
||||
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME)
|
||||
{
|
||||
continue
|
||||
}
|
||||
|
||||
Set-Location -Path $BUILD_FOLDER\Test\bin\Debug\${FRAMEWORK}\${RUNTIME}\publish\
|
||||
if ($NON_DLL_FRAMEWORKS -contains $FRAMEWORK -or $NON_DLL_RUNTIMES -contains $RUNTIME)
|
||||
{
|
||||
7z a -tzip -x'!CascLib.dll' -x'!mspack.dll' -x'!StormLib.dll' $BUILD_FOLDER\BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_debug.zip *
|
||||
}
|
||||
else
|
||||
{
|
||||
7z a -tzip $BUILD_FOLDER\BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_debug.zip *
|
||||
}
|
||||
Set-Location -Path $BUILD_FOLDER\Test\bin\Release\${FRAMEWORK}\${RUNTIME}\publish\
|
||||
if ($NON_DLL_FRAMEWORKS -contains $FRAMEWORK -or $NON_DLL_RUNTIMES -contains $RUNTIME)
|
||||
{
|
||||
7z a -tzip -x'!CascLib.dll' -x'!mspack.dll' -x'!StormLib.dll' $BUILD_FOLDER\BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_release.zip *
|
||||
}
|
||||
else
|
||||
{
|
||||
7z a -tzip $BUILD_FOLDER\BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_release.zip *
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Reset the directory
|
||||
Set-Location -Path $PSScriptRoot
|
||||
}
|
||||
Reference in New Issue
Block a user