Use framework in even more content protections

This commit is contained in:
Matt Nadareski
2021-03-22 11:43:51 -07:00
parent da165345b6
commit e47a52dbe0
20 changed files with 203 additions and 147 deletions

View File

@@ -89,10 +89,9 @@ namespace BurnOutSharp.Matching
}
// Otherwise, invoke the version method
// TODO: Pass all positions to the version finding method
else
{
string version = matcher.GetContentVersion(file, fileContent, positions[0]) ?? "Unknown Version";
string version = matcher.GetContentVersion(file, fileContent, positions) ?? "Unknown Version";
matchedProtections.Add($"{matcher.ProtectionName ?? "Unknown Protection"} {version}" + (includePosition ? $" (Index {positionsString})" : string.Empty));
}

View File

@@ -17,8 +17,7 @@ namespace BurnOutSharp.Matching
/// <summary>
/// Function to get a content version for this Matcher
/// </summary>
/// TODO: Can this be made more generic?
public Func<string, byte[], int, string> GetContentVersion { get; set; }
public Func<string, byte[], List<int>, string> GetContentVersion { get; set; }
/// <summary>
/// Set of all path matches
@@ -28,7 +27,6 @@ namespace BurnOutSharp.Matching
/// <summary>
/// Function to get a path version for this Matcher
/// </summary>
/// TODO: Can this be made more generic?
public Func<List<string>, string> GetPathVersion { get; set; }
/// <summary>
@@ -44,10 +42,10 @@ namespace BurnOutSharp.Matching
public Matcher(List<byte?[]> needles, string protectionName)
: this(needles, null, protectionName) { }
public Matcher(byte?[] needle, Func<string, byte[], int, string> getVersion, string protectionName)
public Matcher(byte?[] needle, Func<string, byte[], List<int>, string> getVersion, string protectionName)
: this(new List<byte?[]> { needle }, getVersion, protectionName) { }
public Matcher(List<byte?[]> needles, Func<string, byte[], int, string> getVersion, string protectionName)
public Matcher(List<byte?[]> needles, Func<string, byte[], List<int>, string> getVersion, string protectionName)
: this(needles.Select(n => new ContentMatch(n)).ToList(), getVersion, protectionName) { }
public Matcher(ContentMatch needle, string protectionName)
@@ -56,10 +54,10 @@ namespace BurnOutSharp.Matching
public Matcher(List<ContentMatch> needles, string protectionName)
: this(needles, null, protectionName) { }
public Matcher(ContentMatch needle, Func<string, byte[], int, string> getVersion, string protectionName)
public Matcher(ContentMatch needle, Func<string, byte[], List<int>, string> getVersion, string protectionName)
: this(new List<ContentMatch>() { needle }, getVersion, protectionName) { }
public Matcher(List<ContentMatch> needles, Func<string, byte[], int, string> getVersion, string protectionName)
public Matcher(List<ContentMatch> needles, Func<string, byte[], List<int>, string> getVersion, string protectionName)
{
ContentMatches = needles;
GetContentVersion = getVersion;

View File

@@ -46,7 +46,7 @@ namespace BurnOutSharp.PackerType
return null;
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
byte[] signature = new ArraySegment<byte>(fileContent, 0x30, 12).ToArray();

View File

@@ -32,10 +32,11 @@ namespace BurnOutSharp.PackerType
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
public static string GetVersion(string file, byte[] fileContent, int index)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
try
{
int index = positions[0];
index += 24;
if (fileContent[index] != 'v')
return "(Unknown Version)";

View File

@@ -30,9 +30,9 @@ namespace BurnOutSharp.PackerType
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
return $"v{BitConverter.ToInt16(fileContent, position + 4)}";
return $"v{BitConverter.ToInt16(fileContent, positions[0] + 4)}";
}
}
}

View File

@@ -67,7 +67,7 @@ namespace BurnOutSharp.PackerType
return null;
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
// Check the manifest version first
string version = Utilities.GetManifestVersion(fileContent);

View File

