mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-02-05 21:29:07 +00:00
Compare commits
226 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac917df519 | ||
|
|
3b12fef948 | ||
|
|
a74b769aef | ||
|
|
ea17ad1eae | ||
|
|
6087e6e0c6 | ||
|
|
535f14bc54 | ||
|
|
6b3d42b81f | ||
|
|
e645b8e1c0 | ||
|
|
955c8685b6 | ||
|
|
6184ae22aa | ||
|
|
4e2c5313f3 | ||
|
|
137f7fcc01 | ||
|
|
d771c4931c | ||
|
|
61a2181924 | ||
|
|
baad181e5f | ||
|
|
1b0fcdcf32 | ||
|
|
9fa1ef1d2e | ||
|
|
e2492c9e5b | ||
|
|
297514ef17 | ||
|
|
2acb0a037c | ||
|
|
c38eb0cc71 | ||
|
|
258369bb9e | ||
|
|
8cba9529d7 | ||
|
|
10296f40b4 | ||
|
|
73d085deac | ||
|
|
c7261c342a | ||
|
|
14d905fba3 | ||
|
|
1f66edc201 | ||
|
|
ade95c3210 | ||
|
|
8a419f50db | ||
|
|
52efca767e | ||
|
|
421dfa2591 | ||
|
|
76183c529c | ||
|
|
463506d1e8 | ||
|
|
1f2a187f55 | ||
|
|
40de5c4d0a | ||
|
|
5e72acb44c | ||
|
|
fab3c935f8 | ||
|
|
a498513662 | ||
|
|
3eaebffff1 | ||
|
|
280ae5babe | ||
|
|
5bf64d46bd | ||
|
|
6fb510c852 | ||
|
|
20223eea87 | ||
|
|
3f796e4e0e | ||
|
|
74732a1b50 | ||
|
|
f252681364 | ||
|
|
82cb0f934d | ||
|
|
7dc5644d21 | ||
|
|
313cc2bfb8 | ||
|
|
f24a8763fd | ||
|
|
47845a2409 | ||
|
|
42da9f4a82 | ||
|
|
e9fa86343a | ||
|
|
8ccf2272d6 | ||
|
|
8fb42bc12d | ||
|
|
6202ee5d5c | ||
|
|
655a8adb1c | ||
|
|
d7fcc99fc2 | ||
|
|
8601f373bd | ||
|
|
3c783fdc68 | ||
|
|
a75388cf17 | ||
|
|
7968a79fe6 | ||
|
|
8502924083 | ||
|
|
af95ca08c3 | ||
|
|
06995b75d6 | ||
|
|
1a2be26c72 | ||
|
|
a2a583e317 | ||
|
|
289a55ca21 | ||
|
|
598f625ed1 | ||
|
|
d604a6d784 | ||
|
|
cf34a0adee | ||
|
|
083ded8a7e | ||
|
|
1517a66724 | ||
|
|
5385de0f0a | ||
|
|
43729b53f0 | ||
|
|
e4aa618f0b | ||
|
|
4953673caf | ||
|
|
35c6d4f36c | ||
|
|
9108fa5a11 | ||
|
|
dc97feae39 | ||
|
|
beac29c650 | ||
|
|
21a041dad6 | ||
|
|
26eee23511 | ||
|
|
0915c7eccd | ||
|
|
e2e65bfbdf | ||
|
|
033f2e0a4e | ||
|
|
71ee0863eb | ||
|
|
3203c3ac83 | ||
|
|
1733f60a0f | ||
|
|
b01abdcce3 | ||
|
|
53c90533e3 | ||
|
|
03bd7bd1f5 | ||
|
|
637579b0fc | ||
|
|
bd40ca6d9d | ||
|
|
3c1623cb22 | ||
|
|
66da32b5c1 | ||
|
|
c21b64b5bd | ||
|
|
e968eeea96 | ||
|
|
c14005dcc4 | ||
|
|
84c6c257df | ||
|
|
e28b930f85 | ||
|
|
9dac2eb91b | ||
|
|
2209f362fa | ||
|
|
614413ab76 | ||
|
|
35c15d0ff8 | ||
|
|
b521df2ad4 | ||
|
|
778fe106f9 | ||
|
|
9171014dcd | ||
|
|
7ee74d9b81 | ||
|
|
826011f532 | ||
|
|
adb349932f | ||
|
|
f4f13c03fe | ||
|
|
e29e87444e | ||
|
|
b233b3c17b | ||
|
|
a8fca77331 | ||
|
|
5e4ee07646 | ||
|
|
52b2a9bef8 | ||
|
|
dc7f8da52f | ||
|
|
d46b0768a0 | ||
|
|
f136af3457 | ||
|
|
2e2b6068c5 | ||
|
|
7a29d8a8f9 | ||
|
|
ae0c47066e | ||
|
|
11188c9488 | ||
|
|
4d5d2d8690 | ||
|
|
1860a863b8 | ||
|
|
8dbf6d9362 | ||
|
|
e3e8a1170f | ||
|
|
b22641b7ab | ||
|
|
d3d75b9e58 | ||
|
|
6083c64b87 | ||
|
|
4185367a49 | ||
|
|
c027b1798a | ||
|
|
76e52292a8 | ||
|
|
dd5f7c4e0b | ||
|
|
6e70991e86 | ||
|
|
f1803b9f3a | ||
|
|
9e0abe7c5d | ||
|
|
1a01102252 | ||
|
|
ce849d312f | ||
|
|
71da8a53c0 | ||
|
|
b8f7d00dc9 | ||
|
|
7e69a56892 | ||
|
|
8cedd3e469 | ||
|
|
d5e60439fb | ||
|
|
1a0e16a05b | ||
|
|
bee6d2b885 | ||
|
|
5d515c7ddd | ||
|
|
013301fa99 | ||
|
|
152ae8bf6c | ||
|
|
439f71ef5c | ||
|
|
66c7afe20b | ||
|
|
6a609ea3f5 | ||
|
|
6752d0cfa3 | ||
|
|
1d26b06592 | ||
|
|
9ca24a3053 | ||
|
|
76ca87f7a9 | ||
|
|
c913b10286 | ||
|
|
768c77a6bc | ||
|
|
20d90d6a60 | ||
|
|
54a48e0729 | ||
|
|
15c05c65e7 | ||
|
|
4dbaa415c5 | ||
|
|
1a0b83a9f1 | ||
|
|
4316427980 | ||
|
|
21ecaca761 | ||
|
|
7022a957d6 | ||
|
|
32cfcbff0a | ||
|
|
283fa425d4 | ||
|
|
d37eac02d5 | ||
|
|
c3e0b99002 | ||
|
|
9e49703bc5 | ||
|
|
98a7149cc9 | ||
|
|
394b4e70fb | ||
|
|
b29198b3d4 | ||
|
|
044c398fa7 | ||
|
|
ae7087e8d0 | ||
|
|
90bc78982c | ||
|
|
2ce8bda394 | ||
|
|
ac0ed050dc | ||
|
|
e4aadb3794 | ||
|
|
80626f3b9e | ||
|
|
93263dfeb9 | ||
|
|
51e5f82cc2 | ||
|
|
b69c5cf928 | ||
|
|
e45b593c7b | ||
|
|
c245ebb80a | ||
|
|
cd38407e4e | ||
|
|
f34b1ba5cf | ||
|
|
08c97d291e | ||
|
|
3ea294f4d9 | ||
|
|
ddb2be278a | ||
|
|
b6b5dc4efa | ||
|
|
218fecb273 | ||
|
|
b23a504c7b | ||
|
|
c54181e9ac | ||
|
|
7e100a261c | ||
|
|
38e1154bad | ||
|
|
901804e9e4 | ||
|
|
dfee4a8d76 | ||
|
|
295b86fbd0 | ||
|
|
177543a51c | ||
|
|
dfff702e5d | ||
|
|
c0ad427b5e | ||
|
|
2f68f95d80 | ||
|
|
a8ba104d0f | ||
|
|
6f9e92d222 | ||
|
|
1e20c1b147 | ||
|
|
c16946ace7 | ||
|
|
9d7cc4012c | ||
|
|
a44bdf9013 | ||
|
|
f9f2e0d932 | ||
|
|
2dd3e21ea6 | ||
|
|
81bb47b634 | ||
|
|
c8efc1430a | ||
|
|
7883638f0a | ||
|
|
e930be12c8 | ||
|
|
c45ae4b693 | ||
|
|
478f28b513 | ||
|
|
aac3c391db | ||
|
|
802734b515 | ||
|
|
ef212fc8d9 | ||
|
|
ee85f2f6f0 | ||
|
|
9a160b3127 | ||
|
|
4486c5ed62 |
19
.gitmodules
vendored
19
.gitmodules
vendored
@@ -1,15 +1,12 @@
|
||||
[submodule "BurnOutSharp/External/LessIO"]
|
||||
path = BurnOutSharp/External/LessIO
|
||||
url = https://github.com/activescott/LessIO.git
|
||||
[submodule "BurnOutSharp/External/libmspack4n"]
|
||||
path = BurnOutSharp/External/libmspack4n
|
||||
url = https://github.com/activescott/libmspack4n.git
|
||||
[submodule "BurnOutSharp/External/hllib"]
|
||||
path = BurnOutSharp/External/hllib
|
||||
url = https://github.com/RavuAlHemio/hllib.git
|
||||
[submodule "BurnOutSharp/External/stormlibsharp"]
|
||||
path = BurnOutSharp/External/stormlibsharp
|
||||
url = https://github.com/robpaveza/stormlibsharp.git
|
||||
[submodule "BurnOutSharp/External/WixToolset"]
|
||||
path = WixToolset
|
||||
[submodule "HLLibSharp"]
|
||||
path = HLLibSharp
|
||||
url = https://github.com/mnadareski/HLLibSharp
|
||||
[submodule "LibMSPackSharp"]
|
||||
path = LibMSPackSharp
|
||||
url = https://github.com/mnadareski/LibMSPackSharp.git
|
||||
[submodule "Dtf"]
|
||||
path = Dtf
|
||||
url = https://github.com/wixtoolset/Dtf.git
|
||||
|
||||
@@ -14,11 +14,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WixToolset", "WixToolset", "{09D405CA-CF15-4929-8408-C970F0656C62}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HLLibSharp", "HLLibSharp\HLLibSharp\HLLibSharp.csproj", "{14E9764A-A8BF-44C0-A1A8-2C95EA307040}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{182E02A8-5E8E-4140-9C9B-61049C33E921}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibMSPackSharp", "LibMSPackSharp\LibMSPackSharp\LibMSPackSharp.csproj", "{BD8144B8-4857-47E6-9717-E9F2DB374A89}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Dtf.WindowsInstaller", "WixToolset\src\WixToolset.Dtf.WindowsInstaller\WixToolset.Dtf.WindowsInstaller.csproj", "{B3537EB7-CEF6-4D90-A041-47626442A656}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Dtf.Compression.Cab", "Dtf\src\WixToolset.Dtf.Compression.Cab\WixToolset.Dtf.Compression.Cab.csproj", "{55B1D2D8-7470-4332-96EE-E18079C8A306}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Dtf.Compression", "Dtf\src\WixToolset.Dtf.Compression\WixToolset.Dtf.Compression.csproj", "{3065BE52-CB56-4557-80CD-E3AC57C242F2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -34,18 +36,26 @@ Global
|
||||
{88735BA2-778D-4192-8EB2-FFF6843719E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{88735BA2-778D-4192-8EB2-FFF6843719E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{88735BA2-778D-4192-8EB2-FFF6843719E2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B3537EB7-CEF6-4D90-A041-47626442A656}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B3537EB7-CEF6-4D90-A041-47626442A656}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B3537EB7-CEF6-4D90-A041-47626442A656}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B3537EB7-CEF6-4D90-A041-47626442A656}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{14E9764A-A8BF-44C0-A1A8-2C95EA307040}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{14E9764A-A8BF-44C0-A1A8-2C95EA307040}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{14E9764A-A8BF-44C0-A1A8-2C95EA307040}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{14E9764A-A8BF-44C0-A1A8-2C95EA307040}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BD8144B8-4857-47E6-9717-E9F2DB374A89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BD8144B8-4857-47E6-9717-E9F2DB374A89}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BD8144B8-4857-47E6-9717-E9F2DB374A89}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BD8144B8-4857-47E6-9717-E9F2DB374A89}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{55B1D2D8-7470-4332-96EE-E18079C8A306}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{55B1D2D8-7470-4332-96EE-E18079C8A306}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{55B1D2D8-7470-4332-96EE-E18079C8A306}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{55B1D2D8-7470-4332-96EE-E18079C8A306}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3065BE52-CB56-4557-80CD-E3AC57C242F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3065BE52-CB56-4557-80CD-E3AC57C242F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3065BE52-CB56-4557-80CD-E3AC57C242F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3065BE52-CB56-4557-80CD-E3AC57C242F2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{182E02A8-5E8E-4140-9C9B-61049C33E921} = {09D405CA-CF15-4929-8408-C970F0656C62}
|
||||
{B3537EB7-CEF6-4D90-A041-47626442A656} = {182E02A8-5E8E-4140-9C9B-61049C33E921}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0B343DD2-8852-47B0-9647-DFCFBEDF933C}
|
||||
EndGlobalSection
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<Title>BurnOutSharp</Title>
|
||||
<AssemblyName>BurnOutSharp</AssemblyName>
|
||||
<Description>Port of BurnOut to C#, with additions</Description>
|
||||
@@ -11,9 +10,9 @@
|
||||
<Copyright>Copyright (c)2005-2010 Gernot Knippen, Copyright (c)2018-2022 Matt Nadareski</Copyright>
|
||||
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
|
||||
<RepositoryUrl>https://github.com/mnadareski/BurnOutSharp</RepositoryUrl>
|
||||
<Version>2.1.0</Version>
|
||||
<AssemblyVersion>2.1.0</AssemblyVersion>
|
||||
<FileVersion>2.1.0</FileVersion>
|
||||
<Version>2.3.4</Version>
|
||||
<AssemblyVersion>2.3.4</AssemblyVersion>
|
||||
<FileVersion>2.3.4</FileVersion>
|
||||
<IncludeSource>true</IncludeSource>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
</PropertyGroup>
|
||||
@@ -23,7 +22,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SharpCompress" Version="0.31.0" />
|
||||
<PackageReference Include="OpenMcdf" Version="2.2.1.12" />
|
||||
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0" />
|
||||
<PackageReference Include="Teronis.MSBuild.Packaging.ProjectBuildInPackage" Version="1.0.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
@@ -31,6 +31,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="UnshieldSharp" Version="1.6.8" />
|
||||
<PackageReference Include="WiseUnpacker" Version="1.0.3" />
|
||||
<PackageReference Include="zlib.net-mutliplatform" Version="1.0.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- These are needed for dealing with submodules -->
|
||||
@@ -38,12 +39,6 @@
|
||||
<DefaultItemExcludes>
|
||||
$(DefaultItemExcludes);
|
||||
**\AssemblyInfo.cs;
|
||||
External\hllib\HLExtract\**\*;
|
||||
External\hllib\HLExtract.Net\Program.cs;
|
||||
External\hllib\HLLib\**\*;
|
||||
External\LessIO\src\LessIO.Tests\**\*;
|
||||
External\libmspack4n\lib\**\*;
|
||||
External\libmspack4n\libmspack4ntest\**\*;
|
||||
External\stormlibsharp\lib\**;
|
||||
External\stormlibsharp\TestConsole\**
|
||||
</DefaultItemExcludes>
|
||||
@@ -62,7 +57,20 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WixToolset\src\WixToolset.Dtf.WindowsInstaller\WixToolset.Dtf.WindowsInstaller.csproj">
|
||||
<ProjectReference Include="..\Dtf\src\WixToolset.Dtf.Compression\WixToolset.Dtf.Compression.csproj">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Dtf\src\WixToolset.Dtf.Compression.Cab\WixToolset.Dtf.Compression.Cab.csproj">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\HLLibSharp\HLLibSharp\HLLibSharp.csproj">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\LibMSPackSharp\LibMSPackSharp\LibMSPackSharp.csproj">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE.Headers
|
||||
/// The address of the entry point relative to the image base when the executable file is loaded into memory.
|
||||
/// For program images, this is the starting address.
|
||||
/// For device drivers, this is the address of the initialization function.
|
||||
// An entry point is optional for DLLs.
|
||||
/// An entry point is optional for DLLs.
|
||||
/// When no entry point is present, this field must be zero.
|
||||
/// </summary>
|
||||
public uint AddressOfEntryPoint;
|
||||
|
||||
@@ -184,6 +184,20 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
|
||||
|
||||
#endregion
|
||||
|
||||
#region Raw Other Data
|
||||
|
||||
/// <summary>
|
||||
/// Data at the entry point of the application
|
||||
/// </summary>
|
||||
public byte[] EntryPointRaw;
|
||||
|
||||
/// <summary>
|
||||
/// Data from the overlay of the application
|
||||
/// </summary>
|
||||
public byte[] OverlayRaw;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Resources
|
||||
|
||||
/// <summary>
|
||||
@@ -211,6 +225,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
|
||||
/// </summary>
|
||||
public string LegalCopyright { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Legal trademarks resource string
|
||||
/// </summary>
|
||||
public string LegalTrademarks { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Description manifest string
|
||||
/// </summary>
|
||||
@@ -366,6 +385,30 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
|
||||
|
||||
#endregion
|
||||
|
||||
#region Freeform Data
|
||||
|
||||
// Entry Point Data
|
||||
if (this.OptionalHeader != null && this.OptionalHeader.AddressOfEntryPoint != 0)
|
||||
{
|
||||
int entryPointAddress = (int)ConvertVirtualAddress(this.OptionalHeader.AddressOfEntryPoint, SectionTable);
|
||||
this.EntryPointRaw = this.ReadArbitraryRange(entryPointAddress, 1024);
|
||||
}
|
||||
|
||||
// Overlay Data
|
||||
if (this.SectionTable != null && this.SectionTable.Length > 0)
|
||||
{
|
||||
// TODO: Read certificate data separately
|
||||
int overlayOffset = this.SectionTable
|
||||
.Select(sh => (int)(sh.PointerToRawData + sh.VirtualSize))
|
||||
.OrderByDescending(o => o)
|
||||
.First();
|
||||
|
||||
if (overlayOffset < stream.Length)
|
||||
this.OverlayRaw = this.ReadArbitraryRange(rangeStart: overlayOffset);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// Populate resources, if possible
|
||||
PopulateResourceStrings();
|
||||
}
|
||||
@@ -476,6 +519,30 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
|
||||
|
||||
#endregion
|
||||
|
||||
#region Freeform Data
|
||||
|
||||
// Entry Point Data
|
||||
if (this.OptionalHeader != null && this.OptionalHeader.AddressOfEntryPoint != 0)
|
||||
{
|
||||
int entryPointAddress = (int)ConvertVirtualAddress(this.OptionalHeader.AddressOfEntryPoint, SectionTable);
|
||||
this.EntryPointRaw = this.ReadArbitraryRange(entryPointAddress, 1024);
|
||||
}
|
||||
|
||||
// Overlay Data
|
||||
if (this.SectionTable != null && this.SectionTable.Length > 0)
|
||||
{
|
||||
// TODO: Read certificate data separately
|
||||
int overlayOffset = this.SectionTable
|
||||
.Select(sh => (int)(sh.PointerToRawData + sh.VirtualSize))
|
||||
.OrderByDescending(o => o)
|
||||
.First();
|
||||
|
||||
if (overlayOffset < content.Length)
|
||||
this.OverlayRaw = this.ReadArbitraryRange(rangeStart: overlayOffset);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// Populate resources, if possible
|
||||
PopulateResourceStrings();
|
||||
}
|
||||
@@ -562,6 +629,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
|
||||
{
|
||||
if (rdte.IsResourceDataEntry() && rdte.DataEntry != null)
|
||||
{
|
||||
// Ignore if we have a nested executable
|
||||
// TODO: Support nested executables
|
||||
if (rdte.DataEntry.DataAsUTF8String.StartsWith("MZ"))
|
||||
return null;
|
||||
|
||||
if (dataStart != null && rdte.DataEntry.DataAsUTF8String.StartsWith(dataStart))
|
||||
return rdte.DataEntry;
|
||||
else if (dataContains != null && rdte.DataEntry.DataAsUTF8String.Contains(dataContains))
|
||||
@@ -581,6 +653,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
|
||||
{
|
||||
if (rdte.IsResourceDataEntry() && rdte.DataEntry != null)
|
||||
{
|
||||
// Ignore if we have a nested executable
|
||||
// TODO: Support nested executables
|
||||
if (rdte.DataEntry.DataAsUTF8String.StartsWith("MZ"))
|
||||
return null;
|
||||
|
||||
if (dataStart != null && rdte.DataEntry.DataAsUTF8String.StartsWith(dataStart))
|
||||
return rdte.DataEntry;
|
||||
else if (dataContains != null && rdte.DataEntry.DataAsUTF8String.Contains(dataContains))
|
||||
@@ -729,6 +806,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
|
||||
this.FileVersion = GetResourceString("FileVersion")?.Replace(", ", ".");
|
||||
this.InternalName = GetResourceString("InternalName");
|
||||
this.LegalCopyright = GetResourceString("LegalCopyright");
|
||||
this.LegalTrademarks = GetResourceString("LegalTrademarks");
|
||||
this.OriginalFileName = GetResourceString("OriginalFileName");
|
||||
this.ProductName = GetResourceString("ProductName");
|
||||
this.ProductVersion = GetResourceString("ProductVersion")?.Replace(", ", ".");
|
||||
|
||||
@@ -15,13 +15,13 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
this.Length = resource?.Length ?? default;
|
||||
this.ValueLength = resource?.ValueLength ?? default;
|
||||
this.Type = resource?.Type ?? default;
|
||||
this.Key = resource?.Key ?? default;
|
||||
this.Key = resource?.Key?.TrimStart('\u0001') ?? default;
|
||||
}
|
||||
|
||||
public static new StringFileInfo Deserialize(Stream stream)
|
||||
{
|
||||
Resource resource = Resource.Deserialize(stream);
|
||||
if (resource.Key != "StringFileInfo")
|
||||
if (resource.Key != "StringFileInfo" && resource.Key != "\u0001StringFileInfo")
|
||||
return null;
|
||||
|
||||
StringFileInfo sfi = new StringFileInfo(resource);
|
||||
@@ -33,7 +33,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
public static new StringFileInfo Deserialize(byte[] content, ref int offset)
|
||||
{
|
||||
Resource resource = Resource.Deserialize(content, ref offset);
|
||||
if (resource.Key != "StringFileInfo")
|
||||
if (resource.Key != "StringFileInfo" && resource.Key != "\u0001StringFileInfo")
|
||||
return null;
|
||||
|
||||
StringFileInfo sfi = new StringFileInfo(resource);
|
||||
|
||||
@@ -48,12 +48,12 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
|
||||
long preChildOffset = stream.Position;
|
||||
Resource firstChild = Resource.Deserialize(stream);
|
||||
if (firstChild.Key == "StringFileInfo")
|
||||
if (firstChild.Key == "StringFileInfo" || firstChild.Key == "\u0001StringFileInfo")
|
||||
{
|
||||
stream.Seek(preChildOffset, SeekOrigin.Begin);
|
||||
vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(stream);
|
||||
}
|
||||
else if (firstChild.Key == "VarFileInfo")
|
||||
else if (firstChild.Key == "VarFileInfo" || firstChild.Key == "\u0001VarFileInfo")
|
||||
{
|
||||
stream.Seek(preChildOffset, SeekOrigin.Begin);
|
||||
vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(stream);
|
||||
@@ -64,12 +64,12 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
|
||||
preChildOffset = stream.Position;
|
||||
Resource secondChild = Resource.Deserialize(stream);
|
||||
if (secondChild.Key == "StringFileInfo")
|
||||
if (secondChild.Key == "StringFileInfo" || secondChild.Key == "\u0001StringFileInfo")
|
||||
{
|
||||
stream.Seek(preChildOffset, SeekOrigin.Begin);
|
||||
vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(stream);
|
||||
}
|
||||
else if (secondChild.Key == "VarFileInfo")
|
||||
else if (secondChild.Key == "VarFileInfo" || secondChild.Key == "\u0001VarFileInfo")
|
||||
{
|
||||
stream.Seek(preChildOffset, SeekOrigin.Begin);
|
||||
vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(stream);
|
||||
@@ -95,12 +95,12 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
|
||||
int preChildOffset = offset;
|
||||
Resource firstChild = Resource.Deserialize(content, ref offset);
|
||||
if (firstChild.Key == "StringFileInfo")
|
||||
if (firstChild.Key == "StringFileInfo" || firstChild.Key == "\u0001StringFileInfo")
|
||||
{
|
||||
offset = preChildOffset;
|
||||
vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(content, ref offset);
|
||||
}
|
||||
else if (firstChild.Key == "VarFileInfo")
|
||||
else if (firstChild.Key == "VarFileInfo" || firstChild.Key == "\u0001VarFileInfo")
|
||||
{
|
||||
offset = preChildOffset;
|
||||
vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(content, ref offset);
|
||||
@@ -112,12 +112,12 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
|
||||
preChildOffset = offset;
|
||||
Resource secondChild = Resource.Deserialize(content, ref offset);
|
||||
if (secondChild.Key == "StringFileInfo")
|
||||
if (secondChild.Key == "StringFileInfo" || secondChild.Key == "\u0001StringFileInfo")
|
||||
{
|
||||
offset = preChildOffset;
|
||||
vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(content, ref offset);
|
||||
}
|
||||
else if (secondChild.Key == "VarFileInfo")
|
||||
else if (secondChild.Key == "VarFileInfo" || secondChild.Key == "\u0001VarFileInfo")
|
||||
{
|
||||
offset = preChildOffset;
|
||||
vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(content, ref offset);
|
||||
|
||||
1
BurnOutSharp/External/LessIO
vendored
1
BurnOutSharp/External/LessIO
vendored
Submodule BurnOutSharp/External/LessIO deleted from 1def7d19cc
8
BurnOutSharp/External/README.MD
vendored
Normal file
8
BurnOutSharp/External/README.MD
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# External Library Notes
|
||||
|
||||
This directory contains multiple external libraries. Here is the status of each:
|
||||
|
||||
| Directory | Library | Status |
|
||||
| --------- | ------- | ------ |
|
||||
| psxt001z | [psxt001z](https://github.com/Dremora/psxt001z) | 90% ported to C#, device reading disabled |
|
||||
| stormlibsharp | [stormlibsharp](https://github.com/robpaveza/stormlibsharp) | External submodule |
|
||||
1
BurnOutSharp/External/hllib
vendored
1
BurnOutSharp/External/hllib
vendored
Submodule BurnOutSharp/External/hllib deleted from 2063e3e0cd
1
BurnOutSharp/External/libmspack4n
vendored
1
BurnOutSharp/External/libmspack4n
vendored
Submodule BurnOutSharp/External/libmspack4n deleted from 7213a361f8
6
BurnOutSharp/External/psxt001z/CRC16.cs
vendored
6
BurnOutSharp/External/psxt001z/CRC16.cs
vendored
@@ -1,9 +1,9 @@
|
||||
namespace BurnOutSharp.External.psxt001z
|
||||
namespace psxt001z
|
||||
{
|
||||
public class CRC16
|
||||
{
|
||||
// Table of CRC constants - implements x^16+x^12+x^5+1
|
||||
private static ushort[] crc16_tab = new ushort[]
|
||||
private static ushort[] CRC16Table = new ushort[]
|
||||
{
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
@@ -44,7 +44,7 @@
|
||||
ushort cksum = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
cksum = (ushort)(crc16_tab[((cksum >> 8) ^ buf[bufPtr++]) & 0xFF] ^ (cksum << 8));
|
||||
cksum = (ushort)(CRC16Table[((cksum >> 8) ^ buf[bufPtr++]) & 0xFF] ^ (cksum << 8));
|
||||
}
|
||||
|
||||
return (ushort)(~cksum);
|
||||
|
||||
57
BurnOutSharp/External/psxt001z/CRC32.cs
vendored
Normal file
57
BurnOutSharp/External/psxt001z/CRC32.cs
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
namespace psxt001z
|
||||
{
|
||||
internal class CRC32
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private const uint CRC_POLY = 0xEDB88320;
|
||||
|
||||
private const uint CRC_MASK = 0xD202EF8D;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
protected uint[] Table { get; private set; } = new uint[256];
|
||||
|
||||
public uint m_crc32 { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public CRC32()
|
||||
{
|
||||
for (uint i = 0; i < 256; i++)
|
||||
{
|
||||
uint r, j;
|
||||
for (r = i, j = 8; j != 0; j--)
|
||||
{
|
||||
r = ((r & 1) != 0) ? (r >> 1) ^ CRC_POLY : r >> 1;
|
||||
}
|
||||
|
||||
Table[i] = r;
|
||||
}
|
||||
|
||||
m_crc32 = 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Functions
|
||||
|
||||
public void ProcessCRC(byte[] pData, int pDataPtr, int nLen)
|
||||
{
|
||||
uint crc = m_crc32;
|
||||
while (nLen-- != 0)
|
||||
{
|
||||
crc = Table[(byte)(crc ^ pData[pDataPtr++])] ^ crc >> 8;
|
||||
crc ^= CRC_MASK;
|
||||
}
|
||||
|
||||
m_crc32 = crc;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
19
BurnOutSharp/External/psxt001z/Common.cs
vendored
Normal file
19
BurnOutSharp/External/psxt001z/Common.cs
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace psxt001z
|
||||
{
|
||||
public static class Common
|
||||
{
|
||||
public const int ZERO = 0;
|
||||
|
||||
public const string VERSION = "v0.21 beta 1";
|
||||
|
||||
/// <summary>
|
||||
/// BCD to u_char
|
||||
/// </summary>
|
||||
public static byte btoi(byte b) => (byte)(((b) / 16 * 10 + (b) % 16));
|
||||
|
||||
/// <summary>
|
||||
/// u_char to BCD
|
||||
/// </summary>
|
||||
public static byte itob(byte i) => (byte)(((i) / 10 * 16 + (i) % 10));
|
||||
}
|
||||
}
|
||||
178
BurnOutSharp/External/psxt001z/FileTools.cs
vendored
Normal file
178
BurnOutSharp/External/psxt001z/FileTools.cs
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace psxt001z
|
||||
{
|
||||
internal class FileTools
|
||||
{
|
||||
#region Properties
|
||||
|
||||
private Stream InputStream { get; set; }
|
||||
|
||||
private byte[] ExeName { get; set; } = new byte[20];
|
||||
|
||||
private byte[] DateValue { get; set; } = new byte[11];
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public FileTools(Stream file)
|
||||
{
|
||||
InputStream = file;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Functions
|
||||
|
||||
/// <summary>
|
||||
/// Get file size
|
||||
/// </summary>
|
||||
public long size() => InputStream.Length;
|
||||
|
||||
/// <summary>
|
||||
/// Get executable name
|
||||
/// </summary>
|
||||
public string exe()
|
||||
{
|
||||
InputStream.Seek(51744, SeekOrigin.Begin);
|
||||
|
||||
string filename = string.Empty;
|
||||
while (filename != "SYSTEM.CNF")
|
||||
{
|
||||
byte[] buf = new byte[10];
|
||||
InputStream.Read(buf, 0, 10);
|
||||
filename = Encoding.ASCII.GetString(buf);
|
||||
InputStream.Seek(-9, SeekOrigin.Current);
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[20];
|
||||
|
||||
InputStream.Seek(-32, SeekOrigin.Current);
|
||||
InputStream.Read(buffer, 0, 4);
|
||||
uint lba = BitConverter.ToUInt32(buffer, 0);
|
||||
|
||||
InputStream.Seek((2352 * lba) + 29, SeekOrigin.Begin);
|
||||
InputStream.Read(buffer, 0, 6);
|
||||
|
||||
string iniLine = Encoding.ASCII.GetString(buffer);
|
||||
while (iniLine != "cdrom:")
|
||||
{
|
||||
InputStream.Seek(-5, SeekOrigin.Current);
|
||||
InputStream.Read(buffer, 0, 6);
|
||||
iniLine = Encoding.ASCII.GetString(buffer);
|
||||
}
|
||||
|
||||
InputStream.Read(buffer, 0, 1);
|
||||
if (buffer[0] != '\\')
|
||||
InputStream.Seek(-1, SeekOrigin.Current);
|
||||
|
||||
int i = -1;
|
||||
do
|
||||
{
|
||||
InputStream.Read(buffer, ++i, 1);
|
||||
} while (buffer[i] != ';');
|
||||
|
||||
for (long a = 0; a < i; a++)
|
||||
{
|
||||
ExeName[a] = (byte)char.ToUpper((char)buffer[a]);
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString(ExeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get human-readable date
|
||||
/// </summary>
|
||||
public string date()
|
||||
{
|
||||
byte[] buffer = new byte[12], datenofrmt = new byte[3];
|
||||
|
||||
InputStream.Seek(51744, SeekOrigin.Begin);
|
||||
|
||||
do
|
||||
{
|
||||
InputStream.Read(buffer, 0, 11);
|
||||
buffer[11] = 0;
|
||||
InputStream.Seek(-10, SeekOrigin.Current);
|
||||
} while (Encoding.ASCII.GetString(ExeName) != Encoding.ASCII.GetString(buffer));
|
||||
|
||||
InputStream.Seek(-16, SeekOrigin.Current);
|
||||
InputStream.Read(datenofrmt, 0, 3);
|
||||
|
||||
if (datenofrmt[0] < 50)
|
||||
{
|
||||
byte[] year = Encoding.ASCII.GetBytes($"{2000 + datenofrmt[0]}");
|
||||
Array.Copy(year, 0, buffer, 0, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] year = Encoding.ASCII.GetBytes($"{1900 + datenofrmt[0]}");
|
||||
Array.Copy(year, 0, buffer, 0, 4);
|
||||
}
|
||||
|
||||
DateValue[4] = (byte)'-';
|
||||
if (datenofrmt[1] < 10)
|
||||
{
|
||||
byte[] month = Encoding.ASCII.GetBytes($"0{datenofrmt[1]}");
|
||||
Array.Copy(month, 0, buffer, 5, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] month = Encoding.ASCII.GetBytes($"{datenofrmt[1]}");
|
||||
Array.Copy(month, 0, buffer, 5, 2);
|
||||
}
|
||||
|
||||
DateValue[7] = (byte)'-';
|
||||
if (datenofrmt[2] < 10)
|
||||
{
|
||||
byte[] day = Encoding.ASCII.GetBytes($"0{datenofrmt[2]}");
|
||||
Array.Copy(day, 0, buffer, 8, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] day = Encoding.ASCII.GetBytes($"{datenofrmt[2]}");
|
||||
Array.Copy(day, 0, buffer, 8, 2);
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString(DateValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resize the image
|
||||
/// </summary>
|
||||
public int resize(long newsize)
|
||||
{
|
||||
long oldsize = size();
|
||||
if (oldsize < newsize)
|
||||
{
|
||||
InputStream.SetLength(newsize);
|
||||
return 1;
|
||||
}
|
||||
else if (oldsize > newsize)
|
||||
{
|
||||
InputStream.SetLength(newsize);
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the reported sector count from the image
|
||||
/// </summary>
|
||||
public int imagesize()
|
||||
{
|
||||
InputStream.Seek(0x9368, SeekOrigin.Begin);
|
||||
byte[] sizebuf = new byte[4];
|
||||
InputStream.Read(sizebuf, 0, 4);
|
||||
return BitConverter.ToInt32(sizebuf, 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
108
BurnOutSharp/External/psxt001z/Functions.cs
vendored
Normal file
108
BurnOutSharp/External/psxt001z/Functions.cs
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using static psxt001z.Common;
|
||||
|
||||
namespace psxt001z
|
||||
{
|
||||
internal static class Functions
|
||||
{
|
||||
public static int CalculateEDC(in byte[] src, int srcPtr, int size, int[] edc_lut)
|
||||
{
|
||||
int edc = 0;
|
||||
while (size-- != 0)
|
||||
{
|
||||
edc = (edc >> 8) ^ edc_lut[(edc ^ src[srcPtr++]) & 0xFF];
|
||||
}
|
||||
|
||||
return edc;
|
||||
}
|
||||
|
||||
public static bool ZeroCompare(byte[] buffer, int bufferPtr, int bsize)
|
||||
{
|
||||
for (int i = 0; i < bsize; i++)
|
||||
{
|
||||
if (buffer[bufferPtr + i] != 0x00)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void MSF(long lba, byte[] buffer, int bufferOffset)
|
||||
{
|
||||
lba += 150;
|
||||
|
||||
double mindbl = lba / 60 / 75;
|
||||
byte min = (byte)Math.Floor(mindbl);
|
||||
double secdbl = (lba - (min * 60 * 75)) / 75;
|
||||
byte sec = (byte)Math.Floor(secdbl);
|
||||
byte frame = (byte)(lba - (min * 60 * 75) - (sec * 75));
|
||||
|
||||
buffer[bufferOffset] = itob(min);
|
||||
buffer[bufferOffset + 1] = itob(sec);
|
||||
buffer[bufferOffset + 2] = itob(frame);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public static bool GetEDCStatus(Stream file)
|
||||
{
|
||||
long currentposition = file.Position;
|
||||
|
||||
file.Seek(30572, SeekOrigin.Begin);
|
||||
|
||||
byte[] buffer = new byte[4];
|
||||
file.Read(buffer, 0, 4);
|
||||
|
||||
file.Seek(currentposition, SeekOrigin.Begin);
|
||||
|
||||
return BitConverter.ToInt32(buffer, 0) == 0;
|
||||
}
|
||||
|
||||
public static byte[] ExecutableName(Stream file)
|
||||
{
|
||||
byte[] buffer = new byte[20];
|
||||
byte[] exename = new byte[20];
|
||||
|
||||
//Searching for SYSTEM.CNF
|
||||
file.Seek(51744, SeekOrigin.Begin);
|
||||
while (Encoding.ASCII.GetString(buffer) != "SYSTEM.CNF")
|
||||
{
|
||||
file.Read(buffer, 0, 10);
|
||||
buffer[10] = 0;
|
||||
file.Seek(-9, SeekOrigin.Current);
|
||||
}
|
||||
|
||||
file.Seek(-32, SeekOrigin.Current);
|
||||
byte[] lba = new byte[4];
|
||||
file.Read(lba, 0, 4);
|
||||
file.Seek((2352 * BitConverter.ToInt32(lba, 0)) + 29, SeekOrigin.Begin);
|
||||
file.Read(buffer, 0, 6);
|
||||
buffer[6] = 0;
|
||||
while (Encoding.ASCII.GetString(buffer) != "cdrom:")
|
||||
{
|
||||
file.Seek(-5, SeekOrigin.Current);
|
||||
file.Read(buffer, 0, 6);
|
||||
}
|
||||
|
||||
file.Read(buffer, 0, 1);
|
||||
if (buffer[0] != '\\')
|
||||
file.Seek(-1, SeekOrigin.Current);
|
||||
|
||||
int i = -1;
|
||||
do
|
||||
{
|
||||
file.Read(buffer, ++i, 1);
|
||||
} while (buffer[i] != ';');
|
||||
|
||||
for (int a = 0; a < i; a++)
|
||||
{
|
||||
exename[a] = (byte)char.ToUpper((char)buffer[a]);
|
||||
}
|
||||
|
||||
exename[i] = 0;
|
||||
return exename;
|
||||
}
|
||||
}
|
||||
}
|
||||
293
BurnOutSharp/External/psxt001z/Info.cs
vendored
Normal file
293
BurnOutSharp/External/psxt001z/Info.cs
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using static psxt001z.Functions;
|
||||
|
||||
namespace psxt001z
|
||||
{
|
||||
public class Info
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private static readonly byte[] edc_form_2 = { 0x3F, 0x13, 0xB0, 0xBE };
|
||||
|
||||
private static readonly byte[] syncheader = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
private static readonly byte[] subheader = { 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00 };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Functions
|
||||
|
||||
public static int GetInfo(string filename, bool fix)
|
||||
{
|
||||
// Variables
|
||||
bool errors = false;
|
||||
byte[] buffer = new byte[2352], buffer2 = new byte[2352];
|
||||
int mode = 15; // synñheader[15];
|
||||
|
||||
#region Opening image
|
||||
|
||||
Stream image;
|
||||
try
|
||||
{
|
||||
FileAccess open_mode = fix ? FileAccess.ReadWrite : FileAccess.Read;
|
||||
image = File.Open(filename, FileMode.Open, open_mode);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine(ex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
long size = image.Length;
|
||||
Console.WriteLine($"File: {filename}");
|
||||
|
||||
#endregion
|
||||
|
||||
#region Type
|
||||
|
||||
image.Read(buffer, 0, 12);
|
||||
|
||||
int sectorsize;
|
||||
if (buffer.Take(12).SequenceEqual(syncheader.Take(12)))
|
||||
{
|
||||
sectorsize = 2352;
|
||||
}
|
||||
else
|
||||
{
|
||||
sectorsize = 2048;
|
||||
}
|
||||
if (size % sectorsize != 0)
|
||||
{
|
||||
Console.WriteLine($"{filename}: not ModeX/{sectorsize} image!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
long sectors = size / sectorsize;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mode
|
||||
|
||||
if (sectorsize == 2352)
|
||||
{
|
||||
image.Seek(0xF, SeekOrigin.Begin);
|
||||
mode = image.ReadByte();
|
||||
if (mode != 1 && mode != 2)
|
||||
{
|
||||
Console.WriteLine($"{filename}: unknown mode!");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = -1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Size
|
||||
|
||||
image.Seek(sectorsize * 16 + ((mode == 2) ? 24 : ((mode == 1) ? 16 : 0)) + 0x50, SeekOrigin.Begin);
|
||||
|
||||
// ISO size
|
||||
byte[] buf = new byte[4];
|
||||
image.Read(buf, 0, 4);
|
||||
int realsectors = BitConverter.ToInt32(buf, 0);
|
||||
|
||||
image.Seek(0, SeekOrigin.Begin);
|
||||
int realsize = realsectors * sectorsize;
|
||||
if (sectors == realsectors)
|
||||
{
|
||||
Console.WriteLine($"Size (bytes): {size} (OK)");
|
||||
Console.WriteLine($"Size (sectors): {sectors} (OK)");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Size (bytes): {size}");
|
||||
Console.WriteLine($"From image: {realsize}");
|
||||
Console.WriteLine($"Size (sectors): {sectors}");
|
||||
Console.WriteLine($"From image: {realsectors}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mode
|
||||
|
||||
if (mode > 0)
|
||||
Console.WriteLine($"Mode: {mode}");
|
||||
|
||||
if (mode == 2)
|
||||
{
|
||||
#region EDC in Form 2
|
||||
|
||||
bool imageedc = GetEDCStatus(image);
|
||||
Console.WriteLine($"EDC in Form 2 sectors: {(imageedc ? "YES" : "NO")}");
|
||||
|
||||
#endregion
|
||||
|
||||
#region Sysarea
|
||||
|
||||
string systemArea = "System area: ";
|
||||
image.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
CRC32 crc = new CRC32();
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
image.Read(buffer, 0, 2352);
|
||||
crc.ProcessCRC(buffer, 0, 2352);
|
||||
}
|
||||
|
||||
uint imagecrc = crc.m_crc32;
|
||||
systemArea += GetEdcType(imagecrc);
|
||||
|
||||
Console.WriteLine(systemArea);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Postgap
|
||||
|
||||
image.Seek((sectors - 150) * sectorsize + 16, SeekOrigin.Begin);
|
||||
image.Read(buffer, 0, 2336);
|
||||
|
||||
string postgap = "Postgap type: Form ";
|
||||
if ((buffer[2] >> 5 & 0x1) != 0)
|
||||
{
|
||||
postgap += "2";
|
||||
if (buffer.Take(8).SequenceEqual(subheader))
|
||||
postgap += ", zero subheader";
|
||||
else
|
||||
postgap += ", non-zero subheader";
|
||||
|
||||
if (ZeroCompare(buffer, 8, 2324))
|
||||
postgap += ", zero data";
|
||||
else
|
||||
postgap += ", non-zero data";
|
||||
|
||||
if (ZeroCompare(buffer, 2332, 4))
|
||||
postgap += ", no EDC";
|
||||
else
|
||||
postgap += ", EDC";
|
||||
}
|
||||
else
|
||||
{
|
||||
postgap += "1";
|
||||
if (ZeroCompare(buffer, 0, 8))
|
||||
postgap += ", zero subheader";
|
||||
else
|
||||
postgap += ", non-zero subheader";
|
||||
|
||||
if (ZeroCompare(buffer, 8, 2328))
|
||||
postgap += ", zero data";
|
||||
else
|
||||
postgap += ", non-zero data";
|
||||
}
|
||||
|
||||
Console.WriteLine(postgap);
|
||||
Array.Copy(buffer, buffer2, 2336);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
if (mode < 0)
|
||||
return 0;
|
||||
|
||||
for (long sector = sectors - 150; sector < sectors; sector++)
|
||||
{
|
||||
bool bad = false;
|
||||
image.Seek(sector * sectorsize, SeekOrigin.Begin);
|
||||
image.Read(buffer, 0, sectorsize);
|
||||
|
||||
// Sync
|
||||
string sectorInfo = string.Empty;
|
||||
|
||||
MSF(sector, syncheader, 12);
|
||||
if (!syncheader.SequenceEqual(buffer.Take(16)))
|
||||
{
|
||||
sectorInfo += $"Sector {sector}: Sync/Header";
|
||||
bad = true;
|
||||
if (fix)
|
||||
{
|
||||
image.Seek(sector * sectorsize, SeekOrigin.Begin);
|
||||
image.Write(syncheader, 0, 16);
|
||||
sectorInfo += (" (fixed)");
|
||||
}
|
||||
}
|
||||
|
||||
// Mode 2
|
||||
if (mode == 2 && buffer.Skip(16).Take(2336).SequenceEqual(buffer2))
|
||||
{
|
||||
if (bad)
|
||||
{
|
||||
sectorInfo += ", Subheader/Data/EDC/ECC";
|
||||
}
|
||||
else
|
||||
{
|
||||
sectorInfo = $"Sector {sector}: Subheader/Data/EDC/ECC";
|
||||
bad = true;
|
||||
}
|
||||
|
||||
if (fix)
|
||||
{
|
||||
image.Seek(sector * sectorsize + 16, SeekOrigin.Begin);
|
||||
image.Write(buffer2, 0, 2336);
|
||||
sectorInfo += " (fixed)";
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine(sectorInfo);
|
||||
|
||||
if (bad && (sector + 1 != sectors))
|
||||
errors = true;
|
||||
}
|
||||
|
||||
if (errors)
|
||||
{
|
||||
Console.WriteLine("NOTICE: One or more errors were found not in the last sector.");
|
||||
Console.WriteLine("Please mention this when submitting dump info.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Done.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Utilities
|
||||
|
||||
internal static string GetEdcType(uint imageCrc)
|
||||
{
|
||||
switch (imageCrc)
|
||||
{
|
||||
case 0x11e3052d:
|
||||
return "Eu EDC";
|
||||
case 0x808c19f6:
|
||||
return "Eu NoEDC";
|
||||
case 0x70ffa73e:
|
||||
return "Eu Alt NoEDC";
|
||||
case 0x7f9a25b1:
|
||||
return "Eu Alt 2 EDC";
|
||||
case 0x783aca30:
|
||||
return "Jap EDC";
|
||||
case 0xe955d6eb:
|
||||
return "Jap NoEDC";
|
||||
case 0x9b519a2e:
|
||||
return "US EDC";
|
||||
case 0x0a3e86f5:
|
||||
return "US NoEDC";
|
||||
case 0x6773d4db:
|
||||
return "US Alt NoEDC";
|
||||
default:
|
||||
return $"Unknown, crc {imageCrc:8x}";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
721
BurnOutSharp/External/psxt001z/LibCrypt.cs
vendored
721
BurnOutSharp/External/psxt001z/LibCrypt.cs
vendored
@@ -1,16 +1,44 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using static psxt001z.Common;
|
||||
|
||||
namespace BurnOutSharp.External.psxt001z
|
||||
namespace psxt001z
|
||||
{
|
||||
/// <summary>
|
||||
/// LibCrypt detection code
|
||||
/// Originally written by Dremora: https://github.com/Dremora/psxt001z
|
||||
/// Ported and changed by darksabre76
|
||||
/// </summary>
|
||||
internal class ScsiPassThroughDirect
|
||||
{
|
||||
public ushort Length { get; set; }
|
||||
|
||||
public byte ScsiStatus { get; set; }
|
||||
|
||||
public byte PathId { get; set; }
|
||||
|
||||
public byte TargetId { get; set; }
|
||||
|
||||
public byte Lun { get; set; }
|
||||
|
||||
public byte CDBLength { get; set; }
|
||||
|
||||
public byte SenseInfoLength { get; set; }
|
||||
|
||||
public byte DataIn { get; set; }
|
||||
|
||||
public uint DataTransferLength { get; set; }
|
||||
|
||||
public uint TimeOutValue { get; set; }
|
||||
|
||||
public byte[] DataBuffer { get; set; }
|
||||
|
||||
public uint SenseInfoOffset { get; set; }
|
||||
|
||||
public byte[] CDB { get; set; } = new byte[16];
|
||||
}
|
||||
|
||||
public class LibCrypt
|
||||
{
|
||||
#region OLD
|
||||
|
||||
public static bool CheckSubfile(string subFilePath)
|
||||
{
|
||||
// Check the file exists first
|
||||
@@ -113,16 +141,685 @@ namespace BurnOutSharp.External.psxt001z
|
||||
return modifiedSectors != 0;
|
||||
}
|
||||
|
||||
private static byte btoi(byte b)
|
||||
#endregion
|
||||
|
||||
#region Constants
|
||||
|
||||
private const uint IOCTL_SCSI_PASS_THROUGH_DIRECT = 0x4D014;
|
||||
private const byte SCSI_IOCTL_DATA_IN = 0x1;
|
||||
private const byte RAW_READ_CMD = 0xBE;
|
||||
private const int BUFFER_LEN = 96;
|
||||
private const int SENSE_SIZE = 0; //14
|
||||
private const string F_NAME = "sectors.log";
|
||||
private const int CYCLES = 5;
|
||||
private const int LIBCRYPT_NUM_SECTORS = 64;
|
||||
private const int READ_TIMES = 5;
|
||||
|
||||
private static readonly uint[] lc_addresses = new uint[LIBCRYPT_NUM_SECTORS]
|
||||
{
|
||||
13955, 13960, 14081, 14086, 14335, 14340, 14429, 14434,
|
||||
14499, 14504, 14749, 14754, 14906, 14911, 14980, 14985,
|
||||
15092, 15097, 15162, 15167, 15228, 15233, 15478, 15483,
|
||||
15769, 15774, 15881, 15886, 15951, 15956, 16017, 16022,
|
||||
41895, 41900, 42016, 42021, 42282, 42287, 42430, 42435,
|
||||
42521, 42526, 42663, 42668, 42862, 42867, 43027, 43032,
|
||||
43139, 43144, 43204, 43209, 43258, 43263, 43484, 43489,
|
||||
43813, 43818, 43904, 43909, 44009, 44014, 44162, 44167
|
||||
};
|
||||
|
||||
private static readonly byte[] lc1_sectors_contents = new byte[768]
|
||||
{
|
||||
/* BCD to u_char */
|
||||
return (byte)((b) / 16 * 10 + (b) % 16);
|
||||
0x41, 0x01, 0x01, 0x07, 0x06, 0x05, 0x00, 0x23, 0x08, 0x05, 0x38, 0x39,
|
||||
0x41, 0x01, 0x01, 0x03, 0x06, 0x11, 0x00, 0x03, 0x08, 0x90, 0x5d, 0xa0,
|
||||
0x41, 0x01, 0x01, 0x07, 0x07, 0x56, 0x00, 0x23, 0x09, 0x56, 0xdf, 0xde,
|
||||
0x41, 0x01, 0x01, 0x03, 0x07, 0x60, 0x00, 0x03, 0x09, 0xe1, 0xf2, 0x50,
|
||||
0x41, 0x01, 0x01, 0x03, 0x13, 0x10, 0x00, 0x03, 0x53, 0x10, 0x50, 0xec,
|
||||
0x41, 0x01, 0x01, 0x43, 0x11, 0x15, 0x00, 0x01, 0x13, 0x15, 0x23, 0x1e,
|
||||
0x41, 0x01, 0x01, 0x03, 0x12, 0x09, 0x00, 0x03, 0x14, 0x2d, 0x04, 0x73,
|
||||
0x41, 0x01, 0x01, 0x03, 0x1a, 0x34, 0x00, 0x03, 0x04, 0x34, 0xe2, 0xcf,
|
||||
0x41, 0x01, 0x01, 0x03, 0x13, 0x20, 0x00, 0x03, 0x15, 0x04, 0x82, 0x35,
|
||||
0x41, 0x01, 0x01, 0x01, 0x13, 0x29, 0x00, 0x43, 0x15, 0x29, 0x72, 0xe2,
|
||||
0x41, 0x01, 0x01, 0x03, 0x1e, 0x49, 0x00, 0x03, 0x08, 0x49, 0x32, 0xc5,
|
||||
0x41, 0x01, 0x01, 0x01, 0x16, 0x54, 0x00, 0x43, 0x18, 0x54, 0xd4, 0x79,
|
||||
0x41, 0x01, 0x01, 0x03, 0x18, 0x57, 0x00, 0x03, 0x20, 0xd6, 0xbc, 0x27,
|
||||
0x41, 0x01, 0x01, 0x03, 0x38, 0x61, 0x00, 0x03, 0x24, 0x61, 0x91, 0xa9,
|
||||
0x41, 0x01, 0x01, 0x0b, 0x19, 0x55, 0x00, 0x13, 0x21, 0x55, 0x14, 0x07,
|
||||
0x41, 0x01, 0x01, 0x03, 0x19, 0x62, 0x00, 0x03, 0x21, 0x20, 0x5d, 0x48,
|
||||
0x41, 0x01, 0x01, 0x03, 0x23, 0x17, 0x00, 0x03, 0x63, 0x17, 0x6d, 0xc6,
|
||||
0x41, 0x01, 0x01, 0x43, 0x21, 0x22, 0x00, 0x01, 0x23, 0x22, 0x24, 0x89,
|
||||
0x41, 0x01, 0x01, 0x03, 0x02, 0x12, 0x00, 0x03, 0x20, 0x12, 0x49, 0x43,
|
||||
0x41, 0x01, 0x01, 0x03, 0x22, 0x07, 0x00, 0x03, 0x24, 0x1f, 0x3a, 0xb1,
|
||||
0x41, 0x01, 0x01, 0x03, 0x23, 0x13, 0x00, 0x03, 0x25, 0x0b, 0x93, 0xc9,
|
||||
0x41, 0x01, 0x01, 0x0b, 0x23, 0x08, 0x00, 0x13, 0x25, 0x08, 0xce, 0x5d,
|
||||
0x41, 0x01, 0x01, 0x03, 0x06, 0x28, 0x00, 0x03, 0x2c, 0x28, 0xd7, 0xd6,
|
||||
0x41, 0x01, 0x01, 0x0b, 0x26, 0x33, 0x00, 0x13, 0x28, 0x33, 0x9c, 0x29,
|
||||
0x41, 0x01, 0x01, 0x03, 0x30, 0x59, 0x00, 0x03, 0x32, 0x1b, 0x2c, 0xc6,
|
||||
0x41, 0x01, 0x01, 0x03, 0x20, 0x24, 0x00, 0x03, 0x3a, 0x24, 0xe6, 0xac,
|
||||
0x41, 0x01, 0x01, 0x13, 0x31, 0x56, 0x00, 0x0b, 0x33, 0x56, 0x97, 0xed,
|
||||
0x41, 0x01, 0x01, 0x03, 0x31, 0x65, 0x00, 0x03, 0x33, 0x41, 0xba, 0x63,
|
||||
0x41, 0x01, 0x01, 0x01, 0x32, 0x51, 0x00, 0x43, 0x34, 0x51, 0xd7, 0xa9,
|
||||
0x41, 0x01, 0x01, 0x03, 0x33, 0x56, 0x00, 0x03, 0xb4, 0x56, 0xc0, 0x9a,
|
||||
0x41, 0x01, 0x01, 0x03, 0x32, 0x42, 0x00, 0x03, 0xb5, 0x42, 0x69, 0xe2,
|
||||
0x41, 0x01, 0x01, 0x03, 0x33, 0x07, 0x00, 0x03, 0x35, 0x45, 0x1a, 0x10,
|
||||
0x41, 0x01, 0x01, 0x09, 0x18, 0x65, 0x00, 0x09, 0x20, 0x41, 0x40, 0x72,
|
||||
0x41, 0x01, 0x01, 0x19, 0x18, 0x50, 0x00, 0x01, 0x20, 0x50, 0x25, 0xeb,
|
||||
0x41, 0x01, 0x01, 0x08, 0x20, 0x16, 0x00, 0x89, 0x22, 0x16, 0x95, 0xa8,
|
||||
0x41, 0x01, 0x01, 0x09, 0x20, 0x01, 0x00, 0x09, 0x22, 0x25, 0xb8, 0x26,
|
||||
0x41, 0x01, 0x01, 0x09, 0x23, 0x53, 0x00, 0x09, 0x25, 0x77, 0x21, 0x03,
|
||||
0x41, 0x01, 0x01, 0x0b, 0x23, 0x62, 0x00, 0x49, 0x25, 0x62, 0x68, 0x4c,
|
||||
0x41, 0x01, 0x01, 0x0d, 0x25, 0x55, 0x00, 0x29, 0x27, 0x55, 0xae, 0x41,
|
||||
0x41, 0x01, 0x01, 0x09, 0x25, 0x61, 0x00, 0x09, 0x27, 0xe0, 0xe7, 0x0e,
|
||||
0x41, 0x01, 0x01, 0x08, 0x26, 0x71, 0x00, 0x89, 0x28, 0x71, 0x95, 0xcb,
|
||||
0x41, 0x01, 0x01, 0x09, 0x27, 0x21, 0x00, 0x09, 0x29, 0x05, 0x80, 0x4b,
|
||||
0x41, 0x01, 0x01, 0x0b, 0x28, 0x63, 0x00, 0x49, 0x30, 0x63, 0xed, 0x18,
|
||||
0x41, 0x01, 0x01, 0x09, 0x29, 0x68, 0x00, 0x09, 0xb0, 0x68, 0xb0, 0x8c,
|
||||
0x41, 0x01, 0x01, 0x29, 0x31, 0x37, 0x00, 0x0d, 0x33, 0x37, 0x6c, 0x68,
|
||||
0x41, 0x01, 0x01, 0x09, 0x31, 0x4a, 0x00, 0x09, 0x33, 0x52, 0x7c, 0x8b,
|
||||
0x41, 0x01, 0x01, 0x09, 0x73, 0x52, 0x00, 0x09, 0x37, 0x52, 0x4b, 0x06,
|
||||
0x41, 0x01, 0x01, 0x19, 0x33, 0x57, 0x00, 0x01, 0x35, 0x57, 0x38, 0xf4,
|
||||
0x41, 0x01, 0x01, 0x09, 0x35, 0x04, 0x00, 0x09, 0x37, 0x1c, 0x54, 0x6a,
|
||||
0x41, 0x01, 0x01, 0x09, 0x31, 0x19, 0x00, 0x09, 0x17, 0x19, 0xa4, 0xbd,
|
||||
0x41, 0x01, 0x01, 0x01, 0x36, 0x04, 0x00, 0x19, 0x38, 0x04, 0x9c, 0xdf,
|
||||
0x41, 0x01, 0x01, 0x09, 0x36, 0x0b, 0x00, 0x09, 0x38, 0x49, 0x6c, 0x08,
|
||||
0x41, 0x01, 0x01, 0x49, 0x36, 0x58, 0x00, 0x0b, 0x38, 0x58, 0x99, 0xbf,
|
||||
0x41, 0x01, 0x01, 0x09, 0x36, 0x73, 0x00, 0x09, 0x38, 0x6b, 0xfe, 0x96,
|
||||
0x41, 0x01, 0x01, 0x0b, 0x39, 0x59, 0x00, 0x49, 0x41, 0x59, 0x54, 0x0d,
|
||||
0x41, 0x01, 0x01, 0x09, 0x39, 0x24, 0x00, 0x09, 0x41, 0x66, 0x9e, 0x67,
|
||||
0x41, 0x01, 0x01, 0x09, 0x44, 0x1b, 0x00, 0x09, 0x46, 0x03, 0x78, 0x0d,
|
||||
0x41, 0x01, 0x01, 0x09, 0x46, 0x18, 0x00, 0x09, 0x06, 0x18, 0x25, 0x99,
|
||||
0x41, 0x01, 0x01, 0x09, 0x45, 0x2b, 0x00, 0x09, 0x47, 0x69, 0xd3, 0xc5,
|
||||
0x41, 0x01, 0x01, 0x09, 0x05, 0x34, 0x00, 0x09, 0x45, 0x34, 0x35, 0x79,
|
||||
0x41, 0x01, 0x01, 0x09, 0x44, 0x59, 0x00, 0x09, 0x08, 0x59, 0x6e, 0x0a,
|
||||
0x41, 0x01, 0x01, 0x49, 0x46, 0x64, 0x00, 0x0b, 0x48, 0x64, 0xa4, 0x60,
|
||||
0x41, 0x01, 0x01, 0x09, 0x08, 0x62, 0x00, 0x09, 0x52, 0x62, 0x03, 0x5a,
|
||||
0x41, 0x01, 0x01, 0x19, 0x48, 0x67, 0x00, 0x01, 0x50, 0x67, 0x70, 0xa8
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Enable the following only if reading from a drive directly
|
||||
|
||||
/*
|
||||
internal static byte LibCryptDrive(string[] args)
|
||||
{
|
||||
byte offset = 0;
|
||||
string path = $"\\\\.\\{args[0][0]}:";
|
||||
byte i;
|
||||
byte[] sub = new byte[12], buffer = new byte[BUFFER_LEN], buffer2352 = new byte[23520], buffer2 = new byte[BUFFER_LEN], buffer3 = new byte[BUFFER_LEN], buffer4 = new byte[BUFFER_LEN];
|
||||
byte[] status;
|
||||
ushort crc;
|
||||
uint sector, sector_start, sector_end, a, lcsectors = 0, todo = 9300, done = 0;
|
||||
|
||||
if (args.Length != 1 || (args.Length == 1 && (args[0][1] != 0 && (args[0][1] != ':' || args[0][2] != 0))))
|
||||
{
|
||||
Console.WriteLine("LibCrypt drive detector");
|
||||
Console.WriteLine("nUsage: psxt001z.exe --libcryptdrv <drive letter>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Stream hDevice;
|
||||
try
|
||||
{
|
||||
hDevice = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Can't open device!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Stream f;
|
||||
try
|
||||
{
|
||||
f = File.Open(F_NAME, FileMode.Open, FileAccess.Write);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Can't open file {F_NAME}!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte[] status1 = new byte[4650];
|
||||
byte[] status2 = new byte[4650];
|
||||
|
||||
// Offset detection
|
||||
Console.WriteLine("Determining offset...\r");
|
||||
ScsiPassThroughDirect SRB = new ScsiPassThroughDirect();
|
||||
ReadSub(buffer, 0, f, offset, hDevice, SRB);
|
||||
|
||||
switch (buffer[8])
|
||||
{
|
||||
case 0x01:
|
||||
offset = (byte)(75 - btoi(buffer[9]));
|
||||
break;
|
||||
case 0x02:
|
||||
offset = (byte)(-btoi(buffer[9]));
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("Can't determine offset!");
|
||||
Console.WriteLine(BitConverter.ToString(buffer).Replace('-', ' '));
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub[0] = buffer[0];
|
||||
sub[1] = 0x01;
|
||||
sub[2] = 0x01;
|
||||
sub[6] = 0x00;
|
||||
|
||||
Console.WriteLine($"Subchannels offset correction: {offset}");
|
||||
|
||||
// Section 1) 02:58:00 - 03:69:74 -- status1
|
||||
// Section 2) 08:58:00 - 09:69:74 -- status2
|
||||
|
||||
// Step 1
|
||||
|
||||
for (i = 0; i < CYCLES * 3; i++)
|
||||
{
|
||||
|
||||
if (todo == 0)
|
||||
goto end;
|
||||
|
||||
if (i % 3 == 0)
|
||||
{
|
||||
sector_start = 13350;
|
||||
sector_end = 18000;
|
||||
status = status1;
|
||||
}
|
||||
else if (i % 3 == 1)
|
||||
{
|
||||
sector_start = 40350;
|
||||
sector_end = 45000;
|
||||
status = status2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Left: {todo:4} / Flushing cache... \r");
|
||||
ClearCache(buffer2352, f, offset, hDevice, SRB);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (sector = sector_start; sector < sector_end; sector++)
|
||||
{
|
||||
if (status[sector - sector_start] != 0)
|
||||
continue;
|
||||
|
||||
ReadSub(buffer, sector, f, offset, hDevice, SRB);
|
||||
Console.WriteLine("Left: %4u / Sector %u... \r", todo, sector);
|
||||
// generating q-channel
|
||||
sub[3] = itob((byte)(sector / 60 / 75));
|
||||
sub[4] = itob((byte)((sector / 75) % 60));
|
||||
sub[5] = itob((byte)(sector % 75));
|
||||
sub[7] = itob((byte)((sector + 150) / 60 / 75));
|
||||
sub[8] = itob((byte)(((sector + 150) / 75) % 60));
|
||||
sub[9] = itob((byte)((sector + 150) % 75));
|
||||
crc = CRC16.Calculate(sub, 0, 10);
|
||||
sub[10] = (byte)(crc >> 8);
|
||||
sub[11] = (byte)(crc & 0xFF);
|
||||
if (sub.SequenceEqual(buffer.Take(12)))
|
||||
{
|
||||
status[sector - sector_start] = 1;
|
||||
todo--;
|
||||
done++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
sector_start = 13350;
|
||||
sector_end = 18000;
|
||||
status = status1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sector_start = 40350;
|
||||
sector_end = 45000;
|
||||
status = status2;
|
||||
}
|
||||
|
||||
for (sector = sector_start; sector < sector_end; sector++)
|
||||
{
|
||||
if (status[sector - sector_start] != 0)
|
||||
continue;
|
||||
ReadSub(buffer, sector, f, offset, hDevice, SRB);
|
||||
Console.WriteLine($"Left: {todo:4} / Sector {sector}... \r");
|
||||
|
||||
// generating q-channel
|
||||
sub[3] = itob((byte)(sector / 60 / 75));
|
||||
sub[4] = itob((byte)((sector / 75) % 60));
|
||||
sub[5] = itob((byte)(sector % 75));
|
||||
sub[7] = itob((byte)((sector + 150) / 60 / 75));
|
||||
sub[8] = itob((byte)(((sector + 150) / 75) % 60));
|
||||
sub[9] = itob((byte)((sector + 150) % 75));
|
||||
crc = CRC16.Calculate(sub, 0, 10);
|
||||
sub[10] = (byte)(crc >> 8);
|
||||
sub[11] = (byte)(crc ^ 0xFF);
|
||||
if (sub.SequenceEqual(buffer.Take(12)))
|
||||
{
|
||||
Console.WriteLine($"Left: {todo:4} / Sector {sector}: flushing cache... \r");
|
||||
do
|
||||
{
|
||||
ReadSub(buffer, sector, f, offset, hDevice, SRB);
|
||||
ClearCache(buffer2352, f, offset, hDevice, SRB);
|
||||
ReadSub(buffer2, sector, f, offset, hDevice, SRB);
|
||||
ClearCache(buffer2352, f, offset, hDevice, SRB);
|
||||
ReadSub(buffer3, sector, f, offset, hDevice, SRB);
|
||||
ClearCache(buffer2352, f, offset, hDevice, SRB);
|
||||
} while (!buffer.SequenceEqual(buffer2) || !buffer.SequenceEqual(buffer3));
|
||||
//} while (!matrix(buffer, buffer2, buffer3, buffer4, BUFFER_LEN));
|
||||
|
||||
if (buffer.SequenceEqual(sub))
|
||||
{
|
||||
byte[] buf = Encoding.ASCII.GetBytes($"MSF: {sub[7]:2x}:{sub[8]:2x}:{sub[9]:2x} Q-Data: {BitConverter.ToString(buffer.Take(12).ToArray()).Replace('-', ' ')}");
|
||||
f.Write(buf, 0, buf.Length);
|
||||
lcsectors++;
|
||||
//fwrite(SRB.SRB_BufPointer, 1, SRB.SRB_BufLen - 4, f);
|
||||
f.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
todo--;
|
||||
done++;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
Console.WriteLine($"Done! \nProtected sectors: {(lcsectors == 0 ? "None" : lcsectors.ToString())}");
|
||||
|
||||
f.Close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static byte itob(byte i)
|
||||
internal static int LibCryptDriveFast(string[] args)
|
||||
{
|
||||
/* u_char to BCD */
|
||||
return (byte)((i) / 10 * 16 + (i) % 10);
|
||||
Stream f;
|
||||
Stream hDevice;
|
||||
ScsiPassThroughDirect SRB;
|
||||
s8 offset = 0, path[] = "\\\\.\\X:";
|
||||
u8 buffer[BUFFER_LEN], buffer2352[23520], sub[12], lc1sectors = 0, lc2sectors = 0, othersectors = 0;
|
||||
u16 crc;
|
||||
|
||||
if (argc != 1 || (argc == 1 && (args[0][1] != 0 && (args[0][1] != ':' || args[0][2] != 0))))
|
||||
{
|
||||
Console.WriteLine("LibCrypt drive detector (fast)\nUsage: psxt001z.exe --libcryptdrvfast <drive letter>\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
path[4] = args[0][0];
|
||||
|
||||
if ((hDevice = CreateFile(path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Console.WriteLine("Can't open device!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fopen_s(&f, F_NAME, "wb") != 0)
|
||||
{
|
||||
Console.WriteLine("Can\'t open file %s!\n", F_NAME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Offset detection
|
||||
ReadSub(buffer, 0, f, offset, hDevice, SRB);
|
||||
//if (buffer[5] != buffer[9]) {
|
||||
// Console.WriteLine("Error determining offset!\nSector 0: %02x%02x%02x %02x:%02x:%02x %02x %02x:%02x:%02x %02x%02x\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11]);
|
||||
//}
|
||||
switch (buffer[8])
|
||||
{
|
||||
case 0x01:
|
||||
offset = 75 - btoi(buffer[9]);
|
||||
break;
|
||||
case 0x02:
|
||||
offset = -btoi(buffer[9]);
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("Can't determine offset!\nSector 0: %02x%02x%02x %02x:%02x:%02x %02x %02x:%02x:%02x %02x%02x\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11]);
|
||||
return 0;
|
||||
}
|
||||
Console.WriteLine("Subchannels offset correction: %d\n", offset);
|
||||
sub[0] = buffer[0];
|
||||
sub[1] = 0x01;
|
||||
sub[2] = 0x01;
|
||||
sub[6] = 0x00;
|
||||
|
||||
for (int i = 0; i < LIBCRYPT_NUM_SECTORS; i++)
|
||||
{
|
||||
Console.WriteLine("\nReading sector %u... ", lc_addresses[i]);
|
||||
ReadSub(buffer, lc_addresses[i], f, offset, hDevice, SRB);
|
||||
// generating q-channel
|
||||
sub[3] = itob(lc_addresses[i] / 60 / 75);
|
||||
sub[4] = itob((lc_addresses[i] / 75) % 60);
|
||||
sub[5] = itob(lc_addresses[i] % 75);
|
||||
sub[7] = itob((lc_addresses[i] + 150) / 60 / 75);
|
||||
sub[8] = itob(((lc_addresses[i] + 150) / 75) % 60);
|
||||
sub[9] = itob((lc_addresses[i] + 150) % 75);
|
||||
crc = crc16(sub, 10);
|
||||
sub[10] = HIbyte(crc);
|
||||
sub[11] = LObyte(crc);
|
||||
for (int a = 1; a <= READ_TIMES; a++)
|
||||
{
|
||||
if (!memcmp(sub, buffer, 12))
|
||||
{
|
||||
Console.WriteLine("original sector");
|
||||
break;
|
||||
}
|
||||
else if (!memcmp(lc1_sectors_contents + (12 * i), buffer, 12))
|
||||
{
|
||||
Console.WriteLine("LibCrypt, LC1 sector");
|
||||
fConsole.WriteLine(f, "MSF: %02x:%02x:%02x Q-Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", sub[7], sub[8], sub[9], buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11]);
|
||||
lc1sectors++;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a < READ_TIMES)
|
||||
{
|
||||
ClearCache(buffer2352, 0, offset, hDevice, SRB);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("unknown");
|
||||
fConsole.WriteLine(f, "MSF: %02x:%02x:%02x Q-Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", sub[7], sub[8], sub[9], buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11]);
|
||||
othersectors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Console.WriteLine("\n\nOriginal sectors: %u", LIBCRYPT_NUM_SECTORS - lc1sectors - lc2sectors - othersectors);
|
||||
Console.WriteLine("\nLC1 sectors: %u", lc1sectors);
|
||||
Console.WriteLine("\nLC2 sectors: %u", lc2sectors);
|
||||
Console.WriteLine("\nOther sectors: %u", othersectors);
|
||||
|
||||
fConsole.WriteLine(f, "\nOriginal sectors: %u", LIBCRYPT_NUM_SECTORS - lc1sectors - lc2sectors - othersectors);
|
||||
fConsole.WriteLine(f, "\nLC1 sectors: %u", lc1sectors);
|
||||
fConsole.WriteLine(f, "\nLC2 sectors: %u", lc2sectors);
|
||||
fConsole.WriteLine(f, "\nOther sectors: %u", othersectors);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
internal static void ReadSub(byte[] buffer, uint sector, Stream f, byte offset, Stream hDevice, ScsiPassThroughDirect SRB)
|
||||
{
|
||||
uint returned;
|
||||
ZeroMemory(&SRB, sizeof(ScsiPassThroughDirect));
|
||||
SRB.Length = sizeof(ScsiPassThroughDirect);
|
||||
SRB.CDBLength = 12;
|
||||
SRB.DataIn = SCSI_IOCTL_DATA_IN;
|
||||
SRB.DataTransferLength = BUFFER_LEN;
|
||||
SRB.TimeOutValue = 30;
|
||||
SRB.DataBuffer = buffer;
|
||||
SRB.CDB[0] = RAW_READ_CMD;
|
||||
SRB.CDB[2] = HIbyte(HIWORD(sector + offset));
|
||||
SRB.CDB[3] = LObyte(HIWORD(sector + offset));
|
||||
SRB.CDB[4] = HIbyte(LOWORD(sector + offset));
|
||||
SRB.CDB[5] = LObyte(LOWORD(sector + offset));
|
||||
SRB.CDB[8] = 1;
|
||||
SRB.CDB[10] = 1;
|
||||
|
||||
if (!DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &SRB, sizeof(ScsiPassThroughDirect), &SRB, SENSE_SIZE, &returned, 0))
|
||||
{
|
||||
Console.WriteLine("\nError reading subchannel data!\n");
|
||||
if (f != 0)
|
||||
fConsole.WriteLine(f, "Error reading subchannel data!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Deinterleave(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
internal static void ClearCache(byte[] buffer, Stream f, byte offset, Stream hDevice, ScsiPassThroughDirect SRB)
|
||||
{
|
||||
static uint returned;
|
||||
for (uint sector = 0; sector < 1000; sector += 10)
|
||||
{
|
||||
ZeroMemory(&SRB, sizeof(ScsiPassThroughDirect));
|
||||
SRB.Length = sizeof(ScsiPassThroughDirect);
|
||||
SRB.CDBLength = 12;
|
||||
SRB.DataIn = SCSI_IOCTL_DATA_IN;
|
||||
SRB.DataTransferLength = 23520;
|
||||
SRB.TimeOutValue = 30;
|
||||
SRB.DataBuffer = buffer;
|
||||
SRB.CDB[0] = RAW_READ_CMD;
|
||||
SRB.CDB[2] = HIbyte(HIWORD(sector + offset));
|
||||
SRB.CDB[3] = LObyte(HIWORD(sector + offset));
|
||||
SRB.CDB[4] = HIbyte(LOWORD(sector + offset));
|
||||
SRB.CDB[5] = LObyte(LOWORD(sector + offset));
|
||||
SRB.CDB[8] = 10;
|
||||
SRB.CDB[9] = 0xF8;
|
||||
|
||||
DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &SRB, sizeof(ScsiPassThroughDirect), &SRB, SENSE_SIZE, &returned, 0);
|
||||
|
||||
if (!DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &SRB, sizeof(ScsiPassThroughDirect), &SRB, SENSE_SIZE, &returned, 0))
|
||||
{
|
||||
Console.WriteLine("\nError clearing cache!\n");
|
||||
if (f != 0)
|
||||
fConsole.WriteLine(f, "Error clearing cache!");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
internal static bool Matrix(byte[] buffer, byte[] buffer2, byte[] buffer3, byte[] buffer4, uint length)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if (buffer[i] == buffer2[i])
|
||||
{
|
||||
if (buffer[i] == buffer3[i])
|
||||
continue;
|
||||
if (buffer[i] == buffer4[i])
|
||||
continue;
|
||||
}
|
||||
else if (buffer[i] == buffer3[i] && buffer[i] == buffer4[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (buffer2[i] == buffer3[i] && buffer2[i] == buffer4[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static void Deinterleave(byte[] buffer)
|
||||
{
|
||||
byte[] buffertmp = new byte[12];
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
buffertmp[i] |= (byte)((buffer[i * 8] & 0x40) << 1);
|
||||
buffertmp[i] |= (byte)((buffer[i * 8 + 1] & 0x40));
|
||||
buffertmp[i] |= (byte)((buffer[i * 8 + 2] & 0x40) >> 1);
|
||||
buffertmp[i] |= (byte)((buffer[i * 8 + 3] & 0x40) >> 2);
|
||||
buffertmp[i] |= (byte)((buffer[i * 8 + 4] & 0x40) >> 3);
|
||||
buffertmp[i] |= (byte)((buffer[i * 8 + 5] & 0x40) >> 4);
|
||||
buffertmp[i] |= (byte)((buffer[i * 8 + 6] & 0x40) >> 5);
|
||||
buffertmp[i] |= (byte)((buffer[i * 8 + 7] & 0x40) >> 6);
|
||||
}
|
||||
|
||||
Array.Copy(buffertmp, buffer, 12);
|
||||
return;
|
||||
}
|
||||
|
||||
internal static bool LibCryptDetect(string subPath, string sbiPath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(subPath) || !File.Exists(subPath))
|
||||
return false;
|
||||
|
||||
// Variables
|
||||
byte[] buffer = new byte[16], sub = new byte[16];//, pregap = 0;
|
||||
uint sector, psectors = 0, tpos = 0;
|
||||
|
||||
// Opening .sub
|
||||
Stream subfile = File.OpenRead(subPath);
|
||||
|
||||
// checking extension
|
||||
if (Path.GetExtension(subPath).TrimStart('.').ToLowerInvariant() != "sub")
|
||||
{
|
||||
Console.WriteLine($"{subPath}: unknown file extension");
|
||||
return false;
|
||||
}
|
||||
|
||||
// filesize
|
||||
long size = subfile.Length;
|
||||
if (size % 96 != 0)
|
||||
{
|
||||
Console.WriteLine($"{subfile}: wrong size");
|
||||
return false;
|
||||
}
|
||||
|
||||
// sbi
|
||||
Stream sbi = null;
|
||||
if (sbiPath != null)
|
||||
{
|
||||
sbi = File.OpenWrite(sbiPath);
|
||||
sbi.Write(Encoding.ASCII.GetBytes("SBI\0"), 0, 4);
|
||||
}
|
||||
|
||||
for (sector = 150; sector < ((size / 96) + 150); sector++)
|
||||
{
|
||||
subfile.Seek(12, SeekOrigin.Current);
|
||||
if (subfile.Read(buffer, 0, 12) != 12)
|
||||
return true;
|
||||
|
||||
subfile.Seek(72, SeekOrigin.Current);
|
||||
|
||||
// New track
|
||||
if ((btoi(buffer[1]) == (btoi(sub[1]) + 1)) && (buffer[2] == 0 || buffer[2] == 1))
|
||||
{
|
||||
Array.Copy(buffer, sub, 6);
|
||||
tpos = (uint)((btoi((byte)(buffer[3] * 60)) + btoi(buffer[4])) * 75) + btoi(buffer[5]);
|
||||
}
|
||||
|
||||
// New index
|
||||
else if (btoi(buffer[2]) == (btoi(sub[2]) + 1) && buffer[1] == sub[1])
|
||||
{
|
||||
Array.Copy(buffer, 2, sub, 2, 4);
|
||||
tpos = (uint)((btoi((byte)(buffer[3] * 60)) + btoi(buffer[4])) * 75) + btoi(buffer[5]);
|
||||
}
|
||||
|
||||
// MSF1 [3-5]
|
||||
else
|
||||
{
|
||||
if (sub[2] == 0)
|
||||
tpos--;
|
||||
else
|
||||
tpos++;
|
||||
|
||||
sub[3] = itob((byte)(tpos / 60 / 75));
|
||||
sub[4] = itob((byte)((tpos / 75) % 60));
|
||||
sub[5] = itob((byte)(tpos % 75));
|
||||
}
|
||||
|
||||
//MSF2 [7-9]
|
||||
sub[7] = itob((byte)(sector / 60 / 75));
|
||||
sub[8] = itob((byte)((sector / 75) % 60));
|
||||
sub[9] = itob((byte)(sector % 75));
|
||||
|
||||
// CRC-16 [10-11]
|
||||
ushort crc = CRC16.Calculate(sub, 0, 10);
|
||||
sub[10] = (byte)(crc >> 8);
|
||||
sub[11] = (byte)(crc & 0xFF);
|
||||
|
||||
//if (buffer[10] != sub[10] && buffer[11] != sub[11] && (buffer[3] != sub[3] || buffer[7] != sub[7] || buffer[4] != sub[4] || buffer[8] != sub[8] || buffer[5] != sub[5] || buffer[9] != sub[9])) {
|
||||
//if (buffer[10] != sub[10] || buffer[11] != sub[11] || buffer[3] != sub[3] || buffer[7] != sub[7] || buffer[4] != sub[4] || buffer[8] != sub[8] || buffer[5] != sub[5] || buffer[9] != sub[9]) {
|
||||
if (!buffer.Take(6).SequenceEqual(sub.Take(6)) || !buffer.Skip(7).Take(5).SequenceEqual(sub.Skip(7).Take(5)))
|
||||
{
|
||||
Console.WriteLine($"MSF: {sub[7]:2x}:{sub[8]:2x}:{sub[9]:2x} Q-Data: {buffer[0]:2x}{buffer[1]:2x}{buffer[2]:2x} {buffer[3]:2x}:{buffer[4]:2x}:{buffer[5]:2x} {buffer[6]:2x} {buffer[7]:2x}:{buffer[8]:2x}:{buffer[9]:2x} {buffer[10]:2x}{buffer[11]:2x} xor {crc ^ ((buffer[10] << 8) + buffer[11]):4x} {CRC16.Calculate(buffer, 0, 10) ^ ((buffer[10] << 8) + buffer[11]):4x}");
|
||||
//Console.WriteLine("\nMSF: %02x:%02x:%02x Q-Data: %02x%02x%02x %02x:%02x:%02x %02x %02x:%02x:%02x %02x%02x", sub[7], sub[8], sub[9], sub[0], sub[1], sub[2], sub[3], sub[4], sub[5], sub[6], sub[7], sub[8], sub[9], sub[10], sub[11]);
|
||||
|
||||
if (buffer[3] != sub[3] && buffer[7] != sub[7] && buffer[4] == sub[4] && buffer[8] == sub[8] && buffer[5] == sub[5] && buffer[9] == sub[9])
|
||||
Console.WriteLine($" P1 xor {buffer[3] ^ sub[3]:2x} {buffer[7] ^ sub[7]:2x}");
|
||||
else if (buffer[3] == sub[3] && buffer[7] == sub[7] && buffer[4] != sub[4] && buffer[8] != sub[8] && buffer[5] == sub[5] && buffer[9] == sub[9])
|
||||
Console.WriteLine($" P2 xor {buffer[4] ^ sub[4]:2x} {buffer[8] ^ sub[8]:2x}");
|
||||
else if (buffer[3] == sub[3] && buffer[7] == sub[7] && buffer[4] == sub[4] && buffer[8] == sub[8] && buffer[5] != sub[5] && buffer[9] != sub[9])
|
||||
Console.WriteLine($" P3 xor {buffer[5] ^ sub[5]:2x} {buffer[9] ^ sub[9]:2x}");
|
||||
else
|
||||
Console.WriteLine(" ?");
|
||||
|
||||
Console.WriteLine("\n");
|
||||
psectors++;
|
||||
if (sbi != null)
|
||||
{
|
||||
sbi.Write(sub, 7, 3);
|
||||
sbi.Write(new byte[] { 0x01 }, 0, 1);
|
||||
sbi.Write(buffer, 0, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
Console.WriteLine($"Number of modified sectors: {psectors}");
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static int XorLibCrypt()
|
||||
{
|
||||
sbyte b;
|
||||
byte d;
|
||||
byte i, a, x;
|
||||
byte[] sub = new byte[12]
|
||||
{
|
||||
0x41, 0x01, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
ushort crc;
|
||||
for (i = 0; i < LIBCRYPT_NUM_SECTORS; i++)
|
||||
{
|
||||
sub[3] = itob((byte)(lc_addresses[i] / 60 / 75));
|
||||
sub[4] = itob((byte)((lc_addresses[i] / 75) % 60));
|
||||
sub[5] = itob((byte)(lc_addresses[i] % 75));
|
||||
sub[7] = itob((byte)((lc_addresses[i] + 150) / 60 / 75));
|
||||
sub[8] = itob((byte)(((lc_addresses[i] + 150) / 75) % 60));
|
||||
sub[9] = itob((byte)((lc_addresses[i] + 150) % 75));
|
||||
crc = CRC16.Calculate(sub, 0, 10);
|
||||
sub[10] = (byte)(crc >> 8);
|
||||
sub[11] = (byte)(crc & 0xFF);
|
||||
|
||||
Console.WriteLine($"%u %02x:%02x:%02x", lc_addresses[i], sub[7], sub[8], sub[9]);
|
||||
Console.WriteLine($" %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x %02x%02x", sub[0], sub[1], sub[2], sub[3], sub[4], sub[5], sub[6], sub[7], sub[8], sub[9], sub[10], sub[11]);
|
||||
Console.WriteLine($" %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x %02x%02x", lc1_sectors_contents[i * 12], lc1_sectors_contents[(i * 12) + 1], lc1_sectors_contents[(i * 12) + 2], lc1_sectors_contents[(i * 12) + 3], lc1_sectors_contents[(i * 12) + 4], lc1_sectors_contents[(i * 12) + 5], lc1_sectors_contents[(i * 12) + 6], lc1_sectors_contents[(i * 12) + 7], lc1_sectors_contents[(i * 12) + 8], lc1_sectors_contents[(i * 12) + 9], lc1_sectors_contents[(i * 12) + 10], lc1_sectors_contents[(i * 12) + 11]);
|
||||
|
||||
d = 0;
|
||||
|
||||
for (a = 3; a < 12; a++)
|
||||
{
|
||||
x = (byte)(lc1_sectors_contents[(i * 12) + a] ^ sub[a]);
|
||||
Console.WriteLine($" %x%x%x%x%x%x%x%x", (x >> 7) & 0x1, (x >> 6) & 0x1, (x >> 5) & 0x1, (x >> 4) & 0x1, (x >> 3) & 0x1, (x >> 2) & 0x1, (x >> 1) & 0x1, x & 0x1);
|
||||
if (x == 0)
|
||||
continue;
|
||||
for (b = 7; b >= 0; b--)
|
||||
{
|
||||
if (((x >> b) & 0x1) != 0)
|
||||
{
|
||||
d = (byte)(d << 1);
|
||||
d |= (byte)((sub[a] >> b) & 0x1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($" {(d >> 3) & 0x1:x}{(d >> 2) & 0x1:x}{(d >> 1) & 0x1:x}{d & 0x1}");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1004
BurnOutSharp/External/psxt001z/Main.cs
vendored
Normal file
1004
BurnOutSharp/External/psxt001z/Main.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
110
BurnOutSharp/External/psxt001z/Scramble.cs
vendored
Normal file
110
BurnOutSharp/External/psxt001z/Scramble.cs
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using static psxt001z.Common;
|
||||
|
||||
namespace psxt001z
|
||||
{
|
||||
public class Scramble
|
||||
{
|
||||
private static readonly byte[] sync = new byte[12] { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
|
||||
|
||||
public int __main(string[] args)
|
||||
{
|
||||
if (args.Length < 2 || args.Length > 3)
|
||||
{
|
||||
Console.WriteLine("Syntax: px_p8 [-t] filename");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sectors;
|
||||
if (args.Length == 2 && args[0] == "-t")
|
||||
{
|
||||
args[0] = args[1];
|
||||
sectors = 2352;
|
||||
}
|
||||
else
|
||||
{
|
||||
sectors = 4704;
|
||||
}
|
||||
|
||||
Stream sector_file;
|
||||
try
|
||||
{
|
||||
sector_file = File.OpenRead(args[1]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine(ex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
byte[] sector = new byte[sectors];
|
||||
if (args.Length == 2)
|
||||
{
|
||||
uint hex;
|
||||
for (int i = 0; sector_file.Position < sector_file.Length && i < 3252; i++)
|
||||
{
|
||||
byte[] buf = new byte[2];
|
||||
hex = uint.Parse(Encoding.ASCII.GetString(buf), NumberStyles.HexNumber);
|
||||
sector[i] = (byte)hex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sector_file.Read(sector, 0, sectors);
|
||||
}
|
||||
|
||||
int offset = MemSearch(sector, sync, sectors, 12);
|
||||
if (offset == -1)
|
||||
{
|
||||
Console.WriteLine("Error searching for sync!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console.WriteLine($"MSF: {sector[offset + 12]:2x}:{sector[offset + 12 + 1]:2x}:{sector[offset + 12 + 2]:2x}");
|
||||
|
||||
int shiftRegister = 0x1;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
sector[offset + 12 + i] ^= (byte)(shiftRegister & 0xFF);
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
int hibit = ((shiftRegister & 1) ^ ((shiftRegister & 2) >> 1)) << 15;
|
||||
shiftRegister = (hibit | shiftRegister) >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
int start_sector = (btoi(sector[offset + 12]) * 60 + btoi(sector[offset + 13])) * 75 + btoi(sector[offset + 14]) - 150;
|
||||
|
||||
Console.WriteLine($"MSF: {sector[offset + 12]:2x}:{sector[offset + 12 + 1]:2x}:{sector[offset + 12 + 2]:2x}");
|
||||
|
||||
offset -= start_sector * 2352;
|
||||
|
||||
Console.WriteLine($"Combined offset: {offset} bytes / {offset / 4} samples");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Search for a byte array in another
|
||||
/// </summary>
|
||||
private int MemSearch(in byte[] buf_where, in byte[] buf_search, int buf_where_len, int buf_search_len)
|
||||
{
|
||||
for (int i = 0; i <= buf_where_len - buf_search_len; i++)
|
||||
{
|
||||
for (int j = 0; j < buf_search_len; j++)
|
||||
{
|
||||
if (buf_where[i + j] != buf_search[j])
|
||||
break;
|
||||
|
||||
if (j + 1 == buf_search_len)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
310
BurnOutSharp/External/psxt001z/Track.cs
vendored
Normal file
310
BurnOutSharp/External/psxt001z/Track.cs
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace psxt001z
|
||||
{
|
||||
internal class Track
|
||||
{
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Original input path for the track
|
||||
/// </summary>
|
||||
private string InputPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stream representing the track data
|
||||
/// </summary>
|
||||
private Stream InputStream { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Output for saving the track data
|
||||
/// </summary>
|
||||
private string OutputPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Starting offset within the file
|
||||
/// </summary>
|
||||
private int Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Size of the input file
|
||||
/// </summary>
|
||||
private int Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CRC-32 of the track data to compare against
|
||||
/// </summary>
|
||||
private uint CRC32 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Audio data header
|
||||
/// </summary>
|
||||
private byte[] RiffData { get; set; } = new byte[44];
|
||||
|
||||
/// <summary>
|
||||
/// True if the track is audio data
|
||||
/// </summary>
|
||||
private bool IsRiff { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the file is under ~100MB
|
||||
/// </summary>
|
||||
private bool SmallFile { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// True to write out the track data
|
||||
/// </summary>
|
||||
private bool SaveTrack { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True means '+' or 'p'
|
||||
/// False means '-' or 'n'
|
||||
/// Null means neither
|
||||
/// </summary>
|
||||
private bool? Mode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cache for small file data
|
||||
/// </summary>
|
||||
private byte[] FileContents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cached file offset
|
||||
/// </summary>
|
||||
private int Offset { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Current file offset
|
||||
/// </summary>
|
||||
private int Current { get; set; } = 0;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public Track(string filename, int start, int size, uint crc, bool isRiff = false, bool? mode = null, string output = null)
|
||||
{
|
||||
InputPath = filename;
|
||||
InputStream = File.OpenRead(filename);
|
||||
OutputPath = output;
|
||||
|
||||
Start = start;
|
||||
Size = size;
|
||||
CRC32 = crc;
|
||||
Mode = mode;
|
||||
|
||||
IsRiff = isRiff;
|
||||
SmallFile = Size <= 100_000_000;
|
||||
SaveTrack = output != null;
|
||||
|
||||
Console.WriteLine($"File: {InputPath}\nStart: {Start}\nSize: {Size}\nCRC-32: {CRC32:8x}");
|
||||
Console.WriteLine();
|
||||
|
||||
if (IsRiff)
|
||||
PopulateRiffData();
|
||||
|
||||
if (SmallFile)
|
||||
CacheFileData();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Functions
|
||||
|
||||
public bool FindTrack()
|
||||
{
|
||||
// Positive mode
|
||||
if (Mode == true)
|
||||
{
|
||||
if (Current > 20000)
|
||||
{
|
||||
Mode = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
Offset = Current;
|
||||
Current += 4;
|
||||
return MatchesCRC();
|
||||
}
|
||||
|
||||
// Negative mode
|
||||
else if (Mode == false)
|
||||
{
|
||||
if (Current > 20000)
|
||||
{
|
||||
Mode = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
Offset = -Current;
|
||||
Current += 4;
|
||||
return MatchesCRC();
|
||||
}
|
||||
|
||||
// Neutral mode
|
||||
else
|
||||
{
|
||||
if (Current > 20000)
|
||||
{
|
||||
Mode = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
Offset = Current;
|
||||
if (MatchesCRC())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Offset = -Current;
|
||||
Current += 4;
|
||||
return MatchesCRC();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool MatchesCRC()
|
||||
{
|
||||
CRC32 calc = new CRC32();
|
||||
if (SmallFile)
|
||||
{
|
||||
if (IsRiff)
|
||||
calc.ProcessCRC(RiffData, 0, 44);
|
||||
|
||||
calc.ProcessCRC(FileContents, (int)(20000 + Offset), (int)Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
InputStream.Seek(Start + Offset, SeekOrigin.Begin);
|
||||
if (IsRiff)
|
||||
calc.ProcessCRC(RiffData, 0, 44);
|
||||
|
||||
for (long i = 0; i < Size; i++)
|
||||
{
|
||||
byte[] buffer = new byte[1];
|
||||
if (InputStream.Read(buffer, 0, 1) != 1)
|
||||
{
|
||||
buffer[0] = 0x00;
|
||||
InputStream.Seek(Start + Offset + i + 1, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
calc.ProcessCRC(buffer, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
Console.Write($"Offset correction {Offset} bytes, {Offset / 4} samples, CRC-32 {calc.m_crc32:8x}");
|
||||
return (calc.m_crc32 == CRC32);
|
||||
}
|
||||
|
||||
public void Done()
|
||||
{
|
||||
if (SmallFile)
|
||||
FileContents = null;
|
||||
|
||||
if (Mode == null)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Can't find offset!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (SaveTrack)
|
||||
{
|
||||
byte[] buffer = new byte[1];
|
||||
Stream f2 = File.Open(OutputPath, FileMode.Create, FileAccess.ReadWrite);
|
||||
if (IsRiff)
|
||||
f2.Write(RiffData, 0, 44);
|
||||
|
||||
InputStream.Seek(Start + Offset, SeekOrigin.Begin);
|
||||
for (long i = 0; i < Size; i++)
|
||||
{
|
||||
if (InputStream.Read(buffer, 0, 1) != 1)
|
||||
{
|
||||
buffer[0] = 0x00;
|
||||
InputStream.Seek(Start + Offset + i + 1, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
f2.Write(buffer, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
Console.Write("DONE!");
|
||||
Console.WriteLine();
|
||||
Console.Write($"Offset correction: {Offset} bytes / {Offset / 4} samples");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Utilities
|
||||
|
||||
// TODO: Figure out what this actually does
|
||||
private void CacheFileData()
|
||||
{
|
||||
FileContents = new byte[Size + 40000];
|
||||
InputStream.Seek(Start - 20000, SeekOrigin.Begin);
|
||||
|
||||
for (int i = 0; i < Size + 40000; i++)
|
||||
{
|
||||
if (Start + i <= 20000)
|
||||
InputStream.Seek(Start + i - 20000, SeekOrigin.Begin);
|
||||
|
||||
if (InputStream.Read(new byte[1], 0, 1) != 1)
|
||||
FileContents[i] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulateRiffData()
|
||||
{
|
||||
RiffData[0] = 0x52;
|
||||
RiffData[1] = 0x49;
|
||||
RiffData[2] = 0x46;
|
||||
RiffData[3] = 0x46;
|
||||
|
||||
byte[] temp = BitConverter.GetBytes(Size - 8);
|
||||
Array.Copy(temp, 0, RiffData, 4, 4);
|
||||
|
||||
RiffData[8] = 0x57;
|
||||
RiffData[9] = 0x41;
|
||||
RiffData[10] = 0x56;
|
||||
RiffData[11] = 0x45;
|
||||
RiffData[12] = 0x66;
|
||||
RiffData[13] = 0x6D;
|
||||
RiffData[14] = 0x74;
|
||||
RiffData[15] = 0x20;
|
||||
RiffData[16] = 0x10;
|
||||
RiffData[17] = 0x00;
|
||||
RiffData[18] = 0x00;
|
||||
RiffData[19] = 0x00;
|
||||
RiffData[20] = 0x01;
|
||||
RiffData[21] = 0x00;
|
||||
RiffData[22] = 0x02;
|
||||
RiffData[23] = 0x00;
|
||||
RiffData[24] = 0x44;
|
||||
RiffData[25] = 0xAC;
|
||||
RiffData[26] = 0x00;
|
||||
RiffData[27] = 0x00;
|
||||
RiffData[28] = 0x10;
|
||||
RiffData[29] = 0xB1;
|
||||
RiffData[30] = 0x02;
|
||||
RiffData[31] = 0x00;
|
||||
RiffData[32] = 0x04;
|
||||
RiffData[33] = 0x00;
|
||||
RiffData[34] = 0x10;
|
||||
RiffData[35] = 0x00;
|
||||
RiffData[36] = 0x64;
|
||||
RiffData[37] = 0x61;
|
||||
RiffData[38] = 0x74;
|
||||
RiffData[39] = 0x61;
|
||||
|
||||
temp = BitConverter.GetBytes(Size - 44);
|
||||
Array.Copy(temp, 0, RiffData, 40, 4);
|
||||
|
||||
Size -= 44;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using SharpCompress.Compressors;
|
||||
using SharpCompress.Compressors.Deflate;
|
||||
@@ -62,7 +63,7 @@ namespace BurnOutSharp.FileType
|
||||
|
||||
br.BaseStream.Seek(offset, SeekOrigin.Begin);
|
||||
uint compressedSize = br.ReadUInt32();
|
||||
|
||||
|
||||
// Some files can lack the length prefix
|
||||
if (compressedSize > br.BaseStream.Length)
|
||||
{
|
||||
@@ -101,8 +102,11 @@ namespace BurnOutSharp.FileType
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
br.BaseStream.Seek(current, SeekOrigin.Begin);
|
||||
}
|
||||
}
|
||||
@@ -115,14 +119,20 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using SharpCompress.Compressors;
|
||||
using SharpCompress.Compressors.BZip2;
|
||||
@@ -50,7 +51,10 @@ namespace BurnOutSharp.FileType
|
||||
bz2File.CopyTo(fs);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect and format all found protections
|
||||
@@ -61,14 +65,20 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,34 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.FileType
|
||||
{
|
||||
public class Executable : IScannable
|
||||
{
|
||||
/// <summary>
|
||||
/// Cache for all IContentCheck types
|
||||
/// </summary>
|
||||
private static readonly IEnumerable<IContentCheck> contentCheckClasses = InitContentCheckClasses();
|
||||
|
||||
/// <summary>
|
||||
/// Cache for all INEContentCheck types
|
||||
/// </summary>
|
||||
private static readonly IEnumerable<INEContentCheck> neContentCheckClasses = InitNEContentCheckClasses();
|
||||
|
||||
/// <summary>
|
||||
/// Cache for all IPEContentCheck types
|
||||
/// </summary>
|
||||
private static readonly IEnumerable<IPEContentCheck> peContentCheckClasses = InitPEContentCheckClasses();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic)
|
||||
{
|
||||
@@ -92,8 +75,10 @@ namespace BurnOutSharp.FileType
|
||||
fileContent = br.ReadBytes((int)stream.Length);
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
|
||||
Utilities.AppendToDictionary(protections, file, "[Out of memory attempting to open]");
|
||||
return protections;
|
||||
}
|
||||
@@ -109,10 +94,10 @@ namespace BurnOutSharp.FileType
|
||||
// Iterate through all generic content checks
|
||||
if (fileContent != null)
|
||||
{
|
||||
Parallel.ForEach(contentCheckClasses, contentCheckClass =>
|
||||
Parallel.ForEach(ScanningClasses.ContentCheckClasses, contentCheckClass =>
|
||||
{
|
||||
string protection = contentCheckClass.CheckContents(file, fileContent, scanner.IncludeDebug, pex, nex);
|
||||
if (ShouldAddProtection(contentCheckClass, scanner, protection))
|
||||
string protection = contentCheckClass.CheckContents(file, fileContent, scanner.IncludeDebug);
|
||||
if (ShouldAddProtection(contentCheckClass, scanner.ScanPackers, protection))
|
||||
Utilities.AppendToDictionary(protections, file, protection);
|
||||
|
||||
// If we have an IScannable implementation
|
||||
@@ -131,11 +116,11 @@ namespace BurnOutSharp.FileType
|
||||
// If we have a NE executable, iterate through all NE content checks
|
||||
if (nex?.Initialized == true)
|
||||
{
|
||||
Parallel.ForEach(neContentCheckClasses, contentCheckClass =>
|
||||
Parallel.ForEach(ScanningClasses.NewExecutableCheckClasses, contentCheckClass =>
|
||||
{
|
||||
// Check using custom content checks first
|
||||
string protection = contentCheckClass.CheckNEContents(file, nex, scanner.IncludeDebug);
|
||||
if (ShouldAddProtection(contentCheckClass, scanner, protection))
|
||||
string protection = contentCheckClass.CheckNewExecutable(file, nex, scanner.IncludeDebug);
|
||||
if (ShouldAddProtection(contentCheckClass, scanner.ScanPackers, protection))
|
||||
Utilities.AppendToDictionary(protections, file, protection);
|
||||
|
||||
// If we have an IScannable implementation
|
||||
@@ -154,11 +139,15 @@ namespace BurnOutSharp.FileType
|
||||
// If we have a PE executable, iterate through all PE content checks
|
||||
if (pex?.Initialized == true)
|
||||
{
|
||||
Parallel.ForEach(peContentCheckClasses, contentCheckClass =>
|
||||
// Print the section table for debug
|
||||
if (scanner.IncludeDebug && pex.SectionTable != null)
|
||||
pex.PrintAllSections();
|
||||
|
||||
Parallel.ForEach(ScanningClasses.PortableExecutableCheckClasses, contentCheckClass =>
|
||||
{
|
||||
// Check using custom content checks first
|
||||
string protection = contentCheckClass.CheckPEContents(file, pex, scanner.IncludeDebug);
|
||||
if (ShouldAddProtection(contentCheckClass, scanner, protection))
|
||||
string protection = contentCheckClass.CheckPortableExecutable(file, pex, scanner.IncludeDebug);
|
||||
if (ShouldAddProtection(contentCheckClass, scanner.ScanPackers, protection))
|
||||
Utilities.AppendToDictionary(protections, file, protection);
|
||||
|
||||
// If we have an IScannable implementation
|
||||
@@ -179,87 +168,23 @@ namespace BurnOutSharp.FileType
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Initialize all IContentCheck implementations
|
||||
/// </summary>
|
||||
private static IEnumerable<IContentCheck> InitContentCheckClasses()
|
||||
{
|
||||
return Assembly.GetExecutingAssembly().GetTypes()
|
||||
.Where(t => t.IsClass && t.GetInterface(nameof(IContentCheck)) != null)
|
||||
.Select(t => Activator.CreateInstance(t) as IContentCheck);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize all INEContentCheck implementations
|
||||
/// </summary>
|
||||
private static IEnumerable<INEContentCheck> InitNEContentCheckClasses()
|
||||
{
|
||||
return Assembly.GetExecutingAssembly().GetTypes()
|
||||
.Where(t => t.IsClass && t.GetInterface(nameof(INEContentCheck)) != null)
|
||||
.Select(t => Activator.CreateInstance(t) as INEContentCheck);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize all IPEContentCheck implementations
|
||||
/// </summary>
|
||||
private static IEnumerable<IPEContentCheck> InitPEContentCheckClasses()
|
||||
{
|
||||
return Assembly.GetExecutingAssembly().GetTypes()
|
||||
.Where(t => t.IsClass && t.GetInterface(nameof(IPEContentCheck)) != null)
|
||||
.Select(t => Activator.CreateInstance(t) as IPEContentCheck);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if a protection should be added or not
|
||||
/// </summary>
|
||||
/// <param name="contentCheckClass">Class that was last used to check</param>
|
||||
/// <param name="scanner">Scanner object for state tracking</param>
|
||||
/// <param name="checkClass">Class that was last used to check</param>
|
||||
/// <param name="scanPackers">Determines if packers should be included in the output</param>
|
||||
/// <param name="protection">The protection result to be checked</param>
|
||||
private bool ShouldAddProtection(IContentCheck contentCheckClass, Scanner scanner, string protection)
|
||||
private bool ShouldAddProtection(object checkClass, bool scanPackers, string protection)
|
||||
{
|
||||
// If we have an invalid protection
|
||||
if (string.IsNullOrWhiteSpace(protection))
|
||||
return false;
|
||||
|
||||
// If we have a valid content check based on settings
|
||||
if (!contentCheckClass.GetType().Namespace.ToLowerInvariant().Contains("packertype") || scanner.ScanPackers)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(protection))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if a protection should be added or not
|
||||
/// </summary>
|
||||
/// <param name="neContentCheckClass">Class that was last used to check</param>
|
||||
/// <param name="scanner">Scanner object for state tracking</param>
|
||||
/// <param name="protection">The protection result to be checked</param>
|
||||
private bool ShouldAddProtection(INEContentCheck neContentCheckClass, Scanner scanner, string protection)
|
||||
{
|
||||
// If we have a valid content check based on settings
|
||||
if (!neContentCheckClass.GetType().Namespace.ToLowerInvariant().Contains("packertype") || scanner.ScanPackers)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(protection))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if a protection should be added or not
|
||||
/// </summary>
|
||||
/// <param name="peContentCheckClass">Class that was last used to check</param>
|
||||
/// <param name="scanner">Scanner object for state tracking</param>
|
||||
/// <param name="protection">The protection result to be checked</param>
|
||||
private bool ShouldAddProtection(IPEContentCheck peContentCheckClass, Scanner scanner, string protection)
|
||||
{
|
||||
// If we have a valid content check based on settings
|
||||
if (!peContentCheckClass.GetType().Namespace.ToLowerInvariant().Contains("packertype") || scanner.ScanPackers)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(protection))
|
||||
return true;
|
||||
}
|
||||
if (scanPackers || !checkClass.GetType().Namespace.ToLowerInvariant().Contains("packertype"))
|
||||
return true;
|
||||
|
||||
// Everything else fails
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.GZip;
|
||||
@@ -53,7 +54,10 @@ namespace BurnOutSharp.FileType
|
||||
string tempFile = Path.Combine(tempPath, entry.Key);
|
||||
entry.WriteToFile(tempFile);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,14 +69,20 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using UnshieldSharp.Archive;
|
||||
|
||||
@@ -74,7 +75,10 @@ namespace BurnOutSharp.FileType
|
||||
fs.Write(fileContents, 0, fileContents.Length);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect and format all found protections
|
||||
@@ -85,14 +89,20 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using UnshieldSharp.Cabinet;
|
||||
|
||||
@@ -60,10 +61,23 @@ namespace BurnOutSharp.FileType
|
||||
// If an individual entry fails
|
||||
try
|
||||
{
|
||||
string tempFile = Path.Combine(tempPath, cabfile.FileName(i));
|
||||
string filename = cabfile.FileName(i);
|
||||
string tempFile;
|
||||
try
|
||||
{
|
||||
tempFile = Path.Combine(tempPath, filename);
|
||||
}
|
||||
catch
|
||||
{
|
||||
tempFile = Path.Combine(tempPath, $"BAD_FILENAME{i}");
|
||||
}
|
||||
|
||||
cabfile.FileSave(i, tempFile);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect and format all found protections
|
||||
@@ -74,14 +88,20 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using WixToolset.Dtf.WindowsInstaller;
|
||||
using OpenMcdf;
|
||||
|
||||
namespace BurnOutSharp.FileType
|
||||
{
|
||||
@@ -39,9 +41,39 @@ namespace BurnOutSharp.FileType
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
using (Database msidb = new Database(file, DatabaseOpenMode.ReadOnly))
|
||||
using (CompoundFile msi = new CompoundFile(stream, CFSUpdateMode.ReadOnly, CFSConfiguration.Default))
|
||||
{
|
||||
msidb.ExportAll(tempPath);
|
||||
msi.RootStorage.VisitEntries((e) =>
|
||||
{
|
||||
if (!e.IsStream)
|
||||
return;
|
||||
|
||||
var str = msi.RootStorage.GetStream(e.Name);
|
||||
if (str == null)
|
||||
return;
|
||||
|
||||
byte[] strData = str.GetData();
|
||||
if (strData == null)
|
||||
return;
|
||||
|
||||
string decoded = DecodeStreamName(e.Name).TrimEnd('\0');
|
||||
byte[] nameBytes = Encoding.UTF8.GetBytes(e.Name);
|
||||
|
||||
// UTF-8 encoding of 0x4840.
|
||||
if (nameBytes[0] == 0xe4 && nameBytes[1] == 0xa1 && nameBytes[2] == 0x80)
|
||||
decoded = decoded.Substring(3);
|
||||
|
||||
foreach (char c in Path.GetInvalidFileNameChars())
|
||||
{
|
||||
decoded = decoded.Replace(c, '_');
|
||||
}
|
||||
|
||||
string filename = Path.Combine(tempPath, decoded);
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
fs.Write(strData, 0, strData.Length);
|
||||
}
|
||||
}, recursive: true);
|
||||
}
|
||||
|
||||
// Collect and format all found protections
|
||||
@@ -52,16 +84,85 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <remarks>Adapted from LibMSI</remarks>
|
||||
private static string DecodeStreamName(string input)
|
||||
{
|
||||
if (input == null)
|
||||
return null;
|
||||
|
||||
int count = 0;
|
||||
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
|
||||
int p = 0; // inputBytes[0]
|
||||
|
||||
byte[] output = new byte[inputBytes.Length + 1];
|
||||
int q = 0; // output[0]
|
||||
while (p < inputBytes.Length && inputBytes[p] != 0)
|
||||
{
|
||||
int ch = inputBytes[p];
|
||||
if ((ch == 0xe3 && inputBytes[p + 1] >= 0xa0) || (ch == 0xe4 && inputBytes[p + 1] < 0xa0))
|
||||
{
|
||||
// UTF-8 encoding of 0x3800..0x47ff.
|
||||
output[q++] = (byte)Mime2Utf(inputBytes[p + 2] & 0x7f);
|
||||
output[q++] = (byte)Mime2Utf(inputBytes[p + 1] ^ 0xa0);
|
||||
p += 3;
|
||||
count += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == 0xe4 && inputBytes[p + 1] == 0xa0)
|
||||
{
|
||||
// UTF-8 encoding of 0x4800..0x483f.
|
||||
output[q++] = (byte)Mime2Utf(inputBytes[p + 2] & 0x7f);
|
||||
p += 3;
|
||||
count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
output[q++] = inputBytes[p++];
|
||||
if (ch >= 0xc1)
|
||||
output[q++] = inputBytes[p++];
|
||||
if (ch >= 0xe0)
|
||||
output[q++] = inputBytes[p++];
|
||||
if (ch >= 0xf0)
|
||||
output[q++] = inputBytes[p++];
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
output[q] = 0;
|
||||
return Encoding.ASCII.GetString(output);
|
||||
}
|
||||
|
||||
/// <remarks>Adapted from LibMSI</remarks>
|
||||
private static int Mime2Utf(int x)
|
||||
{
|
||||
if (x < 10)
|
||||
return x + '0';
|
||||
if (x < (10 + 26))
|
||||
return x - 10 + 'A';
|
||||
if (x < (10 + 26 + 26))
|
||||
return x - 10 - 26 + 'a';
|
||||
if (x == (10 + 26 + 26))
|
||||
return '.';
|
||||
return '_';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.Zip;
|
||||
@@ -12,6 +13,10 @@ namespace BurnOutSharp.FileType
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic)
|
||||
{
|
||||
// PKZIP (Unknown)
|
||||
if (magic.StartsWith(new byte?[] { 0x50, 0x4b, 0x00, 0x00 }))
|
||||
return true;
|
||||
|
||||
// PKZIP
|
||||
if (magic.StartsWith(new byte?[] { 0x50, 0x4b, 0x03, 0x04 }))
|
||||
return true;
|
||||
@@ -60,9 +65,13 @@ namespace BurnOutSharp.FileType
|
||||
continue;
|
||||
|
||||
string tempFile = Path.Combine(tempPath, entry.Key);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
|
||||
entry.WriteToFile(tempFile);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,14 +83,20 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
57
BurnOutSharp/FileType/PLJ.cs
Normal file
57
BurnOutSharp/FileType/PLJ.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.FileType
|
||||
{
|
||||
public class PLJ : IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic)
|
||||
{
|
||||
// https://www.iana.org/assignments/media-types/audio/vnd.everad.plj
|
||||
if (magic.StartsWith(new byte?[] { 0xFF, 0x9D, 0x53, 0x4B }))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
try
|
||||
{
|
||||
byte[] magic = new byte[16];
|
||||
stream.Read(magic, 0, 16);
|
||||
|
||||
if (ShouldScan(magic))
|
||||
{
|
||||
Utilities.AppendToDictionary(protections, file, "PlayJ Audio File");
|
||||
return protections;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.Rar;
|
||||
@@ -58,7 +59,10 @@ namespace BurnOutSharp.FileType
|
||||
string tempFile = Path.Combine(tempPath, entry.Key);
|
||||
entry.WriteToFile(tempFile);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,14 +74,20 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.SevenZip;
|
||||
@@ -53,7 +54,10 @@ namespace BurnOutSharp.FileType
|
||||
string tempFile = Path.Combine(tempPath, entry.Key);
|
||||
entry.WriteToFile(tempFile);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect and format all found protections
|
||||
@@ -64,7 +68,10 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
@@ -72,7 +79,10 @@ namespace BurnOutSharp.FileType
|
||||
return protections;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.Tar;
|
||||
@@ -56,7 +57,10 @@ namespace BurnOutSharp.FileType
|
||||
string tempFile = Path.Combine(tempPath, entry.Key);
|
||||
entry.WriteToFile(tempFile);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,14 +72,20 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.FileType
|
||||
@@ -38,10 +39,22 @@ namespace BurnOutSharp.FileType
|
||||
if (magic.StartsWith(new byte?[] { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 }))
|
||||
return true;
|
||||
|
||||
// InstallShield Compiled Rules
|
||||
if (magic.StartsWith(new byte?[] { 0x61, 0x4C, 0x75, 0x5A }))
|
||||
return true;
|
||||
|
||||
// InstallShield Script
|
||||
if (string.Equals(extension?.TrimStart('.'), "ins", StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
|
||||
// Generic textfile (no header)
|
||||
if (string.Equals(extension?.TrimStart('.'), "txt", StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
|
||||
// XML (multiple headers possible)
|
||||
if (string.Equals(extension?.TrimStart('.'), "xml", StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -72,15 +85,38 @@ namespace BurnOutSharp.FileType
|
||||
fileContent = sr.ReadToEnd();
|
||||
}
|
||||
|
||||
// AegiSoft License Manager
|
||||
// Found in "setup.ins" (Redump entry 73521/IA item "Nova_HoyleCasino99USA").
|
||||
if (fileContent.Contains("Failed to load the AegiSoft License Manager install program."))
|
||||
Utilities.AppendToDictionary(protections, file, "AegiSoft License Manager");
|
||||
|
||||
// CD-Key
|
||||
if (fileContent.Contains("a valid serial number is required"))
|
||||
Utilities.AppendToDictionary(protections, file, "CD-Key / Serial");
|
||||
else if (fileContent.Contains("serial number is located"))
|
||||
Utilities.AppendToDictionary(protections, file, "CD-Key / Serial");
|
||||
|
||||
// MediaCloQ
|
||||
if (fileContent.Contains("SunnComm MediaCloQ"))
|
||||
Utilities.AppendToDictionary(protections, file, "MediaCloQ");
|
||||
else if (fileContent.Contains("http://download.mediacloq.com/"))
|
||||
Utilities.AppendToDictionary(protections, file, "MediaCloQ");
|
||||
else if (fileContent.Contains("http://www.sunncomm.com/mediacloq/"))
|
||||
Utilities.AppendToDictionary(protections, file, "MediaCloQ");
|
||||
|
||||
// MediaMax
|
||||
if (fileContent.Contains("MediaMax technology"))
|
||||
Utilities.AppendToDictionary(protections, file, "MediaMax CD-3");
|
||||
else if (fileContent.Contains("exclusive Cd3 technology"))
|
||||
Utilities.AppendToDictionary(protections, file, "MediaMax CD-3");
|
||||
else if (fileContent.Contains("<PROTECTION-VENDOR>MediaMAX</PROTECTION-VENDOR>"))
|
||||
Utilities.AppendToDictionary(protections, file, "MediaMax CD-3");
|
||||
else if (fileContent.Contains("MediaMax(tm)"))
|
||||
Utilities.AppendToDictionary(protections, file, "MediaMax CD-3");
|
||||
|
||||
// phenoProtect
|
||||
if (fileContent.Contains("phenoProtect"))
|
||||
Utilities.AppendToDictionary(protections, file, "phenoProtect");
|
||||
|
||||
// The full line from a sample is as follows:
|
||||
//
|
||||
@@ -92,13 +128,17 @@ namespace BurnOutSharp.FileType
|
||||
if (fileContent.Contains("SecuROM protected application"))
|
||||
Utilities.AppendToDictionary(protections, file, "SecuROM");
|
||||
|
||||
// Steam
|
||||
if (fileContent.Contains("All use of the Program is governed by the terms of the Steam Agreement as described below."))
|
||||
Utilities.AppendToDictionary(protections, file, "Steam");
|
||||
|
||||
// XCP
|
||||
if (fileContent.Contains("http://cp.sonybmg.com/xcp/"))
|
||||
Utilities.AppendToDictionary(protections, file, "XCP");
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
// We don't care what the error was
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return protections;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
using SharpCompress.Compressors.Xz;
|
||||
|
||||
@@ -49,7 +50,10 @@ namespace BurnOutSharp.FileType
|
||||
xzFile.CopyTo(fs);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect and format all found protections
|
||||
@@ -60,14 +64,20 @@ namespace BurnOutSharp.FileType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,21 +1,17 @@
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
|
||||
namespace BurnOutSharp
|
||||
namespace BurnOutSharp.Interfaces
|
||||
{
|
||||
// TODO: This should either include an override that takes a Stream instead of the byte[]
|
||||
// TODO: This should be retired in lieu of the I*ContentCheck interfaces
|
||||
/// <summary>
|
||||
/// Check a generic file for protection
|
||||
/// </summary>
|
||||
internal interface IContentCheck
|
||||
{
|
||||
/// <summary>
|
||||
/// Check a path for protections based on file contents
|
||||
/// </summary>
|
||||
/// <param name="pex">PortableExecutable representing the read-in file</param>
|
||||
/// <param name="file">File to check for protection indicators</param>
|
||||
/// <param name="fileContent">Byte array representing the file contents</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>String containing any protections found in the file</returns>
|
||||
/// <remarks>This still includes PE and NE because this is primarily used for debug testing</remarks>
|
||||
string CheckContents(string file, byte[] fileContent, bool includeDebug, PortableExecutable pex, NewExecutable nex);
|
||||
string CheckContents(string file, byte[] fileContent, bool includeDebug);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
|
||||
namespace BurnOutSharp
|
||||
namespace BurnOutSharp.Interfaces
|
||||
{
|
||||
// TODO: This should either include an override that takes a Stream instead of the byte[]
|
||||
internal interface INEContentCheck
|
||||
/// <summary>
|
||||
/// Check a New Executable (NE) for protection
|
||||
/// </summary>
|
||||
internal interface INewExecutableCheck
|
||||
{
|
||||
/// <summary>
|
||||
/// Check a path for protections based on file contents
|
||||
@@ -12,6 +14,6 @@ namespace BurnOutSharp
|
||||
/// <param name="nex">NewExecutable representing the read-in file</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>String containing any protections found in the file</returns>
|
||||
string CheckNEContents(string file, NewExecutable nex, bool includeDebug);
|
||||
string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,14 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BurnOutSharp
|
||||
namespace BurnOutSharp.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Check a file or directory path for protection
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These checks rely primarily on filenames and paths, not file contents
|
||||
/// </remarks>
|
||||
internal interface IPathCheck
|
||||
{
|
||||
/// <summary>
|
||||
@@ -10,14 +16,14 @@ namespace BurnOutSharp
|
||||
/// </summary>
|
||||
/// <param name="path">Path to check for protection indicators</param>
|
||||
/// <param name="files">Enumerable of strings representing files in a directory</param>
|
||||
/// <remarks>This can do some limited content checking as well, but it's suggested to use IContentCheck instead, if possible</remarks>
|
||||
/// <remarks>This can do some limited content checking as well, but it's suggested to use a content check instead, if possible</remarks>
|
||||
ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files);
|
||||
|
||||
/// <summary>
|
||||
/// Check a file path for protections based on path name
|
||||
/// </summary>
|
||||
/// <param name="path">Path to check for protection indicators</param>
|
||||
/// <remarks>This can do some limited content checking as well, but it's suggested to use IContentCheck instead, if possible</remarks>
|
||||
/// <remarks>This can do some limited content checking as well, but it's suggested to use a content check instead, if possible</remarks>
|
||||
string CheckFilePath(string path);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,19 @@
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
|
||||
namespace BurnOutSharp
|
||||
namespace BurnOutSharp.Interfaces
|
||||
{
|
||||
// TODO: This should either include an override that takes a Stream instead of the byte[]
|
||||
internal interface IPEContentCheck
|
||||
/// <summary>
|
||||
/// Check a Portable Executable (PE) for protection
|
||||
/// </summary>
|
||||
internal interface IPortableExecutableCheck
|
||||
{
|
||||
/// <summary>
|
||||
/// Check a path for protections based on file contents
|
||||
/// </summary>
|
||||
/// <param name="file">File to check for protection indicators</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <param name="pex">PortableExecutable representing the read-in file</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>String containing any protections found in the file</returns>
|
||||
string CheckPEContents(string file, PortableExecutable pex, bool includeDebug);
|
||||
string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
|
||||
namespace BurnOutSharp
|
||||
namespace BurnOutSharp.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Mark a file type as extractable
|
||||
/// </summary>
|
||||
internal interface IScannable
|
||||
{
|
||||
/// <summary>
|
||||
@@ -51,13 +51,17 @@ namespace BurnOutSharp.Matching
|
||||
if (Needle.Length > stack.Length)
|
||||
return (false, -1);
|
||||
|
||||
// If start or end are not set properly, set them to defaults
|
||||
if (Start < 0)
|
||||
Start = 0;
|
||||
if (End < 0)
|
||||
End = stack.Length - Needle.Length;
|
||||
// Set the default start and end values
|
||||
int start = Start;
|
||||
int end = End;
|
||||
|
||||
for (int i = reverse ? End : Start; reverse ? i > Start : i < End; i += reverse ? -1 : 1)
|
||||
// If start or end are not set properly, set them to defaults
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (end < 0)
|
||||
end = stack.Length - Needle.Length;
|
||||
|
||||
for (int i = reverse ? end : start; reverse ? i > start : i < end; i += reverse ? -1 : 1)
|
||||
{
|
||||
// If we somehow have an invalid end and we haven't matched, return
|
||||
if (i > stack.Length)
|
||||
@@ -84,7 +88,7 @@ namespace BurnOutSharp.Matching
|
||||
return false;
|
||||
|
||||
// If we're too close to the end of the stack, return false
|
||||
if (Needle.Length >= stack.Length - index)
|
||||
if (Needle.Length > stack.Length - index)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < Needle.Length; i++)
|
||||
|
||||
661
BurnOutSharp/PackerType/ASPack.cs
Normal file
661
BurnOutSharp/PackerType/ASPack.cs
Normal file
@@ -0,0 +1,661 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class ASPack : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .aspack section, if it exists
|
||||
bool aspackSection = pex.ContainsSection(".aspack", exact: true);
|
||||
if (aspackSection)
|
||||
return "ASPack 2.29";
|
||||
|
||||
// Use the entry point data, if it exists
|
||||
if (pex.EntryPointRaw != null)
|
||||
{
|
||||
var matchers = GenerateMatchers();
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
|
||||
// Get the .adata* section, if it exists
|
||||
var adataSection = pex.GetFirstSection(".adata", exact: false);
|
||||
if (adataSection != null)
|
||||
{
|
||||
var adataSectionRaw = pex.ReadRawSection(adataSection.NameString);
|
||||
if (adataSectionRaw != null)
|
||||
{
|
||||
var matchers = GenerateMatchers();
|
||||
string match = MatchUtil.GetFirstMatch(file, adataSectionRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate the set of matchers used for each section
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private List<ContentMatchSet> GenerateMatchers()
|
||||
{
|
||||
return new List<ContentMatchSet>
|
||||
{
|
||||
#region No Wildcards (Long)
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x92, 0x1A, 0x44, 0x00, 0xB8, 0x8C, 0x1A,
|
||||
0x44, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0xCD, 0x1D,
|
||||
0x44, 0x00, 0x89, 0x85, 0xD9, 0x1D, 0x44, 0x00,
|
||||
0x80, 0xBD, 0xC4, 0x1D, 0x44,
|
||||
}, "ASPack 1.00b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xD2, 0x2A, 0x44, 0x00, 0xB8, 0xCC, 0x2A,
|
||||
0x44, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0xA5, 0x2E,
|
||||
0x44, 0x00, 0x89, 0x85, 0xB1, 0x2E, 0x44, 0x00,
|
||||
0x80, 0xBD, 0x9C, 0x2E, 0x44, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x9C, 0x2E, 0x44, 0x00, 0xE8,
|
||||
0x1D, 0x00, 0x00, 0x00, 0xE8, 0xE4, 0x01, 0x00,
|
||||
0x00, 0xE8, 0x7A, 0x02, 0x00, 0x00, 0x8B, 0x85,
|
||||
0x9D, 0x2E, 0x44, 0x00, 0x03, 0x85, 0xB1, 0x2E,
|
||||
0x44, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.01b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xD2, 0x2A, 0x44, 0x00, 0xB8, 0xCC, 0x2A,
|
||||
0x44, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0xA5, 0x2E,
|
||||
0x44, 0x00, 0x89, 0x85, 0xB1, 0x2E, 0x44, 0x00,
|
||||
0x80, 0xBD, 0x9C, 0x2E, 0x44
|
||||
}, "ASPack 1.01b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x96, 0x78, 0x43, 0x00, 0xB8, 0x90, 0x78,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x7D, 0x7C,
|
||||
0x43, 0x00, 0x89, 0x85, 0x89, 0x7C, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x74, 0x7C, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x74, 0x7C, 0x43, 0x00, 0xE8,
|
||||
0x1D, 0x00, 0x00, 0x00, 0xE8, 0xF7, 0x01, 0x00,
|
||||
0x00, 0xE8, 0x8E, 0x02, 0x00, 0x00, 0x8B, 0x85,
|
||||
0x75, 0x7C, 0x43, 0x00, 0x03, 0x85, 0x89, 0x7C,
|
||||
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.02b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x96, 0x78, 0x43, 0x00, 0xB8, 0x90, 0x78,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x7D, 0x7C,
|
||||
0x43, 0x00, 0x89, 0x85, 0x89, 0x7C, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x74, 0x7C, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x74, 0x7C, 0x43
|
||||
}, "ASPack 1.02b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x8A, 0x1C, 0x40, 0x00, 0xB9, 0x9E, 0x00,
|
||||
0x00, 0x00, 0x8D, 0xBD, 0x4C, 0x23, 0x40, 0x00,
|
||||
0x8B, 0xF7, 0x33
|
||||
}, "ASPack 1.02b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x96, 0x78, 0x43, 0x00, 0xB8, 0x90, 0x78,
|
||||
0x43, 0x00, 0x03, 0xC5
|
||||
}, "ASPack 1.02b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xAE, 0x98, 0x43, 0x00, 0xB8, 0xA8, 0x98,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x18, 0x9D,
|
||||
0x43, 0x00, 0x89, 0x85, 0x24, 0x9D, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x0E, 0x9D, 0x43
|
||||
}, "ASPack 1.03b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xCE, 0x3A, 0x44, 0x00, 0xB8, 0xC8, 0x3A,
|
||||
0x44, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0xB5, 0x3E,
|
||||
0x44, 0x00, 0x89, 0x85, 0xC1, 0x3E, 0x44, 0x00,
|
||||
0x80, 0xBD, 0xAC, 0x3E, 0x44
|
||||
}, "ASPack 1.05b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xEA, 0xA8, 0x43, 0x00, 0xB8, 0xE4, 0xA8,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x78, 0xAD,
|
||||
0x43, 0x00, 0x89, 0x85, 0x84, 0xAD, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x6E, 0xAD, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x6E, 0xAD, 0x43, 0x00, 0xE8,
|
||||
0x1D, 0x00, 0x00, 0x00, 0xE8, 0x73, 0x02, 0x00,
|
||||
0x00, 0xE8, 0x0A, 0x03, 0x00, 0x00, 0x8B, 0x85,
|
||||
0x70, 0xAD, 0x43, 0x00, 0x03, 0x85, 0x84, 0xAD,
|
||||
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.06.01b (DLL)"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xEA, 0xA8, 0x43, 0x00, 0xB8, 0xE4, 0xA8,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x78, 0xAD,
|
||||
0x43, 0x00, 0x89, 0x85, 0x84, 0xAD, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x6E, 0xAD, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x6E, 0xAD, 0x43
|
||||
}, "ASPack 1.06.01b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x3E, 0xD9, 0x43, 0x00, 0xB8, 0x38, 0xD9,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x0B, 0xDE,
|
||||
0x43, 0x00, 0x89, 0x85, 0x17, 0xDE, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x01, 0xDE, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x01, 0xDE, 0x43, 0x00, 0xE8,
|
||||
0x1D, 0x00, 0x00, 0x00, 0xE8, 0x79, 0x02, 0x00,
|
||||
0x00, 0xE8, 0x12, 0x03, 0x00, 0x00, 0x8B, 0x85,
|
||||
0x03, 0xDE, 0x43, 0x00, 0x03, 0x85, 0x17, 0xDE,
|
||||
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.07b (DLL)"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xEB, 0x03, 0x5D, 0xFF, 0xE5, 0xE8, 0xF8,
|
||||
0xFF, 0xFF, 0xFF, 0x81, 0xED, 0x1B, 0x6A, 0x44,
|
||||
0x00, 0xBB, 0x10, 0x6A, 0x44, 0x00, 0x03, 0xDD,
|
||||
0x2B, 0x9D, 0x2A
|
||||
}, "ASPack 1.08"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x0A, 0x4A, 0x44, 0x00, 0xBB, 0x04, 0x4A,
|
||||
0x44, 0x00, 0x03, 0xDD, 0x2B, 0x9D, 0xB1, 0x50,
|
||||
0x44, 0x00, 0x83, 0xBD, 0xAC, 0x50, 0x44, 0x00,
|
||||
0x00, 0x89, 0x9D, 0xBB, 0x4E, 0x44, 0x00, 0x0F,
|
||||
0x85, 0x17, 0x05, 0x00, 0x00, 0x8D, 0x85, 0xD1,
|
||||
0x50, 0x44, 0x00, 0x50, 0xFF, 0x95, 0x94, 0x51,
|
||||
0x44, 0x00, 0x89, 0x85, 0xCD, 0x50, 0x44, 0x00,
|
||||
0x8B, 0xF8, 0x8D, 0x9D, 0xDE, 0x50, 0x44, 0x00,
|
||||
0x53, 0x50, 0xFF, 0x95, 0x90, 0x51, 0x44, 0x00
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x0A, 0x4A, 0x44, 0x00, 0xBB, 0x04, 0x4A,
|
||||
0x44, 0x00, 0x03, 0xDD, 0x2B, 0x9D, 0xB1, 0x50,
|
||||
0x44, 0x00, 0x83, 0xBD, 0xAC, 0x50, 0x44, 0x00,
|
||||
0x00, 0x89, 0x9D, 0xBB, 0x4E
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x0A, 0x4A, 0x44, 0x00, 0xBB, 0x04, 0x4A,
|
||||
0x44, 0x00, 0x03, 0xDD
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x72, 0x05, 0x00, 0x00, 0xEB, 0x33,
|
||||
0x87, 0xDB, 0x90, 0x00
|
||||
}, "ASPack 2.00.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
|
||||
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01, 0x00,
|
||||
0x00, 0x00, 0xEB, 0x5D, 0xBB, 0xED, 0xFF, 0xFF,
|
||||
0xFF, 0x03, 0xDD, 0x81, 0xEB
|
||||
}, "ASPack 2.1"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
|
||||
0x5D, 0x55, 0x81, 0xED, 0x39, 0x39, 0x44, 0x00,
|
||||
0xC3, 0xE9, 0x3D, 0x04, 0x00, 0x00
|
||||
}, "ASPack 2.11b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
|
||||
0x5D, 0x55
|
||||
}, "ASPack 2.11b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
|
||||
0x5D, 0x55, 0x81, 0xED, 0x39, 0x39, 0x44, 0x00,
|
||||
0xC3, 0xE9, 0x59, 0x04, 0x00, 0x00
|
||||
}, "ASPack 2.11c"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xCD, 0x20,
|
||||
0xE8, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x2B, 0xC9,
|
||||
0x58, 0x74, 0x02
|
||||
}, "ASPack 2.11d"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
|
||||
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01
|
||||
}, "ASPack 2.12"),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Wildcards (Long)
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0x3E, 0xD9, 0x43, null, 0xB8, 0x38, null,
|
||||
null, null, 0x03, 0xC5, 0x2B, 0x85, 0x0B, 0xDE,
|
||||
0x43, null, 0x89, 0x85, 0x17, 0xDE, 0x43, null,
|
||||
0x80, 0xBD, 0x01, 0xDE, 0x43, null, null, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x01, 0xDE, 0x43, null, 0xE8,
|
||||
0x1D, null, null, null, 0xE8, 0x79, 0x02, null,
|
||||
null, 0xE8, 0x12, 0x03, null, null, 0x8B, 0x85,
|
||||
0x03, 0xDE, 0x43, null, 0x03, 0x85, 0x17, 0xDE,
|
||||
0x43, null, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.00b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0xD2, 0x2A, 0x44, null, 0xB8, 0xCC, 0x2A,
|
||||
0x44, null, 0x03, 0xC5, 0x2B, 0x85, 0xA5, 0x2E,
|
||||
0x44, null, 0x89, 0x85, 0xB1, 0x2E, 0x44, null,
|
||||
0x80, 0xBD, 0x9C, 0x2E, 0x44
|
||||
}, "ASPack 1.01b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0xCE, 0x3A, 0x44, null, 0xB8, 0xC8, 0x3A,
|
||||
0x44, null, 0x03, 0xC5, 0x2B, 0x85, 0xB5, 0x3E,
|
||||
0x44, null, 0x89, 0x85, 0xC1, 0x3E, 0x44, null,
|
||||
0x80, 0xBD, 0xAC, 0x3E, 0x44
|
||||
}, "ASPack 1.01b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x3E, 0xD9, 0x43, 0x00, 0xB8, 0x38, null,
|
||||
null, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x0B, 0xDE,
|
||||
0x43, 0x00, 0x89, 0x85, 0x17, 0xDE, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x01, 0xDE, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x01, 0xDE, 0x43, 0x00, 0xE8,
|
||||
0x1D, 0x00, 0x00, 0x00, 0xE8, 0x79, 0x02, 0x00,
|
||||
0x00, 0xE8, 0x12, 0x03, 0x00, 0x00, 0x8B, 0x85,
|
||||
0x03, 0xDE, 0x43, 0x00, 0x03, 0x85, 0x17, 0xDE,
|
||||
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.02a -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0x06, null, null, null, 0x64, 0xA0, 0x23
|
||||
}, "ASPack 1.02a"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0x96, 0x78, 0x43, null, 0xB8, 0x90, 0x78,
|
||||
0x43, null, 0x03, 0xC5, 0x2B, 0x85, 0x7D, 0x7C,
|
||||
0x43, null, 0x89, 0x85, 0x89, 0x7C, 0x43, null,
|
||||
0x80, 0xBD, 0x74, 0x7C, 0x43
|
||||
}, "ASPack 1.02b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0xAE, 0x98, 0x43, null, 0xB8, 0xA8, 0x98,
|
||||
0x43, null, 0x03, 0xC5, 0x2B, 0x85, 0x18, 0x9D,
|
||||
0x43, null, 0x89, 0x85, 0x24, 0x9D, 0x43, null,
|
||||
0x80, 0xBD, 0x0E, 0x9D, 0x43
|
||||
}, "ASPack 1.03b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, null, null, null, null, 0xE8, 0x0D, null,
|
||||
null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, 0x58
|
||||
}, "ASPack 1.03b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, null, null, null, 0x00, 0xB8, null, null,
|
||||
null, 0x00, 0x03, 0xC5, 0x2B, 0x85, null, 0x12,
|
||||
0x9D, null, 0x89, 0x85, 0x1E, 0x9D, null, 0x00,
|
||||
0x80, 0xBD, 0x08, 0x9D, null, 0x00, 0x00
|
||||
}, "ASPack 1.04b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, null, null, null, null, 0xB8, null, null,
|
||||
null, null, 0x03, 0xC5, 0x2B, 0x85, null, 0x12,
|
||||
0x9D, null, 0x89, 0x85, 0x1E, 0x9D, null, null,
|
||||
0x80, 0xBD, 0x08, 0x9D
|
||||
}, "ASPack 1.04b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, null, null, null, null, 0xB8, null, null,
|
||||
null, null, 0x03, 0xC5, 0x2B, 0x85, null, 0x0B,
|
||||
0xDE, null, 0x89, 0x85, 0x17, 0xDE, null, null,
|
||||
0x80, 0xBD, 0x01, 0xDE
|
||||
}, "ASPack 1.04b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0xEA, 0xA8, 0x43, null, 0xB8, 0xE4, 0xA8,
|
||||
0x43, null, 0x03, 0xC5, 0x2B, 0x85, 0x78, 0xAD,
|
||||
0x43, null, 0x89, 0x85, 0x84, 0xAD, 0x43, null,
|
||||
0x80, 0xBD, 0x6E, 0xAD, 0x43
|
||||
}, "ASPack 1.06.1b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x90, 0x61, 0xBE, null, null, null, null, 0x8D,
|
||||
0xBE, null, null, null, null, 0x57, 0x83, 0xCD,
|
||||
0xFF
|
||||
}, "ASPack 1.06.1b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, null,
|
||||
null, null, null, null, null, 0xB8, null, null,
|
||||
null, null, 0x03, 0xC5
|
||||
}, "ASPack 1.07b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, null, null, null, null, 0x60, 0xE8, 0x2B,
|
||||
0x03, 0x00, 0x00
|
||||
}, "ASPack 1.07b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xEB, 0x0A, 0x5D, 0xEB, 0x02, 0xFF, 0x25,
|
||||
0x45, 0xFF, 0xE5, 0xE8, 0xE9, 0xE8, 0xF1, 0xFF,
|
||||
0xFF, 0xFF, 0xE9, 0x81, null, null, null, 0x44,
|
||||
0x00, 0xBB, 0x10, null, 0x44, 0x00, 0x03, 0xDD,
|
||||
0x2B, 0x9D
|
||||
}, "ASPack 1.08.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xEB, 0x0A, 0x5D, 0xEB, 0x02, 0xFF, 0x25,
|
||||
0x45, 0xFF, 0xE5, 0xE8, 0xE9, 0xE8, 0xF1, 0xFF,
|
||||
0xFF, 0xFF, 0xE9, 0x81, null, null, null, 0x44,
|
||||
null, 0xBB, 0x10, null, 0x44, null, 0x03, 0xDD,
|
||||
0x2B, 0x9D
|
||||
}, "ASPack 1.08.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xEB, 0x0A, 0x5D, 0xEB, 0x02, 0xFF, 0x25,
|
||||
0x45, 0xFF, 0xE5, 0xE8, 0xE9, 0xE8, 0xF1, 0xFF,
|
||||
0xFF, 0xFF, 0xE9, 0x81, 0xED, 0x23, 0x6A, 0x44,
|
||||
0x00, 0xBB, 0x10, null, 0x44, 0x00, 0x03, 0xDD,
|
||||
0x2B, 0x9D, 0x72
|
||||
}, "ASPack 1.08.02"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, null,
|
||||
null, null, null, null, null, 0xBB, null, null,
|
||||
null, null, 0x03, 0xDD, 0x2B, 0x9D, 0xB1, 0x50,
|
||||
0x44, 0x00, 0x83, 0xBD, 0xAC, 0x50, 0x44, 0x00,
|
||||
0x00, 0x89, 0x9D, 0xBB, 0x4E
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, null,
|
||||
null, null, null, null, null, 0xBB, null, null,
|
||||
null, null, 0x03, 0xDD
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x55, 0x57, 0x51, 0x53, 0xE8, null, null, null,
|
||||
null, 0x5D, 0x8B, 0xC5, 0x81, 0xED, null, null,
|
||||
null, null, 0x2B, 0x85, null, null, null, null,
|
||||
0x83, 0xE8, 0x09, 0x89, 0x85, null, null, null,
|
||||
null, 0x0F, 0xB6
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE9, null, null, null, null, 0xEF, 0x40,
|
||||
0x03, 0xA7, 0x07, 0x8F, 0x07, 0x1C, 0x37, 0x5D,
|
||||
0x43, 0xA7, 0x04, 0xB9, 0x2C, 0x3A
|
||||
}, "ASPack 1.08.x"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
|
||||
0x5D, 0x55, 0x81, 0xED, 0x39, 0x39, 0x44, 0x00,
|
||||
0xC3, 0xE9, null, 0x04, 0x00, 0x00
|
||||
}, "ASPack 2.11.x -> Alexey Solodovnikov"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
null, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
|
||||
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01
|
||||
}, "ASPack 2.12 (without Poly) -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
null, 0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9,
|
||||
0xEB, 0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01,
|
||||
0x00, 0x00, 0x00, 0xEB, 0x5D, 0xBB, 0xEC, 0xFF,
|
||||
0xFF, 0xFF, 0x03, 0xDD, 0x81, 0xEB, 0x00, null,
|
||||
null, 0x00, 0x83, 0xBD, 0x22, 0x04, 0x00, 0x00,
|
||||
0x00, 0x89, 0x9D, 0x22, 0x04, 0x00, 0x00, 0x0F,
|
||||
0x85, 0x65, 0x03, 0x00, 0x00, 0x8D, 0x85, 0x2E,
|
||||
0x04, 0x00, 0x00, 0x50, 0xFF, 0x95, 0x4C, 0x0F,
|
||||
0x00, 0x00, 0x89, 0x85, 0x26, 0x04, 0x00, 0x00,
|
||||
0x8B, 0xF8, 0x8D, 0x5D, 0x5E, 0x53, 0x50, 0xFF,
|
||||
0x95, 0x48, 0x0F, 0x00, 0x00, 0x89, 0x85, 0x4C,
|
||||
0x05, 0x00, 0x00, 0x8D, 0x5D, 0x6B, 0x53, 0x57,
|
||||
0xFF, 0x95, 0x48, 0x0F
|
||||
}, "ASPack 2.12b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
|
||||
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01, 0x00,
|
||||
0x00, 0x00, 0xEB, 0x5D, 0xBB, 0xED, 0xFF, 0xFF,
|
||||
0xFF, 0x03, 0xDD, null, null, null, null, null,
|
||||
null, 0x83, 0xBD, 0x7D, 0x04, 0x00, 0x00, 0x00,
|
||||
0x89, 0x9D, 0x7D, 0x04, 0x00, 0x00, 0x0F, 0x85,
|
||||
0xC0, 0x03, 0x00, 0x00, 0x8D, 0x85, 0x89, 0x04,
|
||||
0x00, 0x00, 0x50, 0xFF, 0x95, 0x09, 0x0F, 0x00,
|
||||
0x00, 0x89, 0x85, 0x81, 0x04, 0x00, 0x00, 0x8B,
|
||||
0xF0, 0x8D, 0x7D, 0x51, 0x57, 0x56, 0xFF, 0x95,
|
||||
0x05, 0x0F, 0x00, 0x00, 0xAB, 0xB0, 0x00, 0xAE,
|
||||
0x75, 0xFD, 0x38, 0x07, 0x75, 0xEE, 0x8D, 0x45,
|
||||
0x7A, 0xFF, 0xE0, 0x56, 0x69, 0x72, 0x74, 0x75,
|
||||
0x61, 0x6C, 0x41, 0x6C, 0x6C, 0x6F, 0x63, 0x00,
|
||||
0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6C, 0x46,
|
||||
0x72, 0x65, 0x65, 0x00, 0x56, 0x69, 0x72, 0x74,
|
||||
0x75, 0x61, 0x6C, 0x50, 0x72, 0x6F, 0x74, 0x65,
|
||||
0x63, 0x74, 0x00, 0x00, 0x8B, 0x9D, 0x8D, 0x05,
|
||||
0x00, 0x00, 0x0B, 0xDB, 0x74, 0x0A, 0x8B, 0x03,
|
||||
0x87, 0x85, 0x91, 0x05, 0x00, 0x00, 0x89, 0x03,
|
||||
0x8D, 0xB5, 0xBD, 0x05, 0x00, 0x00, 0x83, 0x3E,
|
||||
0x00, 0x0F, 0x84, 0x15, 0x01, 0x00, 0x00, 0x6A,
|
||||
0x04, 0x68, 0x00, 0x10, 0x00, 0x00, 0x68, 0x00,
|
||||
0x18, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0x55, 0x51,
|
||||
0x89, 0x85, 0x53, 0x01, 0x00, 0x00, 0x8B, 0x46,
|
||||
0x04, 0x05, 0x0E, 0x01, 0x00, 0x00, 0x6A, 0x04,
|
||||
0x68, 0x00, 0x10, 0x00, 0x00, 0x50, 0x6A, 0x00,
|
||||
0xFF, 0x55, 0x51, 0x89, 0x85, 0x4F, 0x01, 0x00,
|
||||
0x00, 0x56, 0x8B, 0x1E, 0x03, 0x9D, 0x7D, 0x04,
|
||||
0x00, 0x00, 0xFF, 0xB5, 0x53, 0x01, 0x00, 0x00,
|
||||
0xFF, 0x76, 0x04, 0x50, 0x53, 0xE8, 0x2D, 0x05,
|
||||
0x00, 0x00, 0xB3, 0x00, 0x80, 0xFB, 0x00, 0x75,
|
||||
0x5E, 0xFE, 0x85, 0xE9, 0x00, 0x00, 0x00, 0x8B,
|
||||
0x3E, 0x03, 0xBD, 0x7D, 0x04, 0x00, 0x00, 0xFF,
|
||||
0x37, 0xC6, 0x07, 0xC3, 0xFF, 0xD7, 0x8F, 0x07,
|
||||
0x50, 0x51, 0x56, 0x53, 0x8B, 0xC8, 0x83, 0xE9,
|
||||
0x06, 0x8B, 0xB5, 0x4F, 0x01, 0x00, 0x00, 0x33,
|
||||
0xDB, 0x0B, 0xC9, 0x74, 0x2E, 0x78, 0x2C, 0xAC,
|
||||
0x3C, 0xE8, 0x74, 0x0A, 0xEB, 0x00, 0x3C, 0xE9,
|
||||
0x74, 0x04, 0x43, 0x49, 0xEB, 0xEB, 0x8B, 0x06,
|
||||
0xEB, 0x00, null, null, null, 0x75, 0xF3, 0x24,
|
||||
0x00, 0xC1, 0xC0, 0x18, 0x2B, 0xC3, 0x89, 0x06,
|
||||
0x83, 0xC3, 0x05, 0x83, 0xC6, 0x04, 0x83, 0xE9,
|
||||
0x05, 0xEB, 0xCE, 0x5B, 0x5E, 0x59, 0x58, 0xEB,
|
||||
0x08
|
||||
}, "ASPack 2.2 -> Alexey Solodovnikov & StarForce * 2009408"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
null, 0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9,
|
||||
0xEB, 0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01,
|
||||
0x00, 0x00, 0x00, 0xEB, 0x5D, 0xBB, 0xEC, 0xFF,
|
||||
0xFF, 0xFF, 0x03, 0xDD, 0x81, 0xEB, 0x00, 0x40,
|
||||
0x1C, 0x00
|
||||
}, "ASPack 2.x (without Poly) -> Solodovnikov Alexey"),
|
||||
|
||||
#endregion
|
||||
|
||||
#region 2.xx (Long)
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0xA8, 0x03, 0x00, 0x00, 0x61, 0x75, 0x08, 0xB8,
|
||||
0x01, 0x00, 0x00, 0x00, 0xC2, 0x0C, 0x00, 0x68,
|
||||
0x00, 0x00, 0x00, 0x00, 0xC3, 0x8B, 0x85, 0x26,
|
||||
0x04, 0x00, 0x00, 0x8D, 0x8D, 0x3B, 0x04, 0x00,
|
||||
0x00, 0x51, 0x50, 0xFF, 0x95
|
||||
}, "ASPack 2.xx"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0xA8, 0x03, null, null, 0x61, 0x75, 0x08, 0xB8,
|
||||
0x01, null, null, null, 0xC2, 0x0C, null, 0x68,
|
||||
null, null, null, null, 0xC3, 0x8B, 0x85, 0x26,
|
||||
0x04, null, null, 0x8D, 0x8D, 0x3B, 0x04, null,
|
||||
null, 0x51, 0x50, 0xFF, 0x95
|
||||
}, "ASPack 2.xx"),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Short
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x75, 0x00, 0xE9 }, "ASPack 1.05b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08.02"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08.02"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x41, 0x06, 0x00, 0x00, 0xEB, 0x41 }, "ASPack 1.08.04"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, null, null, null, null, 0xEB }, "ASPack 1.08.04"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x70, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.00"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x48, 0x11, 0x00, 0x00, 0xC3, 0x83 }, "ASPack 2.00.00"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x72, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, null, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.x -> Alexey Solodovnikov"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE9, 0x3D, 0x04, 0x00, 0x00 }, "ASPack 2.11"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0xF9, 0x11, 0x00, 0x00, 0xC3, 0x83 }, "ASPack 2.11"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81, 0xED }, "ASPack 1.02b/1.08.03"),
|
||||
|
||||
#endregion
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,21 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
// TODO: Add extraction and verify that all versions are detected
|
||||
public class AdvancedInstaller : IPEContentCheck
|
||||
// TODO: Add extraction
|
||||
// TODO: Verify that all versions are detected
|
||||
public class AdvancedInstaller : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -36,5 +43,23 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// TODO: Add version checking, if possible
|
||||
public class Armadillo : IPEContentCheck
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class Armadillo : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -42,5 +49,23 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,21 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
// Created by IndigoRose (creators of Setup Factory), primarily to be used to create autorun menus for various media.
|
||||
// Official website: https://www.autoplay.org/
|
||||
public class AutoPlayMediaStudio : IPEContentCheck, IScannable
|
||||
// TODO: Add extraction
|
||||
public class AutoPlayMediaStudio : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -23,13 +25,13 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
// Known to detect versions 5.0.0.3 - 8.1.0.0
|
||||
string name = pex.ProductName;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("AutoPlay Media Studio", StringComparison.OrdinalIgnoreCase))
|
||||
if (name?.StartsWith("AutoPlay Media Studio", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"AutoPlay Media Studio {GetVersion(pex)}";
|
||||
|
||||
// Currently too vague, may be re-enabled in the future
|
||||
/*
|
||||
name = Utilities.GetLegalCopyright(pex);
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Runtime Engine", StringComparison.OrdinalIgnoreCase))
|
||||
if (name?.StartsWith("Runtime Engine", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"AutoPlay Media Studio {GetVersion(pex)}";
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,19 +2,22 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
// 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
|
||||
public class CExe : IPEContentCheck, IScannable
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class CExe : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var stub = pex?.DOSStubHeader;
|
||||
@@ -23,7 +26,6 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// %Wo<57>a6.<2E>a6.<2E>a6.<2E>a6.<2E>{6.<2E>.).<2E>f6.<2E><>).<2E>`6.<2E><>0.<2E>`6.<2E>
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x25, 0x57, 0x6F, 0xC1, 0x61, 0x36, 0x01, 0x92,
|
||||
@@ -55,7 +57,6 @@ namespace BurnOutSharp.PackerType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
// TODO: Add extraction if viable
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
@@ -8,10 +10,15 @@ namespace BurnOutSharp.PackerType
|
||||
// TODO: Figure out how to more granularly determine versions like PiD,
|
||||
// at least for the 2.41 -> 2.75 range
|
||||
// TODO: Detect 3.15 and up (maybe looking for `Metamorphism`)
|
||||
public class EXEStealth : IContentCheck, IPEContentCheck
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class EXEStealth : IContentCheck, IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug, PortableExecutable pex, NewExecutable nex)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
@@ -36,7 +43,7 @@ namespace BurnOutSharp.PackerType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -60,5 +67,23 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class GenteeInstaller : IPEContentCheck
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class GenteeInstaller : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -40,5 +47,23 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,17 +6,20 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class InnoSetup : INEContentCheck, IPEContentCheck, IScannable
|
||||
// TODO: Add extraction - https://github.com/dscharrer/InnoExtract
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class InnoSetup : INewExecutableCheck, IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckNEContents(string file, NewExecutable nex, bool includeDebug)
|
||||
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
// Get the DOS stub from the executable, if possible
|
||||
var stub = nex?.DOSStubHeader;
|
||||
@@ -37,7 +40,7 @@ namespace BurnOutSharp.PackerType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -78,8 +81,6 @@ namespace BurnOutSharp.PackerType
|
||||
}
|
||||
}
|
||||
|
||||
// TOOO: Add Inno Setup extraction
|
||||
// https://github.com/dscharrer/InnoExtract
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
|
||||
@@ -2,17 +2,20 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class InstallAnywhere : IPEContentCheck, IScannable
|
||||
// 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 : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -20,11 +23,11 @@ namespace BurnOutSharp.PackerType
|
||||
return null;
|
||||
|
||||
string name = pex.FileDescription;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("InstallAnywhere Self Extractor", StringComparison.OrdinalIgnoreCase))
|
||||
if (name?.StartsWith("InstallAnywhere Self Extractor", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"InstallAnywhere {GetVersion(pex)}";
|
||||
|
||||
name = pex.ProductName;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("InstallAnywhere", StringComparison.OrdinalIgnoreCase))
|
||||
if (name?.StartsWith("InstallAnywhere", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"InstallAnywhere {GetVersion(pex)}";
|
||||
|
||||
return null;
|
||||
@@ -43,7 +46,6 @@ namespace BurnOutSharp.PackerType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
// TODO: Add extraction, which may be possible with the current libraries but needs to be investigated further.
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -2,18 +2,21 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class InstallerVISE : IPEContentCheck, IScannable
|
||||
// TODO: Add extraction - https://github.com/Bioruebe/UniExtract2
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class InstallerVISE : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
//TODO: Add exact version detection for Windows builds, make sure versions before 3.X are detected as well, and detect the Mac builds.
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -35,8 +38,6 @@ namespace BurnOutSharp.PackerType
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: Add Installer VISE extraction
|
||||
// https://github.com/Bioruebe/UniExtract2
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
// TODO: Add extraction, seems to primarily use MSZip compression.
|
||||
public class IntelInstallationFramework : IPEContentCheck
|
||||
public class IntelInstallationFramework : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -33,5 +39,23 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,19 +3,21 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
// TODO: Add extraction, which should be possible with LibMSPackN, but it refuses to extract due to SFX files lacking the typical CAB identifiers.
|
||||
public class MicrosoftCABSFX : IPEContentCheck, IScannable
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class MicrosoftCABSFX : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -23,11 +25,11 @@ namespace BurnOutSharp.PackerType
|
||||
return null;
|
||||
|
||||
string name = pex.InternalName;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.Equals("Wextract", StringComparison.OrdinalIgnoreCase))
|
||||
if (name?.Equals("Wextract", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
|
||||
name = pex.OriginalFileName;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.Equals("WEXTRACT.EXE", StringComparison.OrdinalIgnoreCase))
|
||||
if (name?.Equals("WEXTRACT.EXE", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
|
||||
// Get the .data section, if it exists
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class NSIS : IPEContentCheck
|
||||
// TODO: Add extraction
|
||||
public class NSIS : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -38,5 +45,23 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,19 @@
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
// TODO: Add extraction and better version detection
|
||||
public class PECompact : IPEContentCheck
|
||||
// TODO: Better version detection - https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
// TODO: Add extraction
|
||||
public class PECompact : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -37,5 +44,23 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class PEtite : IPEContentCheck
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class PEtite : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -19,5 +27,23 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,21 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class SetupFactory : IPEContentCheck, IScannable
|
||||
// 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 : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -21,16 +25,16 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
// Known to detect versions 7.0.5.1 - 9.1.0.0
|
||||
string name = pex.LegalCopyright;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Setup Engine", StringComparison.OrdinalIgnoreCase))
|
||||
if (name?.StartsWith("Setup Engine", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Setup Factory {GetVersion(pex)}";
|
||||
|
||||
name = pex.ProductName;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Setup Factory", StringComparison.OrdinalIgnoreCase))
|
||||
if (name?.StartsWith("Setup Factory", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Setup Factory {GetVersion(pex)}";
|
||||
|
||||
// Known to detect version 5.0.1 - 6.0.1.3
|
||||
name = pex.FileDescription;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Setup Factory", StringComparison.OrdinalIgnoreCase))
|
||||
if (name?.StartsWith("Setup Factory", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Setup Factory {GetVersion(pex)}";
|
||||
|
||||
// Longer version of the check that can be used if false positves become an issue:
|
||||
@@ -52,8 +56,6 @@ namespace BurnOutSharp.PackerType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
// 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)
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Matching;
|
||||
using BurnOutSharp.Interfaces;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class Shrinker : IPEContentCheck
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class Shrinker : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -23,5 +28,23 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class UPX : IPEContentCheck
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class UPX : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -44,6 +52,24 @@ namespace BurnOutSharp.PackerType
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
using BurnOutSharp.Tools;
|
||||
using SharpCompress.Archives;
|
||||
@@ -10,13 +11,13 @@ using SharpCompress.Archives.Rar;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class WinRARSFX : IPEContentCheck, IScannable
|
||||
public class WinRARSFX : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -80,7 +81,10 @@ namespace BurnOutSharp.PackerType
|
||||
string tempFile = Path.Combine(tempPath, entry.Key);
|
||||
entry.WriteToFile(tempFile);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,14 +96,20 @@ namespace BurnOutSharp.PackerType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
using BurnOutSharp.Tools;
|
||||
using SharpCompress.Archives;
|
||||
@@ -12,13 +13,13 @@ using SharpCompress.Archives.Zip;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class WinZipSFX : INEContentCheck, IPEContentCheck, IScannable
|
||||
public class WinZipSFX : INewExecutableCheck, IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckNEContents(string file, NewExecutable nex, bool includeDebug)
|
||||
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
// Get the DOS stub from the executable, if possible
|
||||
var stub = nex?.DOSStubHeader;
|
||||
@@ -37,7 +38,7 @@ namespace BurnOutSharp.PackerType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -157,7 +158,10 @@ namespace BurnOutSharp.PackerType
|
||||
string tempFile = Path.Combine(tempPath, entry.Key);
|
||||
entry.WriteToFile(tempFile);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,14 +173,20 @@ namespace BurnOutSharp.PackerType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -4,19 +4,21 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
using BurnOutSharp.Tools;
|
||||
using Wise = WiseUnpacker.WiseUnpacker;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class WiseInstaller : INEContentCheck, IPEContentCheck, IScannable
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class WiseInstaller : INewExecutableCheck, IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckNEContents(string file, NewExecutable nex, bool includeDebug)
|
||||
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
// Get the DOS stub from the executable, if possible
|
||||
var stub = nex?.DOSStubHeader;
|
||||
@@ -40,7 +42,7 @@ namespace BurnOutSharp.PackerType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -110,14 +112,20 @@ namespace BurnOutSharp.PackerType
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
// Remove temporary path references
|
||||
Utilities.StripFromKeys(protections, tempPath);
|
||||
|
||||
return protections;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (scanner.IncludeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class dotFuscator : IPEContentCheck
|
||||
// TODO: Add extraction
|
||||
public class dotFuscator : IPortableExecutableCheck, IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public bool ShouldScan(byte[] magic) => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -35,5 +42,23 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
return Scan(scanner, fs, file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
// TODO: Figure out how to get version numbers
|
||||
public class ActiveMARK : IContentCheck, IPEContentCheck
|
||||
public class ActiveMARK : IContentCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug, PortableExecutable pex, NewExecutable nex)
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
@@ -22,7 +22,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
0x20, 0xC2, 0x16, 0x00, 0xA8, 0xC1, 0x16, 0x00,
|
||||
0xB8, 0xC1, 0x16, 0x00, 0x86, 0xC8, 0x16, 0x00,
|
||||
0x9A, 0xC1, 0x16, 0x00, 0x10, 0xC2, 0x16, 0x00
|
||||
}, "ActiveMARK 5"),
|
||||
}, "ActiveMARK 5 (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
@@ -32,13 +32,153 @@ namespace BurnOutSharp.ProtectionType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the entry point data, if it exists
|
||||
if (pex.EntryPointRaw != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Checks sourced from https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x79, 0x11, 0x7F, 0xAB, 0x9A, 0x4A, 0x83, 0xB5,
|
||||
0xC9, 0x6B, 0x1A, 0x48, 0xF9, 0x27, 0xB4, 0x25,
|
||||
}, "ActiveMARK"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x20, 0x2D, 0x2D, 0x4D, 0x50, 0x52, 0x4D, 0x4D,
|
||||
0x47, 0x56, 0x41, 0x2D, 0x2D, 0x00, 0x75, 0x73,
|
||||
0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C,
|
||||
0x00, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x42, 0x6F, 0x78, 0x41, 0x00, 0x54, 0x68, 0x69,
|
||||
0x73, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63,
|
||||
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x61,
|
||||
0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x72, 0x75, 0x6E,
|
||||
0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6E,
|
||||
0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20,
|
||||
0x64, 0x65, 0x62, 0x75, 0x67,
|
||||
}, "ActiveMARK 5.x -> Trymedia Systems Inc. (h)"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x20, 0x2D, 0x2D, 0x4D, 0x50, 0x52, 0x4D, 0x4D,
|
||||
0x47, 0x56, 0x41, 0x2D, 0x2D, 0x00, 0x75, 0x73,
|
||||
0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C,
|
||||
0x00, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x42, 0x6F, 0x78, 0x41, 0x00, 0x54, 0x68, 0x69,
|
||||
0x73, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63,
|
||||
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x61,
|
||||
0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x72, 0x75, 0x6E,
|
||||
0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6E,
|
||||
0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20,
|
||||
0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x65, 0x72,
|
||||
0x20, 0x69, 0x6E, 0x20, 0x6D, 0x65, 0x6D, 0x6F,
|
||||
0x72, 0x79, 0x2E, 0x0D, 0x0A, 0x50, 0x6C, 0x65,
|
||||
0x61, 0x73, 0x65, 0x20, 0x75, 0x6E, 0x6C, 0x6F,
|
||||
0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64,
|
||||
0x65, 0x62, 0x75, 0x67, 0x67, 0x65, 0x72, 0x20,
|
||||
0x61, 0x6E, 0x64, 0x20, 0x72, 0x65, 0x73, 0x74,
|
||||
0x61, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20,
|
||||
0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74,
|
||||
0x69, 0x6F, 0x6E, 0x2E, 0x00, 0x57, 0x61, 0x72,
|
||||
0x6E, 0x69, 0x6E, 0x67,
|
||||
}, "ActiveMARK 5.x -> Trymedia Systems,Inc."),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0xBE, 0x48, 0x01, 0x40, 0x00, 0xAD, 0x8B, 0xF8,
|
||||
0x95, 0xA5, 0x33, 0xC0, 0x33, 0xC9, 0xAB, 0x48,
|
||||
0xAB, 0xF7, 0xD8, 0xB1, 0x04, 0xF3, 0xAB, 0xC1,
|
||||
0xE0, 0x0A, 0xB5, 0x1C, 0xF3, 0xAB, 0xAD, 0x50,
|
||||
0x97, 0x51, 0xAD, 0x87, 0xF5, 0x58, 0x8D, 0x54,
|
||||
0x86, 0x5C, 0xFF, 0xD5, 0x72, 0x5A, 0x2C, 0x03,
|
||||
0x73, 0x02, 0xB0, 0x00, 0x3C, 0x07, 0x72, 0x02,
|
||||
0x2C, 0x03, 0x50, 0x0F, 0xB6, 0x5F, 0xFF, 0xC1,
|
||||
0xE3, 0x03, 0xB3, 0x00, 0x8D, 0x1C, 0x5B, 0x8D,
|
||||
0x9C, 0x9E, 0x0C, 0x10, 0x00, 0x00, 0xB0, 0x01,
|
||||
0x67, 0xE3, 0x29, 0x8B, 0xD7, 0x2B, 0x56, 0x0C,
|
||||
0x8A, 0x2A, 0x33, 0xD2, 0x84, 0xE9, 0x0F, 0x95,
|
||||
0xC6, 0x52, 0xFE, 0xC6, 0x8A, 0xD0, 0x8D, 0x14,
|
||||
0x93, 0xFF, 0xD5, 0x5A, 0x9F, 0x12, 0xC0, 0xD0,
|
||||
0xE9, 0x74, 0x0E, 0x9E, 0x1A, 0xF2, 0x74, 0xE4,
|
||||
0xB4, 0x00, 0x33, 0xC9, 0xB5, 0x01, 0xFF, 0x55,
|
||||
0xCC, 0x33, 0xC9, 0xE9, 0xDF, 0x00, 0x00, 0x00,
|
||||
0x8B, 0x5E, 0x0C, 0x83, 0xC2, 0x30, 0xFF, 0xD5,
|
||||
0x73, 0x50, 0x83, 0xC2, 0x30, 0xFF, 0xD5, 0x72,
|
||||
0x1B, 0x83, 0xC2, 0x30, 0xFF, 0xD5, 0x72, 0x2B,
|
||||
0x3C, 0x07, 0xB0, 0x09, 0x72, 0x02, 0xB0, 0x0B,
|
||||
0x50, 0x8B, 0xC7, 0x2B, 0x46, 0x0C, 0xB1, 0x80,
|
||||
0x8A, 0x00, 0xEB, 0xCF, 0x83, 0xC2, 0x60, 0xFF,
|
||||
0xD5, 0x87, 0x5E, 0x10, 0x73, 0x0D, 0x83, 0xC2,
|
||||
0x30, 0xFF, 0xD5, 0x87, 0x5E, 0x14, 0x73, 0x03,
|
||||
0x87, 0x5E, 0x18, 0x3C, 0x07, 0xB0, 0x08, 0x72,
|
||||
0x02, 0xB0, 0x0B, 0x50, 0x53, 0x8D, 0x96, 0x7C,
|
||||
0x07, 0x00, 0x00, 0xFF, 0x55, 0xD0, 0x5B, 0x91,
|
||||
0xEB, 0x77, 0x3C, 0x07, 0xB0, 0x07, 0x72, 0x02,
|
||||
0xB0, 0x0A, 0x50, 0x87, 0x5E, 0x10, 0x87, 0x5E,
|
||||
0x14, 0x89, 0x5E, 0x18, 0x8D, 0x96, 0xC4, 0x0B,
|
||||
0x00, 0x00, 0xFF, 0x55, 0xD0, 0x50, 0x48,
|
||||
}, "ActiveMARK 5.x -> Trymedia Systems,Inc. (h)"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x79, 0x07, 0x0F, 0xB7, 0x07, 0x47, 0x50, 0x47,
|
||||
0xB9, 0x57, 0x48, 0xF2, 0xAE, 0x55, 0xFF, 0x96,
|
||||
0x84, null, 0x00, 0x00, 0x09, 0xC0, 0x74, 0x07,
|
||||
0x89, 0x03, 0x83, 0xC3, 0x04, 0xEB, 0xD8, 0xFF,
|
||||
0x96, 0x88, null, 0x00, 0x00, 0x61, 0xE9, null,
|
||||
null, null, 0xFF,
|
||||
}, "ActiveMARK R5.31.1140 -> Trymedia"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x89, 0x25, null, null, null, null, null, null,
|
||||
null, null, 0xEB,
|
||||
}, "ActiveMark -> Trymedia Systems Inc."),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x89, 0x25, null, null, null, null, 0x33, 0xED,
|
||||
0x55, 0x8B, 0xEC, 0xE8, null, null, null, null,
|
||||
0x8B, 0xD0, 0x81, 0xE2, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x89, 0x15, null, null, null, null, 0x8B, 0xD0,
|
||||
0xC1, 0xEA, 0x08, 0x81, 0xE2, 0xFF, 0x00, 0x00,
|
||||
0x00, 0xA3, null, null, null, null, 0xD1, 0xE0,
|
||||
0x0F, 0x93, 0xC3, 0x33, 0xC0, 0x8A, 0xC3, 0xA3,
|
||||
null, null, null, null, 0x68, 0xFF, 0x00, 0x00,
|
||||
0x00, 0xE8, null, null, null, null, 0x6A, 0x00,
|
||||
0xE8, null, null, null, null, 0xA3, null, null,
|
||||
null, null, 0xBB, null, null, null, null, 0xC7,
|
||||
0x03, 0x44, 0x00, 0x00, 0x00,
|
||||
}, "ActiveMark -> Trymedia Systems Inc."),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
|
||||
// Get the overlay data, if it exists
|
||||
if (pex.OverlayRaw != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// (char)0x00 + TMSAMVOH
|
||||
new ContentMatchSet(new byte?[] { 0x00, 0x54, 0x4D, 0x53, 0x41, 0x4D, 0x56, 0x4F, 0x48, }, "ActiveMARK"),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.OverlayRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
|
||||
// Get the last .bss section, if it exists
|
||||
var bssSectionRaw = pex.ReadRawSection(".bss", first: false);
|
||||
if (bssSectionRaw != null)
|
||||
|
||||
92
BurnOutSharp/ProtectionType/AegiSoft.cs
Normal file
92
BurnOutSharp/ProtectionType/AegiSoft.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
/// <summary>
|
||||
/// AegiSoft License Manager was made AegiSoft, which was later bought by Real Networks, the makes of RealArcade (https://www.crunchbase.com/organization/aegisoft).
|
||||
/// It allowed publishers to give users a time-based free trial of software.
|
||||
/// Based on "Asc006.exe", AegiSoft License Manager may also have been referred to as "Software-On-Demand License Manager", or it may just be a distinct component of the larger product.
|
||||
/// The single sample investigated was only able to run on Windows 9x (Redump entry 73521/IA item "Nova_HoyleCasino99USA").
|
||||
/// Based on the packaging from IA item "Nova_HoyleCasino99USA", it seems that additional software from "www.1-800-software.com" is likely to be protected with AegiSoft License Manager or other DRM.
|
||||
/// References and further information:
|
||||
/// https://pitchbook.com/profiles/company/118805-59
|
||||
/// https://web.archive.org/web/19990417191351/http://www.aegisoft.com:80/
|
||||
/// </summary>
|
||||
public class AegiSoft : IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// There are possibly identifying Product Names for some files used in AegiSoft License Manager, but they were deemed too overmatching to use for the time being (Found in Redump entry 73521/IA item "Nova_HoyleCasino99USA")..
|
||||
// "Asc001.dll" has the Product Name "Install Dynamic Link Library".
|
||||
// "Asc002.dll" has the Product Name "Transact Dynamic Link Library".
|
||||
// "Asc003.dll" has the Product Name "Uninstall Dynamic Link Library".
|
||||
// "Asc005.dll" has the Product Name "OrderWizard Dynamic Link Library".
|
||||
// "Asc006.exe" has the Product Name "AGENT Application".
|
||||
|
||||
// Get the .data section, if it exists
|
||||
if (pex.DataSectionRaw != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Found in "Asc001.dll", "Asc002.dll", "Asc003.dll", "Asc005.dll", "Asc006.exe", and "AscLM.cpl" (Redump entry 73521/IA item "Nova_HoyleCasino99USA").
|
||||
// ÿÿÿÿ\\.\ASCLM
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x5C, 0x5C, 0x2E, 0x5C,
|
||||
0x41, 0x53, 0x43, 0x4C, 0x4D
|
||||
}, "AegiSoft License Manager"),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found in Redump entry 73521/IA item "Nova_HoyleCasino99USA".
|
||||
new PathMatchSet(new PathMatch("AscLM.cpl", useEndsWith: true), "AegiSoft License Manager"),
|
||||
new PathMatchSet(new PathMatch("AscLM.vxd", useEndsWith: true), "AegiSoft License Manager"),
|
||||
new PathMatchSet(new PathMatch("AscLMd.vxd", useEndsWith: true), "AegiSoft License Manager"),
|
||||
|
||||
// There are a few other files present, but the file names on their own may be too overmatching. Due to the small sample size, it's not sure if these files are always present together.
|
||||
// These files are "Asc001.dll", "Asc002.dll", "Asc003.dll", "Asc005.dll", and "Asc006.exe" (Found in Redump entry 73521/IA item "Nova_HoyleCasino99USA").
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckFilePath(string path)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found in Redump entry 73521/IA item "Nova_HoyleCasino99USA".
|
||||
new PathMatchSet(new PathMatch("AscLM.cpl", useEndsWith: true), "AegiSoft License Manager"),
|
||||
new PathMatchSet(new PathMatch("AscLM.vxd", useEndsWith: true), "AegiSoft License Manager"),
|
||||
new PathMatchSet(new PathMatch("AscLMd.vxd", useEndsWith: true), "AegiSoft License Manager"),
|
||||
|
||||
// There are a few other files present, but the file names on their own may be too overmatching. Due to the small sample size, it's not sure if these files are always present together.
|
||||
// These files are "Asc001.dll", "Asc002.dll", "Asc003.dll", "Asc005.dll", and "Asc006.exe" (Found in Redump entry 73521/IA item "Nova_HoyleCasino99USA").
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,5 +3,7 @@
|
||||
public class AlphaAudio
|
||||
{
|
||||
// TODO: Implement - http://settec.net/eng/pro_cd.html
|
||||
// References and further information:
|
||||
// https://www.cdmediaworld.com/hardware/cdrom/cd_protections_alpha.shtml
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
/// <summary>
|
||||
/// Alpha-DVD is a DVD-Video copy protection created by SETTEC.
|
||||
/// References and further information:
|
||||
/// http://www.gonsuke.co.jp/protect.html
|
||||
/// http://copy2.info/copy_protect.html
|
||||
/// http://s2000.yokinihakarae.com/sub03-10-2(DVD).html
|
||||
/// https://www.cdmediaworld.com/hardware/cdrom/cd_protections_alpha.shtml
|
||||
/// </summary>
|
||||
public class AlphaDVD : IPathCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
@@ -11,7 +20,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("PlayDVD.exe", useEndsWith: true), "Alpha-DVD"),
|
||||
new PathMatchSet(new PathMatch("PlayDVD.exe", useEndsWith: true), "Alpha-DVD (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -22,7 +31,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("PlayDVD.exe", useEndsWith: true), "Alpha-DVD"),
|
||||
new PathMatchSet(new PathMatch("PlayDVD.exe", useEndsWith: true), "Alpha-DVD (Unconfirmed - Please report to us on Github"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
@@ -1,9 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
/// <summary>
|
||||
/// Alpha-ROM is a form of copy protection created by SETTEC. It is known to make use of twin sectors as well as region locking.
|
||||
/// Later forms of Alpha-ROM appear to be digital only, and it's currently unsure what forms of protection the digital only version includes, except that it does make use of region locking.
|
||||
/// It seems that Alpha-ROM was used in Visual Novels using certain game engines, most notably RealLive and Siglus (https://forums.fuwanovel.net/topic/20927-cannot-crack-siglus-engine-with-alpharom/).
|
||||
/// Not every Siglus engine game uses Alpha-ROM (Source: https://sample9.dmm.co.jp/digital/pcgame/vsat_0263/vsat_0263t.zip {Official trial mirror}).
|
||||
/// Not every RealLive engine game uses Alpha-ROM (Source: IA item "Kanon_Standard_Edition_Japan").
|
||||
/// Alpha-ROM also seems to have made use of something called "Alpha-DPS" for non-executable data files (http://www.gonsuke.co.jp/protect.html).
|
||||
/// Example of Alpha-ROM (official trial download mirrors):
|
||||
/// (Siglus Engine)
|
||||
/// http://suezou.dyndns.org/dl2018/key/summer_pokets/Summer_Pockets_trial.zip
|
||||
/// http://mirror.studio-ramble.com/upload/300/201103/RewriteTE_Ver200.zip
|
||||
/// http://suezou.dyndns.org/dl2012/tone-works/hatsukoi1-1/hatsukoi_tr_web.zip
|
||||
/// (RealLive Engine)
|
||||
/// http://suezou.dyndns.org/dl2020/hadashi/princess_heart_link/phl_trial.exe
|
||||
/// https://archive.org/details/little-busters-regular-edition-iso-only-2007
|
||||
/// Games that may have Alpha-ROM:
|
||||
/// http://cpdb.kemuri-net.com/ (Protection database that includes many different protections, including Alpha-ROM).
|
||||
/// https://w.atwiki.jp/tirasinoura/pages/3.html (List of games with Alpha-ROM, and explains some version differences).
|
||||
/// https://vndb.org/r?f=fwSiglusEngine- (VNs made with an engine known to use Alpha-ROM).
|
||||
/// https://vndb.org/r?f=fwRealLive- (VNs made with an engine known to use Alpha-ROM).
|
||||
/// References and further information:
|
||||
/// http://hhg.sakura.ne.jp/cd-dvd/dust/alpha/alpha_index.htm
|
||||
/// https://www.weblio.jp/content/Alpha-ROM
|
||||
/// https://ameblo.jp/michael-j-fox/entry-10046574609.html
|
||||
/// http://s2000.yokinihakarae.com/sub03-10-2(DVD).html
|
||||
/// https://www.cdmediaworld.com/hardware/cdrom/cd_protections_alpha.shtml
|
||||
/// Special thanks to Bestest for researching this protection and helping make further improvements possible!
|
||||
/// </summary>
|
||||
|
||||
// TODO: Alternative string possibilities:
|
||||
// - \AlphaDiscLog.txt
|
||||
// - \SETTEC
|
||||
@@ -11,11 +41,14 @@ namespace BurnOutSharp.ProtectionType
|
||||
// - SETTEC0000SETTEC1111
|
||||
// - SOFTWARE\SETTEC
|
||||
// TODO: Are there version numbers?
|
||||
public class AlphaROM : IPEContentCheck
|
||||
public class AlphaROM : IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// TODO: Add support for detecting Alpha-ROM found in older games made with the RealLive engine.
|
||||
// TODO: Add version detection for Alpha-ROM.
|
||||
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
@@ -27,9 +60,11 @@ namespace BurnOutSharp.ProtectionType
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// \SETTEC
|
||||
// Found in IA item "little-busters-regular-edition-iso-only-2007"
|
||||
new ContentMatchSet(new byte?[] { 0x5C, 0x53, 0x45, 0x54, 0x54, 0x45, 0x43 }, "Alpha-ROM"),
|
||||
|
||||
// SETTEC0000
|
||||
// Found in IA item "little-busters-regular-edition-iso-only-2007"
|
||||
new ContentMatchSet(new byte?[] { 0x53, 0x45, 0x54, 0x54, 0x45, 0x43, 0x30, 0x30, 0x30, 0x30 }, "Alpha-ROM"),
|
||||
};
|
||||
|
||||
@@ -38,6 +73,65 @@ namespace BurnOutSharp.ProtectionType
|
||||
return match;
|
||||
}
|
||||
|
||||
// Get the .rdata section, if it exists
|
||||
if (pex.ResourceDataSectionRaw != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// T.h.i.s. .G.a.m.e. .i.s. .J.a.p.a.n. .O.n.l.y.....S0n0²0ü0à0o0åe,gýV…Qg0n0.0×0ì0¤0ïSý€g0Y0.0....ÕR\OU0[0‹0k0o0 ..0 .åe,gžŠHrW.i.n.d.o.w.s. ..0 .L0Å_.‰g0Y0.0....²0ü0à0’0B}†NW0~0Y0.0....åe,gžŠHrW.i.n.d.o.w.s
|
||||
// Found in games using the Siglus engine.
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x54, 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x47, 0x00,
|
||||
0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, 0x00,
|
||||
0x20, 0x00, 0x4A, 0x00, 0x61, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6E, 0x00,
|
||||
0x20, 0x00, 0x4F, 0x00, 0x6E, 0x00, 0x6C, 0x00, 0x79, 0x00, 0x0A, 0x00,
|
||||
0x0A, 0x00, 0x53, 0x30, 0x6E, 0x30, 0xB2, 0x30, 0xFC, 0x30, 0xE0, 0x30,
|
||||
0x6F, 0x30, 0xE5, 0x65, 0x2C, 0x67, 0xFD, 0x56, 0x85, 0x51, 0x67, 0x30,
|
||||
0x6E, 0x30, 0x7F, 0x30, 0xD7, 0x30, 0xEC, 0x30, 0xA4, 0x30, 0xEF, 0x53,
|
||||
0xFD, 0x80, 0x67, 0x30, 0x59, 0x30, 0x02, 0x30, 0x0A, 0x00, 0x0A, 0x00,
|
||||
0xD5, 0x52, 0x5C, 0x4F, 0x55, 0x30, 0x5B, 0x30, 0x8B, 0x30, 0x6B, 0x30,
|
||||
0x6F, 0x30, 0x20, 0x00, 0x0E, 0x30, 0x20, 0x00, 0xE5, 0x65, 0x2C, 0x67,
|
||||
0x9E, 0x8A, 0x48, 0x72, 0x57, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x64, 0x00,
|
||||
0x6F, 0x00, 0x77, 0x00, 0x73
|
||||
}, "Alpha-ROM"),
|
||||
|
||||
// This Game is Japan Only..‚±‚̃Q.[ƒ€‚Í“ú–{.‘“à‚ł̂݃vƒŒƒC‰Â”\‚Å‚·.B..“®.삳‚¹‚é‚É‚Í .w “ú–{Œê”ÅWindows
|
||||
// Found in games using the RealLive engine.
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x54, 0x68, 0x69, 0x73, 0x20, 0x47, 0x61, 0x6D, 0x65, 0x20, 0x69, 0x73,
|
||||
0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x4F, 0x6E, 0x6C, 0x79, 0x0A,
|
||||
0x0A, 0x82, 0xB1, 0x82, 0xCC, 0x83, 0x51, 0x81, 0x5B, 0x83, 0x80, 0x82,
|
||||
0xCD, 0x93, 0xFA, 0x96, 0x7B, 0x8D, 0x91, 0x93, 0xE0, 0x82, 0xC5, 0x82,
|
||||
0xCC, 0x82, 0xDD, 0x83, 0x76, 0x83, 0x8C, 0x83, 0x43, 0x89, 0xC2, 0x94,
|
||||
0x5C, 0x82, 0xC5, 0x82, 0xB7, 0x81, 0x42, 0x0A, 0x0A, 0x93, 0xAE, 0x8D,
|
||||
0xEC, 0x82, 0xB3, 0x82, 0xB9, 0x82, 0xE9, 0x82, 0xC9, 0x82, 0xCD, 0x20,
|
||||
0x81, 0x77, 0x20, 0x93, 0xFA, 0x96, 0x7B, 0x8C, 0xEA, 0x94, 0xC5, 0x57,
|
||||
0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73
|
||||
}, "Alpha-ROM"),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
|
||||
// Get the overlay data, if it exists
|
||||
if (pex.OverlayRaw != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Found in Redump entry 84122.
|
||||
// SETTEC0000
|
||||
new ContentMatchSet(new byte?[] { 0x53, 0x45, 0x54, 0x54, 0x45, 0x43, 0x30, 0x30, 0x30, 0x30 }, "Alpha-ROM"),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.OverlayRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
/// <summary>
|
||||
/// Bitpool is a copy protection that seems to resemble SafeDisc in several ways, found mostly in German releases.
|
||||
/// Makes use of bad sectors, and contains what appears to be an encrypted game executable always called "CD.IDX" (similar to SafeDisc ICD files), which seems to be present in every disc protected with it.
|
||||
/// The "CD.IDX" appears to purposefully contain bad sectors in most, if not all, cases.
|
||||
/// Bitpool is a copy protection found most commonly in German releases.
|
||||
/// It makes use of bad sectors, and contains what appears to be an encrypted game executable always called "CD.IDX" (similar to SafeDisc ICD files), which seems to be present in every disc protected with it.
|
||||
/// I'm not entirely sure of the extent that Bitpool "creatively uses" the ISO9660 filesystem, but there are many, many issues in the filesystems present on these discs.
|
||||
/// The most obvious example is the "CD.IDX" file universally found in Bitpool games, which is often reported as being too large of a file to fit on a CD, as well as various other files that do the same but tend to vary from disc to disc.
|
||||
/// Investigating these files in a hex editor gives confusing results, at times matching the setup executable, or having other seemingly valid data before reaching the erroneous part of the file.
|
||||
/// Most Bitpool protected discs have errors (according to Redump/DIC standards) ranging in the 10,000's, though it seems that pre-1999 discs typically have 1-4 errors (Redump entries 48276 + 51376).
|
||||
/// A "bitpool.rsc" file is present in some, but not all Bitpool protected games. The purpose of it is so far unclear.
|
||||
/// Bitpool protected discs made 1999+ without additional intentional audio tracks always seem to have 3 tracks. The first being the "real" contents of the disc, the second being a brief audio track, and the third being a seemingly empty data track.
|
||||
/// Discs with additional intentional audio tracks don't seem to have any dedicated copy protection tracks, instead having only the main data track, and the additional sound tracks as expected.
|
||||
/// Discs made pre-1999 seem to not have any additional tracks specifically related to Bitpool present.
|
||||
/// It seems likely that some internal indicator may be present for executables with Bitpool, but it is currently unknown.
|
||||
/// Current files that are or may be related to Bitpool but aren't currently checked for include:
|
||||
/// "_" - A corrupted/padded file present in multiple games, in some cases may be a copy of CD.IDX? (Redump entries 35480 + 67046 + 68160).
|
||||
/// "__" - A corrupted/padded file present in at least one game (Redump entry 50229).
|
||||
/// "01.rsc" + "jmptable.rsc" - Corrupted/Padded files present in at least one game (Redump entry 52626).
|
||||
/// "AMAZON.GDB" + "DB.GDB" + "DV.GDB" + "MENTOR.GDB" + "PIMMONS.GDB" + "SAJIKI.GDB" + "TUTORIALS.GDB" - Corrupted/Padded files found in a specific game containing Bitpool (Redump entry 44976).
|
||||
/// "BDA.cab" + "BDB.RSC" - Corrupted/Padded files present in one specific game, with the file names seemingly representing the specific game they're found on (Redump entry 67046).
|
||||
/// "ds.dat" - A corrupted/padded file present in one specific game, with the file name seemingly representing the specific game it's found on (Redump entry 35476).
|
||||
/// Many other game specific, corrupted/padded files not worth noting down individually.
|
||||
/// </summary>
|
||||
public class Bitpool : IPathCheck
|
||||
{
|
||||
@@ -19,6 +35,19 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
new PathMatchSet(new PathMatch("bitpool.rsc", useEndsWith: true), "Bitpool"),
|
||||
new PathMatchSet(new PathMatch("CD.IDX", useEndsWith: true), "Bitpool"),
|
||||
|
||||
// Completely empty file present on multiple discs with Bitpool (Redump entries 52626 and 50229)
|
||||
new PathMatchSet(new PathMatch("LEADOUT.OFS", useEndsWith: true), "Bitpool"),
|
||||
|
||||
// A set of 4 identically sized (within the same game, not between games), corrupted/padded files present in several games (Redump entries 31782 + 35476).
|
||||
// Both examples with only having the first letter uppercase and as the whole file name being uppercase have been seen.
|
||||
new PathMatchSet(new List<PathMatch>
|
||||
{
|
||||
new PathMatch("Crc_a", useEndsWith: true),
|
||||
new PathMatch("Crc_b", useEndsWith: true),
|
||||
new PathMatch("Crc_c", useEndsWith: true),
|
||||
new PathMatch("Crc_d", useEndsWith: true),
|
||||
}, "Bitpool"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -31,6 +60,9 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
new PathMatchSet(new PathMatch("bitpool.rsc", useEndsWith: true), "Bitpool"),
|
||||
new PathMatchSet(new PathMatch("CD.IDX", useEndsWith: true), "Bitpool"),
|
||||
|
||||
// Completely empty file present on multiple discs with Bitpool (Redump entries 52626 and 50229)
|
||||
new PathMatchSet(new PathMatch("LEADOUT.OFS", useEndsWith: true), "Bitpool"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
@@ -11,8 +12,8 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("Byteshield.dll", useEndsWith: true), "ByteShield"),
|
||||
new PathMatchSet(new PathMatch(".bbz", useEndsWith: true), "ByteShield"),
|
||||
new PathMatchSet(new PathMatch("Byteshield.dll", useEndsWith: true), "ByteShield (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch(".bbz", useEndsWith: true), "ByteShield (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -23,8 +24,8 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("Byteshield.dll", useEndsWith: true), "ByteShield"),
|
||||
new PathMatchSet(new PathMatch(".bbz", useEndsWith: true), "ByteShield"),
|
||||
new PathMatchSet(new PathMatch("Byteshield.dll", useEndsWith: true), "ByteShield (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch(".bbz", useEndsWith: true), "ByteShield (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class CDCheck : IPEContentCheck
|
||||
public class CDCheck : IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
|
||||
@@ -4,14 +4,15 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class CDDVDCops : IContentCheck, INEContentCheck, IPEContentCheck, IPathCheck
|
||||
public class CDDVDCops : IContentCheck, INewExecutableCheck, IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug, PortableExecutable pex, NewExecutable nex)
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
@@ -24,14 +25,14 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C,
|
||||
0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20
|
||||
}, GetVersion, "CD-Cops"),
|
||||
}, GetVersion, "CD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
|
||||
// // DVD-Cops, ver.
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x44, 0x56, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73,
|
||||
0x2C, 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20
|
||||
}, GetVersion, "DVD-Cops"),
|
||||
}, GetVersion, "DVD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
@@ -41,7 +42,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckNEContents(string file, NewExecutable nex, bool includeDebug)
|
||||
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
// Get the DOS stub from the executable, if possible
|
||||
var stub = nex?.DOSStubHeader;
|
||||
@@ -65,14 +66,14 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C,
|
||||
0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20
|
||||
}, GetVersion, "CD-Cops"),
|
||||
}, GetVersion, "CD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, data, neMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -80,6 +81,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
return null;
|
||||
|
||||
// Get the .grand section, if it exists -- TODO: Confirm is this is in DVD-Cops as well
|
||||
// Found in "AGENTHUG.QZ_" in Redump entry 84517
|
||||
bool grandSection = pex.ContainsSection(".grand", exact: true);
|
||||
if (grandSection)
|
||||
return "CD-Cops";
|
||||
@@ -93,11 +95,13 @@ namespace BurnOutSharp.ProtectionType
|
||||
// TODO: Original had "CDCOPS.DLL" required and all the rest in a combined OR
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found in Redump entry 84517
|
||||
new PathMatchSet(new PathMatch("CDCOPS.DLL", useEndsWith: true), "CD-Cops"),
|
||||
new PathMatchSet(new PathMatch(".GZ_", useEndsWith: true), "CD-Cops"),
|
||||
new PathMatchSet(new PathMatch(".W_X", useEndsWith: true), "CD-Cops"),
|
||||
new PathMatchSet(new PathMatch(".Qz", useEndsWith: true), "CD-Cops"),
|
||||
new PathMatchSet(new PathMatch(".QZ_", useEndsWith: true), "CD-Cops"),
|
||||
|
||||
new PathMatchSet(new PathMatch(".GZ_", useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch(".Qz", useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -108,11 +112,13 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found in Redump entry 84517
|
||||
new PathMatchSet(new PathMatch("CDCOPS.DLL", useEndsWith: true), "CD-Cops"),
|
||||
new PathMatchSet(new PathMatch(".GZ_", useEndsWith: true), "CD-Cops"),
|
||||
new PathMatchSet(new PathMatch(".W_X", useEndsWith: true), "CD-Cops"),
|
||||
new PathMatchSet(new PathMatch(".Qz", useEndsWith: true), "CD-Cops"),
|
||||
new PathMatchSet(new PathMatch(".QZ_", useEndsWith: true), "CD-Cops"),
|
||||
|
||||
new PathMatchSet(new PathMatch(".GZ_", useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch(".Qz", useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
using System;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class CDKey : IPEContentCheck
|
||||
public class CDKey : IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -14,7 +15,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
return null;
|
||||
|
||||
string name = pex.InternalName;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.Equals("CDKey", StringComparison.OrdinalIgnoreCase))
|
||||
if (name?.Equals("CDKey", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return "CD-Key / Serial";
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,14 +1,33 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class CDLock : IPEContentCheck, IPathCheck
|
||||
/// <summary>
|
||||
/// CD-Lock (https://www.cdmediaworld.com/hardware/cdrom/cd_protections_dummy_files.shtml) is a copy protection most commonly used in Europe and active from 1998-2001 that seems to have a resemblance to Bitpool in a few ways.
|
||||
/// It makes use of padded dummy files with an AFP extension, with there being 4 such files on a disc.
|
||||
/// These files typically have a filename consistening of seemingly random 4 characters with an AFP extension, though there are known exceptions.
|
||||
/// These exceptions have "afp" files with the names "Gang1.afp", "Gang2.afp", "Gang3.afp", and "Gang4.afp" (Redump entries 37788 and 43221).
|
||||
/// There also always seems to be a "CONFIG.AFP" file present, which in most cases contains a marker relating to the other AFP files present on the disc.
|
||||
/// At least one game breaks this mould, having a "CONFIG.AFP" file present but is filled with 0x20 bytes instead of the expected data (Redump entries 37788 and 43221).
|
||||
/// Games protected with CD-Lock also appear to consistently have 3 additional tracks relating to the protection appended. These are 2 audio tracks, followed by a data track.
|
||||
/// Unlike Bitpool, it seems that these additional tracks are appended whether or not there are intentional audio tracks present on the disc as well. Compare Redump entries 37788 and 66321.
|
||||
/// It appears that this latter data track points to the data of the first data track, giving the appearance to some software that the disc contains 2 equally sized data tracks.
|
||||
/// It seems to me that this is intended to confuse dumping software, possibly attempting to lead it to believe that the disc has a larger capacity than it physically could have.
|
||||
/// https://inxs8.tripod.com/illegal_toc.htm seems to confirm that the software of the time especially seems to have had issues with this, though none of the technical information on the page seems to be particularly correct.
|
||||
/// Based off of Redump entries 31615 and 37700, it seems that there are cases where the main data track on two separate discs is identical, but the protection tracks differ. The reason for this is unknown.
|
||||
/// There are a few discs where one of the protection audio tracks is quite large, sometimes even larger than the main data track. The reason for this is also unknown (Redump entries 43221 and 66749).
|
||||
/// https://www.softpedia.com/get/Security/Encrypting/CD-Lock.shtml seems to be an unrelated program that protects CDs via encryption.
|
||||
/// Possible false positives include Redump entries 51241, 51373, 54397, 76437.
|
||||
/// Confirmed to be present on Redump entries 24287, 31615, 34448, 35967, 36627, 37700, 37788, 43221, 55788, and 66749.
|
||||
/// </summary>
|
||||
public class CDLock : IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -20,6 +39,8 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Found in game executables protected with CD-Lock (Redump entries 24287 and 31615).
|
||||
// TODO: Check for possible false postives (Redump entry 97942).
|
||||
// 2 + (char)0xF2 + (char)0x02 + (char)0x82 + (char)0xC3 + (char)0xBC + (char)0x0B + $ + (char)0x99 + (char)0xAD + 'C + (char)0xE4 + (char)0x9D + st + (char)0x99 + (char)0xFA + 2$ + (char)0x9D + )4 + (char)0xFF + t
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
@@ -43,7 +64,12 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch(".AFP", useEndsWith: true), "CD-Lock"),
|
||||
// TODO: Determine if there's any consistency in the naming of the additional AFP files.
|
||||
|
||||
// Found in every confirmed sample of CD-Lock, generally (but not always) appears to include markers relating to the additional AFP files present (Redump entries 24287 and 31615).
|
||||
new PathMatchSet(new PathMatch("CONFIG.AFP", useEndsWith: true), "CD-Lock"),
|
||||
|
||||
// There is also a "$$$$$$$$.$$$" file present on some discs, but it isn't known if this is directly related to CD-Lock (Redump entries 37788 and 43221).
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -54,7 +80,12 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch(".AFP", useEndsWith: true), "CD-Lock"),
|
||||
// TODO: Determine if there's any consistency in the naming of the additional AFP files.
|
||||
|
||||
// Found in every confirmed sample of CD-Lock, generally (but not always) appears to include markers relating to the additional AFP files present (Redump entries 24287 and 31615).
|
||||
new PathMatchSet(new PathMatch("CONFIG.AFP", useEndsWith: true), "CD-Lock"),
|
||||
|
||||
// There is also a "$$$$$$$$.$$$" file present on some discs, but it isn't known if this is directly related to CD-Lock (Redump entries 37788 and 43221).
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
@@ -12,10 +13,10 @@ namespace BurnOutSharp.ProtectionType
|
||||
// TODO: Verify if these are OR or AND
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("_cdp16.dat", useEndsWith: true), "CD-Protector"),
|
||||
new PathMatchSet(new PathMatch("_cdp16.dll", useEndsWith: true), "CD-Protector"),
|
||||
new PathMatchSet(new PathMatch("_cdp32.dat", useEndsWith: true), "CD-Protector"),
|
||||
new PathMatchSet(new PathMatch("_cdp32.dll", useEndsWith: true), "CD-Protector"),
|
||||
new PathMatchSet(new PathMatch("_cdp16.dat", useEndsWith: true), "CD-Protector (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch("_cdp16.dll", useEndsWith: true), "CD-Protector (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch("_cdp32.dat", useEndsWith: true), "CD-Protector (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch("_cdp32.dll", useEndsWith: true), "CD-Protector (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -26,10 +27,10 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("_cdp16.dat", useEndsWith: true), "CD-Protector"),
|
||||
new PathMatchSet(new PathMatch("_cdp16.dll", useEndsWith: true), "CD-Protector"),
|
||||
new PathMatchSet(new PathMatch("_cdp32.dat", useEndsWith: true), "CD-Protector"),
|
||||
new PathMatchSet(new PathMatch("_cdp32.dll", useEndsWith: true), "CD-Protector"),
|
||||
new PathMatchSet(new PathMatch("_cdp16.dat", useEndsWith: true), "CD-Protector (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch("_cdp16.dll", useEndsWith: true), "CD-Protector (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch("_cdp32.dat", useEndsWith: true), "CD-Protector (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch("_cdp32.dll", useEndsWith: true), "CD-Protector (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class CDSHiELDSE : IPEContentCheck
|
||||
public class CDSHiELDSE : IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
@@ -12,9 +13,9 @@ namespace BurnOutSharp.ProtectionType
|
||||
// TODO: Verify if these are OR or AND
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("CHKCDX16.DLL", useEndsWith: true), "CD-X"),
|
||||
new PathMatchSet(new PathMatch("CHKCDX32.DLL", useEndsWith: true), "CD-X"),
|
||||
new PathMatchSet(new PathMatch("CHKCDXNT.DLL", useEndsWith: true), "CD-X"),
|
||||
new PathMatchSet(new PathMatch("CHKCDX16.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch("CHKCDX32.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch("CHKCDXNT.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -25,9 +26,9 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("CHKCDX16.DLL", useEndsWith: true), "CD-X"),
|
||||
new PathMatchSet(new PathMatch("CHKCDX32.DLL", useEndsWith: true), "CD-X"),
|
||||
new PathMatchSet(new PathMatch("CHKCDXNT.DLL", useEndsWith: true), "CD-X"),
|
||||
new PathMatchSet(new PathMatch("CHKCDX16.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch("CHKCDX32.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
|
||||
new PathMatchSet(new PathMatch("CHKCDXNT.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
@@ -4,16 +4,33 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class CactusDataShield : IContentCheck, IPEContentCheck, IPathCheck
|
||||
/// <summary>
|
||||
/// CactusDataShield was a copy protection originally developed by Midbar Technologies, which was then purchased by Macrovision in 2002 (https://variety.com/2002/digital/news/macrovision-acquires-midbar-cuts-ttr-link-1117875824/).
|
||||
/// CDS-100 appears to function by attempting to prevent dumping/ripping the discs protected with it.
|
||||
/// CDS-200+ uses a dedicated audio player to play the music "legitimately".
|
||||
/// Patent relating to CDS-100: https://patents.google.com/patent/US6425098B1/
|
||||
/// Known CDS versions:
|
||||
/// CDS-100 ("The Loveparade Compilation 2001" by various artists (Barcode 74321 86986 2) (Likely Discogs Release Code [r155963]) and "World Of Our Own" (Limited Edition) by Westlife (Barcode 7 43218 98572 0) (Discogs Release Code [r1357706])).
|
||||
/// CDS-200 (PlayJ) (("Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427])) (Confirmed to be CDS-200 from https://www.cdrinfo.com/d7/content/cactus-data-shield-200?page=2).
|
||||
/// CDS200.0.4 - 3.0 build 16a (Redump entry 95036)
|
||||
/// CDS200.0.4 - 3.0 build 16c ("TMF Hitzone 20" by various artists (Barcode 7 31458 37062 8)).
|
||||
/// CDS200.0.4 - 4.1 build 2a ("Ich Habe Einen Traum" by Uwe Busse (Barcode 9 002723 251203)).
|
||||
/// CDS200.0.4 - 4.1 build 2e ("Hallucinations" by David Usher (Barcode 7 24359 30322 2)).
|
||||
/// CDS-300
|
||||
/// Further information:
|
||||
/// https://www.cdrinfo.com/d7/content/cactus-data-shield-200
|
||||
/// https://www.cdmediaworld.com/hardware/cdrom/cd_protections_cactus_data_shield.shtml
|
||||
/// </summary>
|
||||
public class CactusDataShield : IContentCheck, IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug, PortableExecutable pex, NewExecutable nex)
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// TODO: Limit these checks to Mac binaries
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
@@ -36,7 +53,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -60,6 +77,23 @@ namespace BurnOutSharp.ProtectionType
|
||||
return match;
|
||||
}
|
||||
|
||||
// Get the .rsrc section, if it exists
|
||||
var rsrcSectionRaw = pex.ReadRawSection(".rsrc", first: false);
|
||||
if (rsrcSectionRaw != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// CactusPJ
|
||||
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]).
|
||||
// Modified version of the PlayJ Music Player specificaly for CDS, as indicated by the About page present when running the executable.
|
||||
new ContentMatchSet(new byte?[] { 0x43, 0x61, 0x63, 0x74, 0x75, 0x73, 0x50, 0x4A }, "PlayJ Music Player (Cactus Data Shield 200)"),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, rsrcSectionRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -69,10 +103,22 @@ namespace BurnOutSharp.ProtectionType
|
||||
// TODO: Verify if these are OR or AND
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("CACTUSPJ.exe", useEndsWith: true), GetVersion, "Cactus Data Shield"),
|
||||
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]).
|
||||
// Modified version of the PlayJ Music Player specificaly for CDS, as indicated by the About page present when running the executable.
|
||||
// The file "DATA16.BML" is also present on this disc but the name is too generic to check for.
|
||||
new PathMatchSet(new PathMatch("CACTUSPJ.exe", useEndsWith: true), "PlayJ Music Player (Cactus Data Shield 200)"),
|
||||
|
||||
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]).
|
||||
// In "Volumina! - Puur" (7 43218 63282 2), this file is composed of multiple PLJ files combined together.
|
||||
// In later versions, this file is a padded dummy file. ("Ich Habe Einen Traum" by Uwe Busse (Barcode 9 002723 251203)).
|
||||
new PathMatchSet(new PathMatch("YUCCA.CDS", useEndsWith: true), "Cactus Data Shield 200"),
|
||||
|
||||
// TODO: Find samples of the following:
|
||||
new PathMatchSet(new PathMatch("CDSPlayer.app", useEndsWith: true), GetVersion, "Cactus Data Shield"),
|
||||
new PathMatchSet(new PathMatch("PJSTREAM.DLL", useEndsWith: true), GetVersion, "Cactus Data Shield"),
|
||||
new PathMatchSet(new PathMatch("wmmp.exe", useEndsWith: true), GetVersion, "Cactus Data Shield"),
|
||||
|
||||
// Present on CDS-300, as well as SafeDisc. This is likely due to both protections being created by Macrovision.
|
||||
new PathMatchSet(new PathMatch("00000001.TMP", useEndsWith: true), Get00000001TMPVersion, "Cactus Data Shield 300 (Confirm presence of other CDS-300 files)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -83,15 +129,44 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("CACTUSPJ.exe", useEndsWith: true), "Cactus Data Shield 200"),
|
||||
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]).
|
||||
// Modified version of the PlayJ Music Player specificaly for CDS, as indicated by the About page present when running the executable.
|
||||
// The file "DATA16.BML" is also present on this disc but the name is too generic to check for.
|
||||
new PathMatchSet(new PathMatch("CACTUSPJ.exe", useEndsWith: true), "PlayJ Music Player (Cactus Data Shield 200)"),
|
||||
|
||||
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]),
|
||||
// In "Volumia! - Puur", this file is composed of multiple PLJ files combined together.
|
||||
// In later versions, this file is a padded dummy file. ("Ich Habe Einen Traum" by Uwe Busse (Barcode 9 002723 251203)).
|
||||
new PathMatchSet(new PathMatch("YUCCA.CDS", useEndsWith: true), "Cactus Data Shield 200"),
|
||||
|
||||
// TODO: Find samples of the following:
|
||||
new PathMatchSet(new PathMatch("CDSPlayer.app", useEndsWith: true), "Cactus Data Shield 200"),
|
||||
new PathMatchSet(new PathMatch("PJSTREAM.DLL", useEndsWith: true), "Cactus Data Shield 200"),
|
||||
new PathMatchSet(new PathMatch("wmmp.exe", useEndsWith: true), "Cactus Data Shield 200"),
|
||||
|
||||
// Present on CDS-300, as well as SafeDisc. This is likely due to both protections being created by Macrovision.
|
||||
new PathMatchSet(new PathMatch("00000001.TMP", useEndsWith: true), Get00000001TMPVersion, "Cactus Data Shield 300"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
}
|
||||
|
||||
public static string Get00000001TMPVersion(string firstMatchedString, IEnumerable<string> files)
|
||||
{
|
||||
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
|
||||
return string.Empty;
|
||||
|
||||
// This file is present on both CDS-300 and SafeDisc.
|
||||
// Only one specific file size appears to be associated with CDS-300, so any files with a differing file size are discarded. If it is the correct file size, return it as valid.
|
||||
FileInfo fi = new FileInfo(firstMatchedString);
|
||||
switch (fi.Length)
|
||||
{
|
||||
case 2_048:
|
||||
return "(Confirm presence of other CDS-300 files)";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetVersion(string firstMatchedString, IEnumerable<string> files)
|
||||
{
|
||||
// Find the version.txt file first
|
||||
|
||||
@@ -1,23 +1,70 @@
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class CengaProtectDVD : IPEContentCheck
|
||||
/// <summary>
|
||||
/// Cenega ProtectDVD is a protection seemingly created by the publisher Cenega for use with their games.
|
||||
/// Games using this protection aren't able to be run from an ISO file, and presumably use DMI as a protection feature.
|
||||
/// </summary>
|
||||
public class CengaProtectDVD : IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .cenega section, if it exists
|
||||
// Get the .cenega section, if it exists. Seems to be found in the protected game executable (Redump entry 31422).
|
||||
bool cenegaSection = pex.ContainsSection(".cenega", exact: true);
|
||||
if (cenegaSection)
|
||||
return "Cenega ProtectDVD";
|
||||
|
||||
// Get the .cenega0 through .cenega2 sections, if they exists. Found in cenega.dll (Redump entry 31422).
|
||||
cenegaSection = pex.ContainsSection(".cenega0", exact: true);
|
||||
if (cenegaSection)
|
||||
return "Cenega ProtectDVD";
|
||||
|
||||
cenegaSection = pex.ContainsSection(".cenega1", exact: true);
|
||||
if (cenegaSection)
|
||||
return "Cenega ProtectDVD";
|
||||
|
||||
cenegaSection = pex.ContainsSection(".cenega2", exact: true);
|
||||
if (cenegaSection)
|
||||
return "Cenega ProtectDVD";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Seems likely to be present in most, if not all discs protected with Cenega ProtectDVD, but unable to confirm due to only having a small sample size.
|
||||
// References the existence of a "ProtectDVD.dll", which has not yet been located (Redump entry 31422).
|
||||
new PathMatchSet(new PathMatch("cenega.dll", useEndsWith: true), "Cenega ProtectDVD"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckFilePath(string path)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Seems likely to be present in most, if not all discs protected with Cenega ProtectDVD, but unable to confirm due to only having a small sample size.
|
||||
// References the existence of a "ProtectDVD.dll", which has not yet been located (Redump entry 31422).
|
||||
new PathMatchSet(new PathMatch("cenega.dll", useEndsWith: true), "Cenega ProtectDVD"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
// CodeLock / CodeLok / CopyLok
|
||||
public class CodeLock : IContentCheck, IPEContentCheck
|
||||
public class CodeLock : IContentCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug, PortableExecutable pex, NewExecutable nex)
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
@@ -22,7 +22,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
0x43, 0x4F, 0x44, 0x45, 0x2D, 0x4C, 0x4F, 0x43,
|
||||
0x4B, 0x2E, 0x4F, 0x43, 0x58
|
||||
}, "CodeLock / CodeLok / CopyLok"),
|
||||
}, "CodeLock / CodeLok / CopyLok (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
@@ -32,14 +32,15 @@ namespace BurnOutSharp.ProtectionType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
|
||||
// If there are more than 2 icd-prefixed sections, then we have a match
|
||||
// Found in Redump entry 31557.
|
||||
int icdSectionCount = pex.GetSectionNames().Count(s => s.StartsWith("icd"));
|
||||
if (icdSectionCount >= 2)
|
||||
return "CodeLock / CodeLok / CopyLok";
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.NE;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
@@ -9,7 +8,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
public class CopyKiller : IContentCheck, IPathCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug, PortableExecutable pex, NewExecutable nex)
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
|
||||
@@ -3,5 +3,9 @@
|
||||
public class CrypKey
|
||||
{
|
||||
// TODO: Implement - http://www.crypkey.com/products/cdlock/cdmain.html
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
41
BurnOutSharp/ProtectionType/Cucko.cs
Normal file
41
BurnOutSharp/ProtectionType/Cucko.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
// TODO: Do more research into the Cucko protection:
|
||||
// - Reference to `EASTL` and `EAStdC` are standard for EA products and does not indicate Cucko by itself
|
||||
// - There's little information outside of PiD detection that actually knows about Cucko
|
||||
// - Cucko is confirmed to, at least, use DMI checks.
|
||||
public class Cucko : IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .text section, if it exists
|
||||
if (pex.TextSectionRaw == null)
|
||||
return null;
|
||||
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Confirmed to detect most examples known of Cucko. The only known exception is the version of "TSLHost.dll" included on Redump entry 36119.
|
||||
// ŠU‰8...…™...ŠUŠ8T...
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x8A, 0x55, 0x89, 0x38, 0x14, 0x1E, 0x0F, 0x85,
|
||||
0x99, 0x00, 0x00, 0x00, 0x8A, 0x55, 0x8A, 0x38,
|
||||
0x54, 0x1E, 0x01, 0x0F
|
||||
}, "Cucko (EA Custom)")
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, pex.TextSectionRaw, matchers, includeDebug);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
@@ -11,7 +12,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("DvdCrypt.pdb", useEndsWith: true), "DVD Crypt"),
|
||||
new PathMatchSet(new PathMatch("DvdCrypt.pdb", useEndsWith: true), "DVD Crypt (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -22,7 +23,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("DvdCrypt.pdb", useEndsWith: true), "DVD Crypt"),
|
||||
new PathMatchSet(new PathMatch("DvdCrypt.pdb", useEndsWith: true), "DVD Crypt (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BurnOutSharp.Interfaces;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
@@ -22,7 +23,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
FileInfo ifofile = new FileInfo(Path.Combine(bupfile.DirectoryName, bupfile.Name.Substring(0, bupfile.Name.Length - bupfile.Extension.Length) + ".ifo"));
|
||||
if (bupfile.Length != ifofile.Length)
|
||||
{
|
||||
protections.Enqueue("DVD-Movie-PROTECT");
|
||||
protections.Enqueue("DVD-Movie-PROTECT (Unconfirmed - Please report to us on Github)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
218
BurnOutSharp/ProtectionType/Denuvo.cs
Normal file
218
BurnOutSharp/ProtectionType/Denuvo.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
// 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
|
||||
public class Denuvo : IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Denuvo Protector
|
||||
if (pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus && pex.EntryPointRaw != null)
|
||||
{
|
||||
byte?[] denuvoProtector = new byte?[]
|
||||
{
|
||||
0x48, 0x8D, 0x0D, null, null, null, null, null,
|
||||
null, null, null, 0xE9, null, null, null, null,
|
||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
if (pex.EntryPointRaw.StartsWith(denuvoProtector))
|
||||
return "Denuvo Protector";
|
||||
}
|
||||
|
||||
// Denuvo
|
||||
var timingMatchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Denuvo Timing
|
||||
new ContentMatchSet(
|
||||
new byte?[]
|
||||
{
|
||||
0x44, 0x65, 0x6E, 0x75, 0x76, 0x6F, 0x20, 0x54,
|
||||
0x69, 0x6D, 0x69, 0x6E, 0x67,
|
||||
}, "Denuvo")
|
||||
};
|
||||
|
||||
if (pex.ContainsSection(".arch") || pex.ContainsSection(".srdata") || !string.IsNullOrWhiteSpace(MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, timingMatchers, includeDebug)))
|
||||
{
|
||||
if (pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Mad Max, Metal Gear Solid: TPP, Rise of the Tomb Raider
|
||||
new ContentMatchSet(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0x4C, 0x8D,
|
||||
null, null, null, null, null, 0x4C, 0x8D, null,
|
||||
null, null, null, null, 0x4D, 0x29, 0xC1,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v1.0 (x64)"),
|
||||
|
||||
// Lords of the Fallen, Batman: AK, Just Cause 3, Sherlock Holmes: TdD, Tales of Berseria etc
|
||||
new ContentMatchSet(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x48, 0x8D, 0x0D, null, null, null, null, 0xE9,
|
||||
null, null, null, null,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v2.0a (x64)"),
|
||||
|
||||
// Yesterday Origins
|
||||
new ContentMatchSet(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x48, 0x89, null, null, null, null, null, 0x48,
|
||||
0x89, null, null, null, null, null, 0x4C, 0x89,
|
||||
null, null, null, null, null, 0x4C, 0x89, null,
|
||||
null, null, null, null, 0x48, 0x83, 0xFA, 0x01,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v2.0b (x64)"),
|
||||
|
||||
// Sniper Ghost Warrior 3 (beta), Dead Rising 4 (SteamStub-free)
|
||||
new ContentMatchSet(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
null, null, null, null, null, null, null, null,
|
||||
0x4C, 0x89, 0x1C, 0x24, 0x49, 0x89, 0xE3,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v3.0a (x64)"),
|
||||
|
||||
// Train Sim World CSX Heavy Haul
|
||||
new ContentMatchSet(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x4D, 0x8D, null, null, null, null, null, null,
|
||||
null, null, null, 0x48, 0x89, null, null, null,
|
||||
null, null, 0x48, 0x8D, null, null, 0x48, 0x89,
|
||||
null, 0x48, 0x89, null, 0x48, 0x89,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v3.0b (x64)"),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
|
||||
return "Denuvo (Unknown x64 Version)";
|
||||
|
||||
//// Check if steam_api64.dll present
|
||||
//if (PE.isLibraryPresent("steam_api64.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x64 -> Steam";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
//// Check if uplay_r1_loader64.dll present
|
||||
//if (PE.isLibraryPresent("uplay_r1_loader64.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x64 -> uPlay";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
//// Check if uplay_r2_loader64.dll present
|
||||
//if (PE.isLibraryPresent("uplay_r2_loader64.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x64 -> uPlay";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
//// Check if Core/Activation64.dll present
|
||||
//if (PE.isLibraryPresent("Core/Activation64.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x64 -> Origin";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Pro Evolution Soccer 2017, Champions of Anteria
|
||||
new ContentMatchSet(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x55, 0x89, 0xE5, 0x8D, null, null, null, null,
|
||||
null, null, 0xE8, null, null, null, null, 0xE8,
|
||||
null, null, null, null, 0xE8, null, null, null,
|
||||
null, 0xE8, null, null, null, null,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v1.0 (x86)"),
|
||||
|
||||
// Romance of 13 Kingdoms, 2Dark
|
||||
new ContentMatchSet(
|
||||
new ContentMatch(
|
||||
new byte?[]
|
||||
{
|
||||
0x8D, null, null, null, null, null, null, 0x89,
|
||||
0x7C, 0x24, 0x04, 0x89, 0xE7,
|
||||
},
|
||||
end: 0
|
||||
),
|
||||
"Denuvo v2.0 (x86)"),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
|
||||
//// Check if steam_api64.dll present
|
||||
//if (PE.isLibraryPresent("steam_api.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x86 -> Steam";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
//// Check if uplay_r1_loader.dll present
|
||||
//if (PE.isLibraryPresent("uplay_r1_loader.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x86 -> uPlay";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
//// Check if Core/Activation.dll present
|
||||
//if (PE.isLibraryPresent("Core/Activation.dll"))
|
||||
//{
|
||||
// // Override additional info
|
||||
// sOptions = "x86 -> Origin";
|
||||
// bDetected = 1;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
68
BurnOutSharp/ProtectionType/DinamicMultimedia.cs
Normal file
68
BurnOutSharp/ProtectionType/DinamicMultimedia.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class DinamicMultimedia : IPathCheck
|
||||
{
|
||||
// Dinamic Multimedia Protection is the name used here to describe the protections created and used by Dinamic Multimedia for some of their media releases.
|
||||
// LockBlocks falls under this category, being created by and seemingly exclusively in Dinamic Multimedia products, but in every place I find it described online, it is said to very specifically have two rings on the data side of the disc.
|
||||
// Due to there being seemingly no absolute defining feature to LockBlocks other than this, any protected disc from Dinamic Multimedia that doesn't specifically have two rings is considered to have "Dinamic Multimedia Protection".
|
||||
// That being said, it may be entirely possible that LockBlocks is the name for all these protections as a whole, as some sources seem to consider games that don't seem to have two rings to have LockBlocks.
|
||||
|
||||
// Resources:
|
||||
// https://www.cdmediaworld.com/hardware/cdrom/cd_protections_lockblocks.shtml
|
||||
// https://www.cdrinfo.com/d7/content/cd-protection-overview?page=6
|
||||
// https://www.gamecopyworld.com/games/pc_pc_real_madrid_2000.shtml
|
||||
// https://www.gamecopyworld.com/games/pc_combat_mission_shock_force.shtml
|
||||
// https://www.gamecopyworld.com/games/pc_pc_atletismo.shtml
|
||||
// https://www.gamecopyworld.com/games/pc_pc_calcio_2000.shtml
|
||||
// https://www.gamecopyworld.com/games/pc_pc_futbol_2000.shtml
|
||||
|
||||
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Many more checks are likely possible based on the sources, but only ones that have been personally verified are getting added.
|
||||
|
||||
// Uncopyable files found in at least http://redump.org/disc/70531/, and likely in multiple others.
|
||||
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "COMPPLAY._01").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "LANDER.DA0").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "XSMGOP.DAP").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "XSMGOP.VBX").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
|
||||
// Copyable file found in http://redump.org/disc/70531/ that seems to be exclusively associated with the protection and other files that are part of the protection.
|
||||
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "COMPSCO._01").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckFilePath(string path)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Many more checks are likely possible based on the sources, but only ones that have been personally verified are getting added.
|
||||
|
||||
// Uncopyable files found in at least http://redump.org/disc/70531/, and likely in multiple others.
|
||||
new PathMatchSet(new PathMatch("2kscore.sc0", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch("arrcalc.obj", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch("bdrvisa.drv", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch("gprinter.dll", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch("hstadium.ipx", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch("omanager.odl", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch("opublic.001", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch("spland.sc0", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
new PathMatchSet(new PathMatch("uqprime.ipx", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
BurnOutSharp/ProtectionType/DiscAudit.cs
Normal file
12
BurnOutSharp/ProtectionType/DiscAudit.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class DiscAudit
|
||||
{
|
||||
// TODO: Implement - https://web.archive.org/web/19981206095259/http://www.ttrtech.com/discaudi.htm
|
||||
// References and further information:
|
||||
// https://www.sec.gov/Archives/edgar/data/933955/0000950117-97-001817.txt
|
||||
// https://books.google.com/books?id=3gkEAAAAMBAJ&pg=PA39
|
||||
// http://www.jei.org/Restricted/BR98/346x/346.html
|
||||
// https://archive.org/stream/TheJerusalemPost1998IsraelEnglish/Jul%2003%201998%2C%20The%20Jerusalem%20Post%2C%20%2319970%2C%20Israel%20%28en%29_djvu.txt
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,168 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class DiscGuard : IPathCheck
|
||||
/// <summary>
|
||||
/// DiscGuard was a copy protection created by TTR (https://web.archive.org/web/19981212021829/http://ttrtech.com/) for protecting software.
|
||||
/// They also created a similar copy protection for audio CDs called DiscAudit (https://web.archive.org/web/19981206095259/http://www.ttrtech.com/discaudi.htm).
|
||||
/// It seems to work by encrypting the main game executable, and by having a "signature" that is supposedly only present on a genuine disc (https://www.cdmediaworld.com/hardware/cdrom/cd_protections_discguard.shtml).
|
||||
/// Due to the fact that these games can seemingly be burned to CD-R under the right conditions using CloneCD, it likely isn't using twin sectors or DPM (https://www.gameburnworld.com/protections_discguard.shtml).
|
||||
/// It seems likely to be using subchannels as the basis for this signature, as no errored sectors are used.
|
||||
/// DiscGuard is seemingly able to be detect so-called "active debuggers", based on text found in "Alternate.exe" (Redump entry 31914) and "Alt.exe" (Redump entries 46743, 46961, 79284, and 79374).
|
||||
/// There's a reference to a file "Dg.vbn" being present in "Alternate.exe" (Redump entry 31914) and "Alt.exe" (Redump entries 46743, 46961, 79284, and 79374), but no copy has been found in any sample so far.
|
||||
/// There seem to be two distinct versions of DiscGuard, with one only being present on one known game (Redump entry 31914).
|
||||
/// "Alternate.exe" in the outlying version is "Alt.exe" in the rest.
|
||||
/// "TTR1.DLL" and "TTR2.DLL" in the outlying version appear to be "T111.DLL" and "T222.DLL" in the rest, respectively.
|
||||
/// "IOSLink.sys" and "IOSLink.vxd" seem to be the same throughout all versions, even down to the reported File Version in "IOSLink.sys".
|
||||
/// There are other various DLLs, but their names seem to be different on every disc. Their filenames all seem to start with the letter "T", and it seems to be one of these specifically that the protected executable imports.
|
||||
/// These outlying DLLs are:
|
||||
/// "T29.dll" (Redump entry 31914).
|
||||
/// "T5375.dll" (Redump entry 79284).
|
||||
/// "TD352.dll" and "TE091.dll" (Redump entry 46743).
|
||||
/// "T71E1.dll" and "T7181.dll" (Redump entry 46961).
|
||||
/// "TA0E4.DLL" (Redump entry 79374).
|
||||
/// </summary>
|
||||
public class DiscGuard : IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
// TODO: Add checks for the game executables, which seem likely to contain some kind of indicators that can be checked for. The game executables all seem to import "Ord(1)" from one of the varying DLLs present.
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Found in "IOSLinksys.dll" (Redump entries 31914, 46743, 46961, 79284, and 79374).
|
||||
string name = pex.FileDescription;
|
||||
if (name?.StartsWith("IOSLinkNT", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"DiscGuard";
|
||||
|
||||
// Found in "T29.dll" (Redump entry 31914).
|
||||
name = pex.ProductName;
|
||||
if (name?.StartsWith("DiscGuard (tm)", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"DiscGuard";
|
||||
|
||||
// Found in "IOSLinksys.dll" (Redump entries 31914, 46743, 46961, 79284, and 79374).
|
||||
name = pex.ProductName;
|
||||
if (name?.StartsWith("TTR Technologies Ltd. DiscGuard (tm)", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"DiscGuard";
|
||||
|
||||
// Get the .vbn section, if it exists
|
||||
var DiscGuardSection = pex.ReadRawSection(".vbn");
|
||||
if (DiscGuardSection != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Found in "T29.dll" (Redump entry 31914).
|
||||
// This check should be as long as the following check, as this data is nearly identical (including length) in the original files, but for some reason the section ends early, causing part of the remaining data to not be part of a section.
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x7B, 0x39, 0x8F, 0x07, 0x47, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
|
||||
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
|
||||
0xBE, 0xB3, 0xDB, 0xE9, 0x4E, 0x87, 0x8D, 0x46, 0x63, 0x0A, 0x54, 0xB8,
|
||||
0x4F, 0x85, 0x60, 0x2C, 0x06, 0xEC, 0xBD, 0x75, 0xF5, 0x6A, 0x6E, 0x35,
|
||||
0x4D, 0x5A, 0x8B, 0xF4, 0x12, 0x15, 0x23, 0xC8, 0xE9, 0x80, 0x01, 0x10,
|
||||
0xFE, 0xDB, 0xC6, 0x70, 0x1D, 0xC1, 0x4D, 0xAE, 0x9E, 0xE1, 0x01, 0xAA,
|
||||
0x9E, 0x50, 0x50, 0xC5, 0x66, 0x80, 0xC0, 0xA2, 0x2F, 0xA9, 0x7A, 0x3B,
|
||||
0x48, 0x74, 0x9D, 0x17, 0x33, 0x5D, 0x4C, 0x84, 0xD9, 0x54, 0xC4, 0x08,
|
||||
0xCC, 0x10, 0x2A, 0xF6, 0x91, 0x40, 0x51, 0xD3, 0xF5, 0x9A, 0x07, 0xE7,
|
||||
0xAB, 0xE9, 0x0B, 0xAD, 0xD4, 0x3A, 0xEC, 0xBA, 0x4B, 0x6C, 0xD2, 0x82,
|
||||
0x0D, 0xF5, 0x49, 0x83, 0x8E, 0xAB, 0x85, 0x92, 0x78, 0x1D, 0x69, 0x1E,
|
||||
0x44, 0xC6, 0xF6, 0xB4, 0x5F, 0x5F, 0xC2, 0x48, 0x5A, 0xED, 0x43, 0xD3,
|
||||
0xA4, 0x41, 0x81
|
||||
}, "DiscGuard"),
|
||||
|
||||
// Found in "T5375.dll" (Redump entry 79284), "TD352.dll" and "TE091.dll" (Redump entry 46743), "T71E1.dll" and "T7181.dll" (Redump entry 46961), and "TA0E4.DLL" (Redump entry 79374).
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x7B, 0x39, 0x8F, 0x07, 0x45, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
|
||||
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
|
||||
0xBE, 0xB3, 0xDB, 0xE9, 0x4E, 0x87, 0x8D, 0x46, 0x63, 0x0A, 0x54, 0xB8,
|
||||
0x4F, 0x85, 0x60, 0x2C, 0x06, 0xEC, 0xBD, 0x75, 0xC6, 0xEB, 0x6E, 0x35,
|
||||
0xED, 0xD0, 0x8B, 0xF4, 0x15, 0x12, 0x3D, 0xF3, 0x65, 0xF7, 0x01, 0x10,
|
||||
0xF8, 0xFA, 0xC6, 0x70, 0x1D, 0xC1, 0x4D, 0xAE, 0x9E, 0xE1, 0x01, 0xAA,
|
||||
0x9E, 0x50, 0x50, 0xC5, 0x66, 0x80, 0xC0, 0xA2, 0x2F, 0xA9, 0x7A, 0x3B,
|
||||
0x48, 0x74, 0x9D, 0x17, 0x33, 0x5D, 0x4C, 0x84, 0xD9, 0x54, 0xC4, 0x08,
|
||||
0xCC, 0x10, 0x2A, 0xF6, 0x91, 0x40, 0x51, 0xD3, 0x41, 0x9A, 0x07, 0xE7,
|
||||
0xAB, 0xE9, 0x0B, 0xAD, 0xD4, 0x3A, 0xEC, 0xBA, 0xAF, 0x69, 0xD2, 0x82,
|
||||
0x67, 0xF5, 0x49, 0x83, 0x8E, 0xAB, 0x85, 0x92, 0x04, 0x19, 0x69, 0x1E,
|
||||
0x44, 0xC6, 0xF6, 0xB4, 0x5F, 0x5F, 0xC2, 0x48, 0x5A, 0xED, 0x43, 0xD3,
|
||||
0xA4, 0x41, 0x81, 0xAF, 0xB8, 0xCB, 0x46, 0xE3, 0xDA, 0x05, 0x36, 0xEA,
|
||||
0x05, 0xF5, 0xB9, 0xCE, 0x5F, 0x9A, 0xF5, 0x7D, 0x9E, 0x64, 0x66, 0xF9,
|
||||
0xA5, 0x7C, 0x4D, 0x1D, 0x1D, 0x95, 0x02, 0x52, 0x66, 0x23, 0xEF, 0xFF,
|
||||
0xEC, 0x63, 0x11, 0xEB, 0xF6, 0x66, 0x8F, 0x2B, 0xCF, 0x07, 0x50, 0x18,
|
||||
0xBE, 0x58, 0xCA, 0x08, 0x24, 0xAD, 0x81, 0x1A, 0xAB, 0x0E, 0x2D, 0x16,
|
||||
0x38, 0xAB, 0x22, 0xB5, 0xA8, 0xF0, 0x7D, 0x2E, 0xAF, 0x5E, 0xEA, 0x02,
|
||||
0x72, 0x20, 0x14, 0x19, 0x0E, 0x31, 0xF3, 0xD0, 0x40, 0xAE, 0xA2, 0xD5,
|
||||
0x0A, 0xA7, 0xB7, 0xAE, 0x02, 0xCF, 0xAC, 0x5F, 0xB8, 0x03, 0x15, 0x80,
|
||||
0x9A, 0x58, 0x5C, 0x03, 0x28, 0x31, 0x9E, 0xB8, 0x21, 0x5D, 0x07, 0xB3,
|
||||
0xB9, 0xEC, 0x75, 0xBA, 0xC2, 0xC8, 0x9D, 0x6F, 0x7A, 0xA1, 0x00, 0x8A
|
||||
}, "DiscGuard"),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, DiscGuardSection, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
|
||||
// Get the .rsrc section, if it exists
|
||||
var rsrcSection = pex.ReadRawSection(".rsrc");
|
||||
if (rsrcSection != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Found in "Alternate.exe" (Redump entry 31914) and "Alt.exe" (Redump entries 46743, 46961, 79284, and 79374).
|
||||
// T.h.e. .f.i.l.e. .I.o.s.L.i.n.k...V.x.D. .w.a.s. .n.o.t. .f.o.u.n.d.
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x66, 0x00, 0x69, 0x00,
|
||||
0x6C, 0x00, 0x65, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6F, 0x00, 0x73, 0x00,
|
||||
0x4C, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x6B, 0x00, 0x2E, 0x00, 0x56, 0x00,
|
||||
0x78, 0x00, 0x44, 0x00, 0x20, 0x00, 0x77, 0x00, 0x61, 0x00, 0x73, 0x00,
|
||||
0x20, 0x00, 0x6E, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x20, 0x00, 0x66, 0x00,
|
||||
0x6F, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x64, 0x00
|
||||
}, "DiscGuard"),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, rsrcSection, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found together in seemingly every DiscGuard game (Redump entries 31914, 46743, 46961, 79284, and 79374).
|
||||
new PathMatchSet(new List<PathMatch>
|
||||
{
|
||||
new PathMatch("IOSLINK.VXD", useEndsWith: true),
|
||||
new PathMatch("IOSLINK.DLL", useEndsWith: true),
|
||||
new PathMatch("IOSLINK.SYS", useEndsWith: true),
|
||||
}, "DiscGuard"),
|
||||
|
||||
// Found together in one DiscGuard game (Redump entry 31914).
|
||||
new PathMatchSet(new List<PathMatch>
|
||||
{
|
||||
new PathMatch("TTR1.DLL", useEndsWith: true),
|
||||
new PathMatch("TTR2.DLL", useEndsWith: true),
|
||||
}, "DiscGuard"),
|
||||
|
||||
// Found together in most DiscGuard games (Redump entries 46743, 46961, 79284, and 79374).
|
||||
new PathMatchSet(new List<PathMatch>
|
||||
{
|
||||
new PathMatch("T111.DLL", useEndsWith: true),
|
||||
new PathMatch("T222.DLL", useEndsWith: true),
|
||||
}, "DiscGuard"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: false);
|
||||
@@ -27,9 +173,12 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found together in seemingly every DiscGuard game (Redump entries 31914, 46743, 46961, 79284, and 79374).
|
||||
new PathMatchSet(new PathMatch("IOSLINK.VXD", useEndsWith: true), "DiscGuard"),
|
||||
new PathMatchSet(new PathMatch("IOSLINK.DLL", useEndsWith: true), "DiscGuard"),
|
||||
new PathMatchSet(new PathMatch("IOSLINK.SYS", useEndsWith: true), "DiscGuard"),
|
||||
|
||||
// IOSLINK.DLL doesn't seem to be present in any known samples, but a check for it was in the original BurnOut.
|
||||
new PathMatchSet(new PathMatch("IOSLINK.DLL", useEndsWith: true), "DiscGuard (Unconfirmed check, report this to us on GitHub))"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
18
BurnOutSharp/ProtectionType/Doc.loc.cs
Normal file
18
BurnOutSharp/ProtectionType/Doc.loc.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
public class DocLoc
|
||||
{
|
||||
// TODO: Implement - https://web.archive.org/web/20060107074801/http://www.docdata.com/
|
||||
// Doc.Loc appears to be a form of audio CD copy protection, used/created by the company DocData. It seems to work by preventing the tracks being read in PC optical drives using a non-standard second session.
|
||||
// List of known information and resources:
|
||||
// https://www.co-bw.com/DMS_how_to_rip_copy_protected_cds.htm
|
||||
// http://forum.redump.org/topic/40001/interesting-list-of-cd-audio-copy-protections/
|
||||
// https://hydrogenaud.io/index.php/topic,7198.75.html
|
||||
// http://cdr.xenoclast.org/issues/cd/bad/
|
||||
// https://myce.wiki/other/Plextor-PX-W4012S-SCSI-32/10/
|
||||
// https://www.discogs.com/release/790336-Various-Yorin-FM-Hitzone-21
|
||||
// https://www.discogs.com/release/188439-Helium-Vola-Helium-Vola
|
||||
// https://web.archive.org/web/20210420093858/https://club.myce.com/t/wolfsheim-casting-shadows-new-doc-loc-version/60377
|
||||
// https://forums.afterdawn.com/threads/emi-copy-control.266790/
|
||||
}
|
||||
}
|
||||
158
BurnOutSharp/ProtectionType/EasyAntiCheat.cs
Normal file
158
BurnOutSharp/ProtectionType/EasyAntiCheat.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
/// <summary>
|
||||
/// Easy Anti-Cheat is a form of DRM created by Kamu in 2006 (and later acquired by Epic Games in 2018) that prevents cheating in multiplayer games.
|
||||
/// The current official website is https://easy.ac, which began to be used by Easy Anti-Cheat by 2014.
|
||||
/// Care should be taken when viewing older versions of this URL, as before 2009 this domain had been used to promote a brand of condoms created by the RFSU, a Swedish sexual education non-profit organization.
|
||||
/// The first archive of this URL that was used by Easy Anti-Cheat appears to be https://web.archive.org/web/20140324145706/https://www.easy.ac/.
|
||||
/// The first URL used for Easy Anti-Cheat appears to be http://easyanticheat.net/, with seemingly the oldest archive being this: https://web.archive.org/web/20071024001450/http://easyanticheat.net/en/.
|
||||
/// There's a version of Easy Anti-Cheat that's bundled into the Epic Online Services, which is known as the EOS version of Easy Anti-Cheat (https://www.pcgamingwiki.com/wiki/Easy_Anti-Cheat).
|
||||
/// Further information and resources:
|
||||
/// List of games protected by Easy Anti-Cheat: https://www.pcgamingwiki.com/wiki/Easy_Anti-Cheat and https://www.easy.ac/en-us/partners/
|
||||
/// https://dev.epicgames.com/docs/services/en-US/GameServices/AntiCheat/index.html
|
||||
/// https://www.unknowncheats.me/wiki/Easy_Anti_Cheat
|
||||
/// </summary>
|
||||
public class EasyAntiCheat : IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
// TODO: Add support for detecting older versions, especially versions made before Easy Anti-Cheat was purchased by Epic Games.
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
string name = pex.FileDescription;
|
||||
// Found in "VideoHorrorSociety.exe" ("Video Horror Society", Patch 1.0.70309, Steam).
|
||||
if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat Bootstrapper (EOS)"))
|
||||
return "Easy Anti-Cheat (EOS Version)";
|
||||
|
||||
// Found in "EasyAntiCheat_EOS_Setup.exe" ("Video Horror Society", Patch 1.0.70309, Steam) and "EasyAntiCheat_EOS.exe", which is found installed in "Program Files (x86)\EasyAntiCheat_EOS".
|
||||
else if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat Service (EOS)"))
|
||||
return "Easy Anti-Cheat (EOS Version)";
|
||||
|
||||
// These two generic checks are both general enough to detect the majority of files known to contain Easy Anti-Cheat, as well as specific enough to avoid false positives.
|
||||
else if (!string.IsNullOrEmpty(name) && name.Contains("EasyAntiCheat"))
|
||||
return "Easy Anti-Cheat";
|
||||
else if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat"))
|
||||
return "Easy Anti-Cheat";
|
||||
|
||||
// For documentation, known exact File Descriptions and their associated files are listed below:
|
||||
// "Easy Anti-Cheat Bootstrapper (EOS)" -> "VideoHorrorSociety.exe" ("Video Horror Society", Patch 1.0.70309, Steam).
|
||||
// "Easy Anti-Cheat Service (EOS)" -> "EasyAntiCheat_EOS_Setup.exe" ("Video Horror Society", Patch 1.0.70309, Steam) and "EasyAntiCheat_EOS.exe", which is found installed in "Program Files (x86)\EasyAntiCheat_EOS".
|
||||
// "EasyAntiCheat.Client" -> "EasyAntiCheat.Client.dll" from "Intruder" (Update 2287, Steam).
|
||||
// "EasyAntiCheat.Server" -> "EasyAntiCheat.Server.dll" from "Intruder" (Update 2287, Steam).
|
||||
// "EasyAntiCheat Client" -> "EasyAntiCheat.dll", "EasyAntiCheat_x64.dll", and "EasyAntiCheat_x86.dll" from "Intruder" (Update 2287, Steam) and "Rec Room" (Version 20220803, Oculus).
|
||||
// "EasyAntiCheat Driver" -> "EasyAntiCheat.sys", which is found installed in "Program Files (x86)\EasyAntiCheat".
|
||||
// "EasyAntiCheat Launcher" -> "IntruderLauncher.exe" ("Intruder", Update 2287, Steam) and "Recroom_Oculus.exe" ("Rec Room", Version 20220803, Oculus). The Original Filename for this file is "eac_launcher.exe".
|
||||
// "EasyAntiCheat Server" -> "eac_server.dll" from "Intruder" (Update 2287, Steam).
|
||||
// "EasyAntiCheat Service" -> "EasyAntiCheat.exe", which is found installed in "Program Files (x86)\EasyAntiCheat" and "EasyAntiCheat_Setup.exe" ("Intruder", Update 2287, Steam).
|
||||
|
||||
name = pex.ProductName;
|
||||
// Found in multiple files, including "VideoHorrorSociety.exe" ("Video Horror Society", Patch 1.0.70309, Steam) and "start_protected_game.exe" ("VRChat", Version 2022.2.2p2, Oculus).
|
||||
if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat Bootstrapper (EOS)"))
|
||||
return "Easy Anti-Cheat (EOS Version)";
|
||||
|
||||
// Found in multiple files, including "EasyAntiCheat_EOS_Setup.exe" ("Video Horror Society", Patch 1.0.70309, Steam; "VRChat", Version 2022.2.2p2, Oculus) and "EasyAntiCheat.exe", which is found installed in "Program Files (x86)\EasyAntiCheat_EOS".
|
||||
else if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat Service (EOS)"))
|
||||
return "Easy Anti-Cheat (EOS Version)";
|
||||
|
||||
// These two generic checks are both general enough to detect the majority of files known to contain Easy Anti-Cheat, as well as specific enough to avoid false positives.
|
||||
else if (!string.IsNullOrEmpty(name) && name.Contains("EasyAntiCheat"))
|
||||
return "Easy Anti-Cheat";
|
||||
else if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat"))
|
||||
return "Easy Anti-Cheat";
|
||||
|
||||
// For documentation, known exact Product Names and their associated files are listed below:
|
||||
// "Easy Anti-Cheat Bootstrapper (EOS)" -> "VideoHorrorSociety.exe" ("Video Horror Society", Patch 1.0.70309, Steam) and "start_protected_game.exe" ("VRChat", Version 2022.2.2p2, Oculus).
|
||||
// "Easy Anti-Cheat Service (EOS)" -> "EasyAntiCheat_EOS_Setup.exe" ("Video Horror Society", Patch 1.0.70309, Steam; "VRChat", Version 2022.2.2p2, Oculus) and "EasyAntiCheat.exe", which is found installed in "Program Files (x86)\EasyAntiCheat_EOS".
|
||||
// "EasyAntiCheat" -> "EasyAntiCheat.exe" and "EasyAntiCheat.sys", which are both found installed in "Program Files (x86)\EasyAntiCheat"; "eac_server.dll" and "EasyAntiCheat.dll", which are both found in Intruder (Version 2287, Steam); and others.
|
||||
// "EasyAntiCheat Launcher" -> "IntruderLauncher.exe" ("Intruder", Update 2287, Steam) and "Recroom_Oculus.exe" ("Rec Room", Version 20220803, Oculus). The Original Filename for this file, according to file properties, is "eac_launcher.exe".
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
|
||||
{
|
||||
// TODO: Search for the presence of the folder "EasyAntiCheat" specifically, which is present in every checked version so far.
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found installed in "Program Files (x86)\EasyAntiCheat".
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat.exe", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat.sys", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
|
||||
// Found installed in "Program Files (x86)\EasyAntiCheat_EOS".
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS.exe", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS.sys", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
|
||||
|
||||
// Found in "Intruder" (Version 2287, Steam).
|
||||
new PathMatchSet(new PathMatch("eac_server.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("easyanticheat", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("easyanticheat.icns", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat.Client.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat.Server.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
// Found in "Intruder" (Version 2287, Steam) and "Rec Room" (Version 20220803, Oculus).
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_Setup.exe", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_x64.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_x86.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
|
||||
// Found in "Video Horror Society" (Patch 1.0.70309, Steam).
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS_Setup.exe", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
|
||||
new PathMatchSet(new PathMatch("InstallAntiCheat.bat", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("UninstallAntiCheat.bat", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
|
||||
// Found in "VRChat" (Version 2022.2.2p2, Oculus).
|
||||
new PathMatchSet(new PathMatch("start_protected_game.exe", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckFilePath(string path)
|
||||
{
|
||||
// TODO: Search for the presence of the folder "EasyAntiCheat" specifically, which is present in every checked version so far.
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found installed in "Program Files (x86)\EasyAntiCheat".
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat.exe", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat.sys", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
|
||||
// Found installed in "Program Files (x86)\EasyAntiCheat_EOS".
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS.exe", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS.sys", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
|
||||
|
||||
// Found in "Intruder" (Version 2287, Steam).
|
||||
new PathMatchSet(new PathMatch("eac_server.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("easyanticheat", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("easyanticheat.icns", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat.Client.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat.Server.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
// Found in "Intruder" (Version 2287, Steam) and "Rec Room" (Version 20220803, Oculus).
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_Setup.exe", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_x64.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_x86.dll", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
|
||||
// Found in "Video Horror Society" (Patch 1.0.70309, Steam).
|
||||
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS_Setup.exe", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
|
||||
new PathMatchSet(new PathMatch("InstallAntiCheat.bat", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
new PathMatchSet(new PathMatch("UninstallAntiCheat.bat", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
|
||||
// Found in "VRChat" (Version 2022.2.2p2, Oculus).
|
||||
new PathMatchSet(new PathMatch("start_protected_game.exe", useEndsWith: true), "Easy Anti-Cheat"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
// TODO: Do more research into the Cucko protection:
|
||||
// - Reference to `EASTL` and `EAStdC` are standard for EA products and does not indicate Cucko by itself
|
||||
// - There's little information outside of PiD detection that actually knows about Cucko
|
||||
// - Look into `ccinstall`, `Services/EACOM`, `TSLHost`, `SIGS/UploadThread/exchangeAuthToken`,
|
||||
// `blazeURL`, `psapi.dll`, `DasmX86Dll.dll`, `NVCPL.dll`, `iphlpapi.dll`, `dbghelp.dll`,
|
||||
// `WS2_32.dll`,
|
||||
public class ElectronicArts : IPEContentCheck
|
||||
public class ElectronicArts : IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPEContents(string file, PortableExecutable pex, bool includeDebug)
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
@@ -23,15 +18,15 @@ namespace BurnOutSharp.ProtectionType
|
||||
return null;
|
||||
|
||||
string name = pex.FileDescription;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.Contains("EReg MFC Application"))
|
||||
if (name?.Contains("EReg MFC Application") == true)
|
||||
return $"EA CdKey Registration Module {Utilities.GetInternalVersion(pex)}";
|
||||
else if (!string.IsNullOrWhiteSpace(name) && name.Contains("Registration code installer program"))
|
||||
else if (name?.Contains("Registration code installer program") == true)
|
||||
return $"EA CdKey Registration Module {Utilities.GetInternalVersion(pex)}";
|
||||
else if (!string.IsNullOrWhiteSpace(name) && name.Equals("EA DRM Helper", StringComparison.OrdinalIgnoreCase))
|
||||
else if (name?.Equals("EA DRM Helper", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"EA DRM Protection {Utilities.GetInternalVersion(pex)}";
|
||||
|
||||
name = pex.InternalName;
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.Equals("CDCode", StringComparison.Ordinal))
|
||||
if (name?.Equals("CDCode", StringComparison.Ordinal) == true)
|
||||
return $"EA CdKey Registration Module {Utilities.GetInternalVersion(pex)}";
|
||||
|
||||
var resource = pex.FindResource(dataContains: "A\0b\0o\0u\0t\0 \0C\0D\0K\0e\0y");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
@@ -11,7 +12,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("FREELOCK.IMG", useEndsWith: true), "FreeLock"),
|
||||
new PathMatchSet(new PathMatch("FREELOCK.IMG", useEndsWith: true), "FreeLock (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
@@ -22,7 +23,7 @@ namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
new PathMatchSet(new PathMatch("FREELOCK.IMG", useEndsWith: true), "FreeLock"),
|
||||
new PathMatchSet(new PathMatch("FREELOCK.IMG", useEndsWith: true), "FreeLock (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user