@@ -45,10 +45,11 @@ namespace BurnOutSharp.PackerType
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
public static string GetVersion(string file, byte[] fileContent, int index)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
try
{
int index = positions[0];
index -= 5;
string versionString = Encoding.ASCII.GetString(fileContent, index, 4);
if (!char.IsNumber(versionString[0]))

View File

@@ -92,7 +92,7 @@ namespace BurnOutSharp.PackerType
return null;
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
// Check the manifest version first
string version = Utilities.GetManifestVersion(fileContent);

View File

@@ -57,9 +57,9 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
char[] version = new ArraySegment<byte>(fileContent, position + 15, 4).Select(b => (char)b).ToArray();
char[] version = new ArraySegment<byte>(fileContent, positions[0] + 15, 4).Select(b => (char)b).ToArray();
if (version[0] == 0x00)
return "";

View File

@@ -23,9 +23,9 @@ namespace BurnOutSharp.ProtectionType
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
char[] version = new ArraySegment<byte>(fileContent, position + 15, 4).Select(b => (char)b).ToArray();
char[] version = new ArraySegment<byte>(fileContent, positions[0] + 15, 4).Select(b => (char)b).ToArray();
if (version[0] == 0x00)
return "";

View File

@@ -5,35 +5,41 @@ using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
// TODO: Figure out how to use GetContentMatches here
public class JoWooDXProt : IContentCheck
{
/// <inheritdoc/>
public string CheckContents(string file, byte[] fileContent, bool includePosition = false)
{
// ".ext "
byte?[] check = new byte?[] { 0x2E, 0x65, 0x78, 0x74, 0x20, 0x20, 0x20, 0x20 };
if (fileContent.FirstPosition(check, out int position))
{
// "kernel32.dll" + (char)0x00 + (char)0x00 + (char)0x00 + "VirtualProtect"
byte?[] check2 = new byte?[] { 0x6B, 0x65, 0x72, 0x6E, 0x65, 0x6C, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6C, 0x50, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74 };
if (fileContent.FirstPosition(check2, out int position2))
return $"JoWooD X-Prot {GetVersion(fileContent, --position2)}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
else
return $"JoWooD X-Prot v1" + (includePosition ? $" (Index {position})" : string.Empty);
}
var matchers = new List<Matcher>
{
// @HC09
new Matcher(new byte?[] { 0x40, 0x48, 0x43, 0x30, 0x39, 0x20, 0x20, 0x20, 0x20 }, "JoWooD X-Prot v2"),
new Matcher(new List<byte?[]>
{
// .ext
new byte?[] { 0x2E, 0x65, 0x78, 0x74, 0x20, 0x20, 0x20, 0x20 },
// kernel32.dll + (char)0x00 + (char)0x00 + (char)0x00 + VirtualProtect
new byte?[]
{
0x6B, 0x65, 0x72, 0x6E, 0x65, 0x6C, 0x33, 0x32,
0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x56,
0x69, 0x72, 0x74, 0x75, 0x61, 0x6C, 0x50, 0x72,
0x6F, 0x74, 0x65, 0x63, 0x74
},
}, GetVersion, "JoWooD X-Prot"),
// .ext
new Matcher(new byte?[] { 0x2E, 0x65, 0x78, 0x74, 0x20, 0x20, 0x20, 0x20 }, "JoWooD X-Prot v1"),
};
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
private static string GetVersion(byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
int position = positions[1]--; // TODO: Verify this subtract
char[] version = new ArraySegment<byte>(fileContent, position + 67, 8).Select(b => (char)b).ToArray();
return $"{version[0]}.{version[2]}.{version[4]}.{version[6]}{version[7]}";
}

View File

@@ -25,7 +25,7 @@ namespace BurnOutSharp.ProtectionType
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
public static string GetVersion6till8(string file, byte[] fileContent, int position)
public static string GetVersion6till8(string file, byte[] fileContent, List<int> positions)
{
string version = SearchProtectDiscVersion(file, fileContent);
if (version.Length > 0)
@@ -34,10 +34,10 @@ namespace BurnOutSharp.ProtectionType
return $"{astrVersionArray[0]}.{astrVersionArray[1]}.{astrVersionArray[2]} (Build {astrVersionArray[3]})";
}
return $"{GetVersionBuild6till8(fileContent, position)}";
return $"{GetVersionBuild6till8(fileContent, positions[0])}";
}
public static string GetVersion76till10(string file, byte[] fileContent, int position)
public static string GetVersion76till10(string file, byte[] fileContent, List<int> positions)
{
string version = SearchProtectDiscVersion(file, fileContent);
if (version.Length > 0)
@@ -45,7 +45,7 @@ namespace BurnOutSharp.ProtectionType
string[] astrVersionArray = version.Split('.');
if (astrVersionArray[0] == "9")
{
if (GetVersionBuild76till10(fileContent, position, out int ibuild).Length > 0)
if (GetVersionBuild76till10(fileContent, positions[0], out int ibuild).Length > 0)
return $"{astrVersionArray[0]}.{astrVersionArray[1]}{astrVersionArray[2]}.{astrVersionArray[3]} (Build {ibuild})";
}
else

View File

@@ -131,9 +131,18 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string Get320to4xVersion(string file, byte[] fileContent, List<int> positions)
{
int index = position + 20; // Begin reading after "BoG_ *90.0&!! Yy>" for old SafeDisc
string version = SearchSafeDiscVersion(file, fileContent);
if (version.Length > 0)
return version;
return "3.20-4.xx (version removed)";
}
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
int index = positions[0] + 20; // Begin reading after "BoG_ *90.0&!! Yy>" for old SafeDisc
int version = BitConverter.ToInt32(fileContent, index);
index += 4;
int subVersion = BitConverter.ToInt32(fileContent, index);
@@ -143,7 +152,7 @@ namespace BurnOutSharp.ProtectionType
if (version != 0)
return $"{version}.{subVersion:00}.{subsubVersion:000}";
index = position + 18 + 14; // Begin reading after "BoG_ *90.0&!! Yy>" for newer SafeDisc
index = positions[0] + 18 + 14; // Begin reading after "BoG_ *90.0&!! Yy>" for newer SafeDisc
version = BitConverter.ToInt32(fileContent, index);
index += 4;
subVersion = BitConverter.ToInt32(fileContent, index);
@@ -156,15 +165,6 @@ namespace BurnOutSharp.ProtectionType
return $"{version}.{subVersion:00}.{subsubVersion:000}";
}
public static string Get320to4xVersion(string file, byte[] fileContent, int position)
{
string version = SearchSafeDiscVersion(file, fileContent);
if (version.Length > 0)
return version;
return "3.20-4.xx (version removed)";
}
private static string GetDPlayerXVersion(string file)
{
if (file == null || !File.Exists(file))

View File

@@ -92,9 +92,9 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetV4Version(string file, byte[] fileContent, int position)
public static string GetV4Version(string file, byte[] fileContent, List<int> positions)
{
int index = position + 8; // Begin reading after "AddD"
int index = positions[0] + 8; // Begin reading after "AddD"
char version = (char)fileContent[index];
index += 2;
@@ -112,9 +112,9 @@ namespace BurnOutSharp.ProtectionType
return $"{version}.{subVersion}.{subSubVersion}.{subSubSubVersion}";
}
public static string GetV5Version(string file, byte[] fileContent, int position)
public static string GetV5Version(string file, byte[] fileContent, List<int> positions)
{
int index = position + 8; // Begin reading after "ÊÝݬ"
int index = positions[0] + 8; // Begin reading after "ÊÝݬ"
byte version = (byte)(fileContent[index] & 0x0F);
index += 2;
@@ -145,7 +145,7 @@ namespace BurnOutSharp.ProtectionType
return $"{version}.{subVersion[0]}{subVersion[1]}.{subSubVersion[0]}{subSubVersion[1]}.{subSubSubVersion[0]}{subSubSubVersion[1]}{subSubSubVersion[2]}{subSubSubVersion[3]}";
}
public static string GetV7Version(string file, byte[] fileContent, int position)
public static string GetV7Version(string file, byte[] fileContent, List<int> positions)
{
int index = 236;
byte[] bytes = new ReadOnlySpan<byte>(fileContent, index, 4).ToArray();

View File

@@ -7,7 +7,6 @@ using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
// TODO: Figure out how to use GetContentMatches here
public class SolidShield : IContentCheck, IPathCheck
{
/// <inheritdoc/>
@@ -62,7 +61,8 @@ namespace BurnOutSharp.ProtectionType
// dvm.dll
new Matcher(new byte?[] { 0x64, 0x76, 0x6D, 0x2E, 0x64, 0x6C, 0x6C }, "SolidShield EXE Wrapper"),
// Placeholder for the complex SolidShield + TAGES check
// (char)0xAD + (char)0xDE + (char)0xFE + (char)0xCA
new Matcher(new byte?[] { 0xAD, 0xDE, 0xFE, 0xCA }, GetVersionPlusTages, "SolidShield"),
// Solidshield
new Matcher(new byte?[]
@@ -80,41 +80,7 @@ namespace BurnOutSharp.ProtectionType
}, "SolidShield"),
};
string firstMatch = MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
if (firstMatch != null)
return firstMatch;
// (char)0xAD + (char)0xDE + (char)0xFE + (char)0xCA
byte?[] check = new byte?[] { 0xAD, 0xDE, 0xFE, 0xCA };
if (fileContent.FirstPosition(check, out int position))
{
var id1 = new ArraySegment<byte>(fileContent, position + 4, 3);
var id2 = new ArraySegment<byte>(fileContent, position + 15, 4);
if ((fileContent[position + 3] == 0x04 || fileContent[position + 3] == 0x05)
&& id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 })
&& id2.SequenceEqual(new byte[] { 0x00, 0x10, 0x00, 0x00 }))
{
return "SolidShield 2 (SolidShield v2 EXE Wrapper)" + (includePosition ? $" (Index {position})" : string.Empty);
}
else if (id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 })
&& id2.SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00 }))
{
// "T" + (char)0x00 + "a" + (char)0x00 + "g" + (char)0x00 + "e" + (char)0x00 + "s" + (char)0x00 + "S" + (char)0x00 + "e" + (char)0x00 + "t" + (char)0x00 + "u" + (char)0x00 + "p" + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + "0" + (char)0x00 + (char)0x8 + (char)0x00 + (char)0x1 + (char)0x0 + "F" + (char)0x00 + "i" + (char)0x00 + "l" + (char)0x00 + "e" + (char)0x00 + "V" + (char)0x00 + "e" + (char)0x00 + "r" + (char)0x00 + "s" + (char)0x00 + "i" + (char)0x00 + "o" + (char)0x00 + "n" + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00
byte?[] check2 = new byte?[] { 0x54, 0x61, 0x67, 0x65, 0x73, 0x53, 0x65, 0x74, 0x75, 0x70, 0x30, 0x08, 0x01, 0x00, 0x46, 0x69, 0x6C, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00 };
if (fileContent.FirstPosition(check2, out int position2))
{
position2--; // TODO: Verify this subtract
return $"SolidShield 2 + Tagès {fileContent[position2 + 0x38]}.{fileContent[position2 + 0x38 + 4]}.{fileContent[position2 + 0x38 + 8]}.{fileContent[position + 0x38 + 12]}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
}
else
{
return "SolidShield 2 (SolidShield v2 EXE Wrapper)" + (includePosition ? $" (Index {position})" : string.Empty);
}
}
}
return null;
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
/// <inheritdoc/>
@@ -146,10 +112,10 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetExeWrapperVersion(string file, byte[] fileContent, int position)
public static string GetExeWrapperVersion(string file, byte[] fileContent, List<int> positions)
{
var id1 = new ArraySegment<byte>(fileContent, position + 5, 3);
var id2 = new ArraySegment<byte>(fileContent, position + 16, 4);
var id1 = new ArraySegment<byte>(fileContent, positions[0] + 5, 3);
var id2 = new ArraySegment<byte>(fileContent, positions[0] + 16, 4);
if (id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 }) && id2.SequenceEqual(new byte[] { 0x00, 0x10, 0x00, 0x00 }))
return "1 (SolidShield EXE Wrapper)";
@@ -159,7 +125,7 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetFileVersion(string file, byte[] fileContent, int position)
public static string GetFileVersion(string file, byte[] fileContent, List<int> positions)
{
string companyName = string.Empty;
if (file != null)
@@ -171,9 +137,9 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
int index = position + 12; // Begin reading after "Solidshield"
int index = positions[0] + 12; // Begin reading after "Solidshield"
char version = (char)fileContent[index];
index++;
index++;
@@ -187,5 +153,36 @@ namespace BurnOutSharp.ProtectionType
return $"{version}.{subVersion}.{subSubVersion}.{subSubSubVersion}";
}
public static string GetVersionPlusTages(string file, byte[] fileContent, List<int> positions)
{
int position = positions[0];
var id1 = new ArraySegment<byte>(fileContent, position + 4, 3);
var id2 = new ArraySegment<byte>(fileContent, position + 15, 4);
if ((fileContent[position + 3] == 0x04 || fileContent[position + 3] == 0x05)
&& id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 })
&& id2.SequenceEqual(new byte[] { 0x00, 0x10, 0x00, 0x00 }))
{
return "2 (SolidShield v2 EXE Wrapper)";
}
else if (id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 })
&& id2.SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00 }))
{
// "T" + (char)0x00 + "a" + (char)0x00 + "g" + (char)0x00 + "e" + (char)0x00 + "s" + (char)0x00 + "S" + (char)0x00 + "e" + (char)0x00 + "t" + (char)0x00 + "u" + (char)0x00 + "p" + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + "0" + (char)0x00 + (char)0x8 + (char)0x00 + (char)0x1 + (char)0x0 + "F" + (char)0x00 + "i" + (char)0x00 + "l" + (char)0x00 + "e" + (char)0x00 + "V" + (char)0x00 + "e" + (char)0x00 + "r" + (char)0x00 + "s" + (char)0x00 + "i" + (char)0x00 + "o" + (char)0x00 + "n" + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00
byte?[] check2 = new byte?[] { 0x54, 0x61, 0x67, 0x65, 0x73, 0x53, 0x65, 0x74, 0x75, 0x70, 0x30, 0x08, 0x01, 0x00, 0x46, 0x69, 0x6C, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00 };
if (fileContent.FirstPosition(check2, out int position2))
{
position2--; // TODO: Verify this subtract
return $"2 + Tagès {fileContent[position2 + 0x38]}.{fileContent[position2 + 0x38 + 4]}.{fileContent[position2 + 0x38 + 8]}.{fileContent[position + 0x38 + 12]}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
}
else
{
return "2 (SolidShield v2 EXE Wrapper)";
}
}
return null;
}
}
}

View File

@@ -6,50 +6,99 @@ using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
// TODO: Figure out how to use GetContentMatches here
public class StarForce : IContentCheck, IPathCheck
{
/// <inheritdoc/>
public string CheckContents(string file, byte[] fileContent, bool includePosition = false)
{
// "(" + (char)0x00 + "c" + (char)0x00 + ")" + (char)0x00 + " " + (char)0x00 + "P" + (char)0x00 + "r" + (char)0x00 + "o" + (char)0x00 + "t" + (char)0x00 + "e" + (char)0x00 + "c" + (char)0x00 + "t" + (char)0x00 + "i" + (char)0x00 + "o" + (char)0x00 + "n" + (char)0x00 + " " + (char)0x00 + "T" + (char)0x00 + "e" + (char)0x00 + "c" + (char)0x00 + "h" + (char)0x00 + "n" + (char)0x00 + "o" + (char)0x00 + "l" + (char)0x00 + "o" + (char)0x00 + "g" + (char)0x00 + "y" + (char)0x00
byte?[] check = new byte?[] { 0x28, 0x00, 0x63, 0x00, 0x29, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6E, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x67, 0x00, 0x79, 0x00 };
if (fileContent.FirstPosition(check, out int position))
{
// "PSA_GetDiscLabel"
// byte?[] check2 = new byte?[] { 0x50, 0x53, 0x41, 0x5F, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x4C, 0x61, 0x62, 0x65, 0x6C };
// "(c) Protection Technology"
// byte?[] check2 = new byte?[] { 0x28, 0x63, 0x29, 0x20, 0x50, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x79 };
// "TradeName"
byte?[] check2 = new byte?[] { 0x54, 0x72, 0x61, 0x64, 0x65, 0x4E, 0x61, 0x6D, 0x65 };
if (fileContent.FirstPosition(check2, out int position2) && position2 != 0)
return $"StarForce {Utilities.GetFileVersion(file)} ({fileContent.Skip(position2 + 22).TakeWhile(c => c != 0x00)})" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
else
return $"StarForce {Utilities.GetFileVersion(file)}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
}
// "Protection Technology, Ltd."
check = new byte?[] { 0x50, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x79, 0x2C, 0x20, 0x4C, 0x74, 0x64, 0x2E };
if (fileContent.FirstPosition(check, out position))
{
// "PSA_GetDiscLabel"
// byte?[] check2 = new byte?[] { 0x50, 0x53, 0x41, 0x5F, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x4C, 0x61, 0x62, 0x65, 0x6C };
// "(c) Protection Technology"
// byte?[] check2 = new byte?[] { 0x28, 0x63, 0x29, 0x20, 0x50, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x79 };
// "TradeName"
byte?[] check2 = new byte?[] { 0x54, 0x72, 0x61, 0x64, 0x65, 0x4E, 0x61, 0x6D, 0x65 };
if (fileContent.FirstPosition(check2, out int position2) && position2 != 0)
return $"StarForce {Utilities.GetFileVersion(file)} ({fileContent.Skip(position2 + 22).TakeWhile(c => c != 0x00)})" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
else
return $"StarForce {Utilities.GetFileVersion(file)}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
}
var matchers = new List<Matcher>
{
new Matcher(new List<byte?[]>
{
// ( + (char)0x00 + c + (char)0x00 + ) + (char)0x00 + + (char)0x00 + P + (char)0x00 + r + (char)0x00 + o + (char)0x00 + t + (char)0x00 + e + (char)0x00 + c + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + T + (char)0x00 + e + (char)0x00 + c + (char)0x00 + h + (char)0x00 + n + (char)0x00 + o + (char)0x00 + l + (char)0x00 + o + (char)0x00 + g + (char)0x00 + y + (char)0x00
new byte?[]
{
0x28, 0x00, 0x63, 0x00, 0x29, 0x00, 0x20, 0x00,
0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x74, 0x00,
0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00,
0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x54, 0x00,
0x65, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6E, 0x00,
0x6F, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x67, 0x00,
0x79, 0x00
},
// // PSA_GetDiscLabel
// new byte?[]
// {
// 0x50, 0x53, 0x41, 0x5F, 0x47, 0x65, 0x74, 0x44,
// 0x69, 0x73, 0x63, 0x4C, 0x61, 0x62, 0x65, 0x6C
// },
// (c) Protection Technology
// new byte?[]
// {
// 0x28, 0x63, 0x29, 0x20, 0x50, 0x72, 0x6F, 0x74,
// 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x54,
// 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67,
// 0x79
// },
// TradeName
new byte?[] { 0x54, 0x72, 0x61, 0x64, 0x65, 0x4E, 0x61, 0x6D, 0x65 },
}, GetVersion, "StarForce"),
// ( + (char)0x00 + c + (char)0x00 + ) + (char)0x00 + + (char)0x00 + P + (char)0x00 + r + (char)0x00 + o + (char)0x00 + t + (char)0x00 + e + (char)0x00 + c + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + T + (char)0x00 + e + (char)0x00 + c + (char)0x00 + h + (char)0x00 + n + (char)0x00 + o + (char)0x00 + l + (char)0x00 + o + (char)0x00 + g + (char)0x00 + y + (char)0x00
new Matcher(new byte?[]
{
0x28, 0x00, 0x63, 0x00, 0x29, 0x00, 0x20, 0x00,
0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x74, 0x00,
0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00,
0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x54, 0x00,
0x65, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6E, 0x00,
0x6F, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x67, 0x00,
0x79, 0x00
}, Utilities.GetFileVersion, "StarForce"),
new Matcher(new List<byte?[]>
{
// Protection Technology, Ltd.
new byte?[]
{
0x50, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74, 0x69,
0x6F, 0x6E, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E,
0x6F, 0x6C, 0x6F, 0x67, 0x79, 0x2C, 0x20, 0x4C,
0x74, 0x64, 0x2E
},
// // PSA_GetDiscLabel
// new byte?[]
// {
// 0x50, 0x53, 0x41, 0x5F, 0x47, 0x65, 0x74, 0x44,
// 0x69, 0x73, 0x63, 0x4C, 0x61, 0x62, 0x65, 0x6C
// },
// (c) Protection Technology
// new byte?[]
// {
// 0x28, 0x63, 0x29, 0x20, 0x50, 0x72, 0x6F, 0x74,
// 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x54,
// 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67,
// 0x79
// },
// TradeName
new byte?[] { 0x54, 0x72, 0x61, 0x64, 0x65, 0x4E, 0x61, 0x6D, 0x65 },
}, GetVersion, "StarForce"),
// Protection Technology, Ltd.
new Matcher(new byte?[]
{
0x50, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74, 0x69,
0x6F, 0x6E, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E,
0x6F, 0x6C, 0x6F, 0x67, 0x79, 0x2C, 0x20, 0x4C,
0x74, 0x64, 0x2E
}, Utilities.GetFileVersion, "StarForce"),
// .sforce
new Matcher(new byte?[] { 0x2E, 0x73, 0x66, 0x6F, 0x72, 0x63, 0x65 }, "StarForce 3-5"),
@@ -93,5 +142,10 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
return $"{Utilities.GetFileVersion(file)} ({fileContent.Skip(positions[1] + 22).TakeWhile(c => c != 0x00)})";
}
}
}

View File

@@ -28,9 +28,9 @@ namespace BurnOutSharp.ProtectionType
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
int index = position - 3;
int index = positions[0] - 3;
char subVersion = (char)fileContent[index];
index++;
index++;

View File

@@ -94,11 +94,11 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
// (char)0xFF + (char)0xFF + "h"
if (new ArraySegment<byte>(fileContent, --position + 8, 3).SequenceEqual(new byte[] { 0xFF, 0xFF, 0x68 })) // TODO: Verify this subtract
return GetVersion(fileContent, position);
if (new ArraySegment<byte>(fileContent, --positions[0] + 8, 3).SequenceEqual(new byte[] { 0xFF, 0xFF, 0x68 })) // TODO: Verify this subtract
return GetVersion(fileContent, positions[0]);
return null;
}

View File

@@ -50,9 +50,9 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetOldVersion(string file, byte[] fileContent, int position)
public static string GetOldVersion(string file, byte[] fileContent, List<int> positions)
{
position--; // TODO: Verify this subtract
int position = positions[0]--; // TODO: Verify this subtract
char[] version = new ArraySegment<byte>(fileContent, position + 16, 4).Select(b => (char)b).ToArray(); // Begin reading after "VOB ProtectCD"
if (char.IsNumber(version[0]) && char.IsNumber(version[2]) && char.IsNumber(version[3]))
return $"{version[0]}.{version[2]}{version[3]}";
@@ -60,9 +60,9 @@ namespace BurnOutSharp.ProtectionType
return "old";
}
public static string GetVersion(string file, byte[] fileContent, int position)
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
{
string version = GetVersion(fileContent, --position); // TODO: Verify this subtract
string version = GetVersion(fileContent, --positions[0]); // TODO: Verify this subtract
if (version.Length > 0)
return version;
@@ -75,7 +75,7 @@ namespace BurnOutSharp.ProtectionType
return version;
}
return $"5.9-6.0 {GetBuild(fileContent, position)}";
return $"5.9-6.0 {GetBuild(fileContent, positions[0])}";
}
private static string GetBuild(byte[] fileContent, int position)

View File

@@ -248,9 +248,9 @@ namespace BurnOutSharp
/// </summary>
/// <param name="file">File to check for version</param>
/// <param name="fileContent">Byte array representing the file contents</param>
/// <param name="position">Last matched position in the contents</param>
/// <param name="positions">Last matched positions in the contents</param>
/// <returns>Version string, null on error</returns>
public static string GetFileVersion(string file, byte[] fileContent, int position)
public static string GetFileVersion(string file, byte[] fileContent, List<int> positions)
{
return GetFileVersion(file);
}