Use framework for more content protections

This commit is contained in:
Matt Nadareski
2021-03-22 11:13:14 -07:00
parent 8ea54328ef
commit da165345b6
9 changed files with 355 additions and 250 deletions

View File

@@ -2,28 +2,49 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
// TODO: Figure out how to use GetContentMatches here
public class ImpulseReactor : IContentCheck, IPathCheck
{
/// <inheritdoc/>
public string CheckContents(string file, byte[] fileContent, bool includePosition = false)
{
// "CVPInitializeClient"
byte?[] check = new byte?[] { 0x43, 0x56, 0x50, 0x49, 0x6E, 0x69, 0x74, 0x69, 0x61, 0x6C, 0x69, 0x7A, 0x65, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74 };
if (fileContent.FirstPosition(check, out int position))
var matchers = new List<Matcher>
{
// "A" + (char)0x00 + "T" + (char)0x00 + "T" + (char)0x00 + "L" + (char)0x00 + "I" + (char)0x00 + "S" + (char)0x00 + "T" + (char)0x00 + (char)0x00 + (char)0x00 + "E" + (char)0x00 + "L" + (char)0x00 + "E" + (char)0x00 + "M" + (char)0x00 + "E" + (char)0x00 + "N" + (char)0x00 + "T" + (char)0x00 + (char)0x00 + (char)0x00 + "N" + (char)0x00 + "O" + (char)0x00 + "T" + (char)0x00 + "A" + (char)0x00 + "T" + (char)0x00 + "I" + (char)0x00 + "O" + (char)0x00 + "N"
byte?[] check2 = new byte?[] { 0x41, 0x00, 0x54, 0x00, 0x54, 0x00, 0x4C, 0x00, 0x49, 0x00, 0x53, 0x00, 0x54, 0x00, 0x00, 0x00, 0x45, 0x00, 0x4C, 0x00, 0x45, 0x00, 0x4D, 0x00, 0x45, 0x00, 0x4E, 0x00, 0x54, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x4F, 0x00, 0x54, 0x00, 0x41, 0x00, 0x54, 0x00, 0x49, 0x00, 0x4F, 0x00, 0x4E };
if (fileContent.FirstPosition(check2, out int position2))
return $"Impulse Reactor {Utilities.GetFileVersion(file)}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
else
return "Impulse Reactor" + (includePosition ? $" (Index {position})" : string.Empty);
}
new Matcher(new List<byte?[]>
{
// CVPInitializeClient
new byte?[]
{
0x43, 0x56, 0x50, 0x49, 0x6E, 0x69, 0x74, 0x69,
0x61, 0x6C, 0x69, 0x7A, 0x65, 0x43, 0x6C, 0x69,
0x65, 0x6E, 0x74
},
return null;
// A + (char)0x00 + T + (char)0x00 + T + (char)0x00 + L + (char)0x00 + I + (char)0x00 + S + (char)0x00 + T + (char)0x00 + (char)0x00 + (char)0x00 + E + (char)0x00 + L + (char)0x00 + E + (char)0x00 + M + (char)0x00 + E + (char)0x00 + N + (char)0x00 + T + (char)0x00 + (char)0x00 + (char)0x00 + N + (char)0x00 + O + (char)0x00 + T + (char)0x00 + A + (char)0x00 + T + (char)0x00 + I + (char)0x00 + O + (char)0x00 + N + (char)0x00
new byte?[]
{
0x41, 0x00, 0x54, 0x00, 0x54, 0x00, 0x4C, 0x00,
0x49, 0x00, 0x53, 0x00, 0x54, 0x00, 0x00, 0x00,
0x45, 0x00, 0x4C, 0x00, 0x45, 0x00, 0x4D, 0x00,
0x45, 0x00, 0x4E, 0x00, 0x54, 0x00, 0x00, 0x00,
0x4E, 0x00, 0x4F, 0x00, 0x54, 0x00, 0x41, 0x00,
0x54, 0x00, 0x49, 0x00, 0x4F, 0x00, 0x4E
},
}, Utilities.GetFileVersion, "Impulse Reactor"),
// CVPInitializeClient
new Matcher(new byte?[]
{
0x43, 0x56, 0x50, 0x49, 0x6E, 0x69, 0x74, 0x69,
0x61, 0x6C, 0x69, 0x7A, 0x65, 0x43, 0x6C, 0x69,
0x65, 0x6E, 0x74
}, "Impulse Reactor"),
};
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
/// <inheritdoc/>

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
@@ -21,12 +23,13 @@ namespace BurnOutSharp.ProtectionType
return $"JoWooD X-Prot v1" + (includePosition ? $" (Index {position})" : string.Empty);
}
// "@HC09 "
check = new byte?[] { 0x40, 0x48, 0x43, 0x30, 0x39, 0x20, 0x20, 0x20, 0x20 };
if (fileContent.FirstPosition(check, out position))
return $"JoWooD X-Prot v2" + (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"),
};
return null;
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
private static string GetVersion(byte[] fileContent, int position)

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
@@ -29,17 +30,35 @@ namespace BurnOutSharp.ProtectionType
if (file != null && string.Equals(Path.GetFileName(file), "NOMOUSE.SP", StringComparison.OrdinalIgnoreCase))
return $"LaserLock {GetVersion16Bit(fileContent)}" + (includePosition ? $" (Index 71)" : string.Empty);
// ":\\LASERLOK\\LASERLOK.IN" + (char)0x00 + "C:\\NOMOUSE.SP"
check = new byte?[] { 0x3A, 0x5C, 0x5C, 0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C, 0x4F, 0x4B, 0x5C, 0x5C, 0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C, 0x4F, 0x4B, 0x2E, 0x49, 0x4E, 0x00, 0x43, 0x3A, 0x5C, 0x5C, 0x4E, 0x4F, 0x4D, 0x4F, 0x55, 0x53, 0x45, 0x2E, 0x53, 0x50 };
if (fileContent.FirstPosition(check, out position))
return "LaserLock 3" + (includePosition ? $" (Index {position})" : string.Empty);
var matchers = new List<Matcher>
{
// :\\LASERLOK\\LASERLOK.IN + (char)0x00 + C:\\NOMOUSE.SP
new Matcher(new byte?[]
{
0x3A, 0x5C, 0x5C, 0x4C, 0x41, 0x53, 0x45, 0x52,
0x4C, 0x4F, 0x4B, 0x5C, 0x5C, 0x4C, 0x41, 0x53,
0x45, 0x52, 0x4C, 0x4F, 0x4B, 0x2E, 0x49, 0x4E,
0x00, 0x43, 0x3A, 0x5C, 0x5C, 0x4E, 0x4F, 0x4D,
0x4F, 0x55, 0x53, 0x45, 0x2E, 0x53, 0x50
}, "LaserLock 3"),
// "LASERLOK_INIT" + (char)0xC + "LASERLOK_RUN" + (char)0xE + "LASERLOK_CHECK" + (char)0xF + "LASERLOK_CHECK2" + (char)0xF + "LASERLOK_CHECK3"
check = new byte?[] { 0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C, 0x4F, 0x4B, 0x5F, 0x49, 0x4E, 0x49, 0x54, 0x0C, 0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C, 0x4F, 0x4B, 0x5F, 0x52, 0x55, 0x4E, 0x0E, 0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C, 0x4F, 0x4B, 0x5F, 0x43, 0x48, 0x45, 0x43, 0x4B, 0x0F, 0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C, 0x4F, 0x4B, 0x5F, 0x43, 0x48, 0x45, 0x43, 0x4B, 0x32, 0x0F, 0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C, 0x4F, 0x4B, 0x5F, 0x43, 0x48, 0x45, 0x43, 0x4B, 0x33 };
if (fileContent.FirstPosition(check, out position))
return "LaserLock 5" + (includePosition ? $" (Index {position})" : string.Empty);
// LASERLOK_INIT + (char)0xC + LASERLOK_RUN + (char)0xE + LASERLOK_CHECK + (char)0xF + LASERLOK_CHECK2 + (char)0xF + LASERLOK_CHECK3
new Matcher(new byte?[]
{
0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C, 0x4F, 0x4B,
0x5F, 0x49, 0x4E, 0x49, 0x54, 0x0C, 0x4C, 0x41,
0x53, 0x45, 0x52, 0x4C, 0x4F, 0x4B, 0x5F, 0x52,
0x55, 0x4E, 0x0E, 0x4C, 0x41, 0x53, 0x45, 0x52,
0x4C, 0x4F, 0x4B, 0x5F, 0x43, 0x48, 0x45, 0x43,
0x4B, 0x0F, 0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C,
0x4F, 0x4B, 0x5F, 0x43, 0x48, 0x45, 0x43, 0x4B,
0x32, 0x0F, 0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C,
0x4F, 0x4B, 0x5F, 0x43, 0x48, 0x45, 0x43, 0x4B,
0x33
}, "LaserLock 5"),
};
return null;
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
/// <inheritdoc/>

View File

@@ -1,49 +1,57 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
// TODO: Figure out how to use GetContentMatches here
public class ProtectDisc : IContentCheck
{
/// <inheritdoc/>
public string CheckContents(string file, byte[] fileContent, bool includePosition = false)
{
// "HúMETINF"
byte?[] check = new byte?[] { 0x48, 0xFA, 0x4D, 0x45, 0x54, 0x49, 0x4E, 0x46 };
if (fileContent.FirstPosition(check, out int position))
var matchers = new List<Matcher>
{
string version = SearchProtectDiscVersion(file, fileContent);
if (version.Length > 0)
{
string[] astrVersionArray = version.Split('.');
if (astrVersionArray[0] == "9")
{
if (GetVersionBuild76till10(fileContent, position, out int ibuild).Length > 0)
return $"ProtectDisc {astrVersionArray[0]}.{astrVersionArray[1]}{astrVersionArray[2]}.{astrVersionArray[3]} (Build {ibuild})" + (includePosition ? $" (Index {position})" : string.Empty);
}
else
{
return $"ProtectDisc {astrVersionArray[0]}.{astrVersionArray[1]}.{astrVersionArray[2]} (Build {astrVersionArray[3]})" + (includePosition ? $" (Index {position})" : string.Empty);
}
}
// HúMETINF
new Matcher(new byte?[] { 0x48, 0xFA, 0x4D, 0x45, 0x54, 0x49, 0x4E, 0x46 }, GetVersion76till10, "ProtectDisc"),
// ACE-PCD
new Matcher(new byte?[] { 0x41, 0x43, 0x45, 0x2D, 0x50, 0x43, 0x44 }, GetVersion6till8, "ProtectDisc"),
};
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
public static string GetVersion6till8(string file, byte[] fileContent, int position)
{
string version = SearchProtectDiscVersion(file, fileContent);
if (version.Length > 0)
{
string[] astrVersionArray = version.Split('.');
return $"{astrVersionArray[0]}.{astrVersionArray[1]}.{astrVersionArray[2]} (Build {astrVersionArray[3]})";
}
// "ACE-PCD"
check = new byte?[] { 0x41, 0x43, 0x45, 0x2D, 0x50, 0x43, 0x44 };
if (fileContent.FirstPosition(check, out position))
{
string version = SearchProtectDiscVersion(file, fileContent);
if (version.Length > 0)
{
string[] astrVersionArray = version.Split('.');
return $"ProtectDisc {astrVersionArray[0]}.{astrVersionArray[1]}.{astrVersionArray[2]} (Build {astrVersionArray[3]})" + (includePosition ? $" (Index {position})" : string.Empty);
}
return $"{GetVersionBuild6till8(fileContent, position)}";
}
return $"ProtectDisc {GetVersionBuild6till8(fileContent, position)}" + (includePosition ? $" (Index {position})" : string.Empty);
public static string GetVersion76till10(string file, byte[] fileContent, int position)
{
string version = SearchProtectDiscVersion(file, fileContent);
if (version.Length > 0)
{
string[] astrVersionArray = version.Split('.');
if (astrVersionArray[0] == "9")
{
if (GetVersionBuild76till10(fileContent, position, out int ibuild).Length > 0)
return $"{astrVersionArray[0]}.{astrVersionArray[1]}{astrVersionArray[2]}.{astrVersionArray[3]} (Build {ibuild})";
}
else
{
return $"{astrVersionArray[0]}.{astrVersionArray[1]}.{astrVersionArray[2]} (Build {astrVersionArray[3]})";
}
}
return null;

View File

@@ -4,61 +4,56 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
// TODO: Figure out how to use GetContentMatches here
public class SafeDisc : IContentCheck, IPathCheck
{
/// <inheritdoc/>
public string CheckContents(string file, byte[] fileContent, bool includePosition = false)
{
// "BoG_ *90.0&!! Yy>"
byte?[] check = new byte?[] { 0x42, 0x6F, 0x47, 0x5F, 0x20, 0x2A, 0x39, 0x30, 0x2E, 0x30, 0x26, 0x21, 0x21, 0x20, 0x20, 0x59, 0x79, 0x3E };
if (fileContent.FirstPosition(check, out int position))
var matchers = new List<Matcher>
{
// "product activation library"
byte?[] check2 = new byte?[] { 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x74, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79 };
if (fileContent.FirstPosition(check2, out int position2))
return $"SafeCast {GetVersion(fileContent, position)}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
else
return $"SafeDisc {GetVersion(fileContent, position)}" + (includePosition ? $" (Index {position})" : string.Empty);
}
new Matcher(new List<byte?[]>
{
// BoG_ *90.0&!! Yy>
new byte?[]
{
0x42, 0x6F, 0x47, 0x5F, 0x20, 0x2A, 0x39, 0x30,
0x2E, 0x30, 0x26, 0x21, 0x21, 0x20, 0x20, 0x59,
0x79, 0x3E
},
// (char)0x00 + (char)0x00 + "BoG_"
check = new byte?[] { 0x00, 0x00, 0x42, 0x6F, 0x47, 0x5F };
if (fileContent.FirstPosition(check, out position))
{
string version = SearchSafeDiscVersion(file, fileContent);
if (version.Length > 0)
return $"SafeDisc {version}" + (includePosition ? $" (Index {position})" : string.Empty);
// product activation library
new byte?[]
{
0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x74, 0x20,
0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x69,
0x6F, 0x6E, 0x20, 0x6C, 0x69, 0x62, 0x72, 0x61,
0x72, 0x79
},
}, GetVersion, "SafeCast"),
return "SafeDisc 3.20-4.xx (version removed)" + (includePosition ? $" (Index {position})" : string.Empty);
}
// BoG_ *90.0&!! Yy>
new Matcher(new byte?[]
{
0x42, 0x6F, 0x47, 0x5F, 0x20, 0x2A, 0x39, 0x30,
0x2E, 0x30, 0x26, 0x21, 0x21, 0x20, 0x20, 0x59,
0x79, 0x3E
}, "SafeDisc"),
// "stxt774"
check = new byte?[] { 0x73, 0x74, 0x78, 0x74, 0x37, 0x37, 0x34 };
if (fileContent.FirstPosition(check, out position))
{
string version = SearchSafeDiscVersion(file, fileContent);
if (version.Length > 0)
return $"SafeDisc {version}" + (includePosition ? $" (Index {position})" : string.Empty);
// (char)0x00 + (char)0x00 + BoG_
new Matcher(new byte?[] { 0x00, 0x00, 0x42, 0x6F, 0x47, 0x5F }, Get320to4xVersion, "SafeDisc"),
return "SafeDisc 3.20-4.xx (version removed)" + (includePosition ? $" (Index {position})" : string.Empty);
}
// stxt774
new Matcher(new byte?[] { 0x73, 0x74, 0x78, 0x74, 0x37, 0x37, 0x34 }, Get320to4xVersion, "SafeDisc"),
// "stxt371"
check = new byte?[] { 0x73, 0x74, 0x78, 0x74, 0x33, 0x37, 0x31 };
if (fileContent.FirstPosition(check, out position))
{
string version = SearchSafeDiscVersion(file, fileContent);
if (version.Length > 0)
return $"SafeDisc {version}" + (includePosition ? $" (Index {position})" : string.Empty);
// stxt371
new Matcher(new byte?[] { 0x73, 0x74, 0x78, 0x74, 0x33, 0x37, 0x31 }, Get320to4xVersion, "SafeDisc"),
};
return "SafeDisc 3.20-4.xx (version removed)" + (includePosition ? $" (Index {position})" : string.Empty);
}
return null;
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
/// <inheritdoc/>
@@ -136,6 +131,40 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetVersion(string file, byte[] fileContent, int position)
{
int index = position + 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);
index += 4;
int subsubVersion = BitConverter.ToInt32(fileContent, index);
if (version != 0)
return $"{version}.{subVersion:00}.{subsubVersion:000}";
index = position + 18 + 14; // Begin reading after "BoG_ *90.0&!! Yy>" for newer SafeDisc
version = BitConverter.ToInt32(fileContent, index);
index += 4;
subVersion = BitConverter.ToInt32(fileContent, index);
index += 4;
subsubVersion = BitConverter.ToInt32(fileContent, index);
if (version == 0)
return "";
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))
@@ -226,31 +255,6 @@ namespace BurnOutSharp.ProtectionType
return "SafeDisc 1 or greater";
}
private static string GetVersion(byte[] fileContent, int position)
{
int index = position + 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);
index += 4;
int subsubVersion = BitConverter.ToInt32(fileContent, index);
if (version != 0)
return $"{version}.{subVersion:00}.{subsubVersion:000}";
index = position + 18 + 14; // Begin reading after "BoG_ *90.0&!! Yy>" for newer SafeDisc
version = BitConverter.ToInt32(fileContent, index);
index += 4;
subVersion = BitConverter.ToInt32(fileContent, index);
index += 4;
subsubVersion = BitConverter.ToInt32(fileContent, index);
if (version == 0)
return "";
return $"{version}.{subVersion:00}.{subsubVersion:000}";
}
// TODO: Analyze this method and figure out if this can be done without attempting execution
private static string SearchSafeDiscVersion(string file, byte[] fileContent)
{

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
@@ -12,68 +13,80 @@ namespace BurnOutSharp.ProtectionType
/// <inheritdoc/>
public string CheckContents(string file, byte[] fileContent, bool includePosition = false)
{
// "D" + (char)0x00 + "V" + (char)0x00 + "M" + (char)0x00 + " " + (char)0x00 + "L" + (char)0x00 + "i" + (char)0x00 + "b" + (char)0x00 + "r" + (char)0x00 + "a" + (char)0x00 + "r" + (char)0x00 + "y"
byte?[] check = new byte?[] { 0x44, 0x00, 0x56, 0x00, 0x4D, 0x00, 0x20, 0x00, 0x4C, 0x00, 0x69, 0x00, 0x62, 0x00, 0x72, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79 };
if (fileContent.FirstPosition(check, out int position))
return $"SolidShield {Utilities.GetFileVersion(file)}" + (includePosition ? $" (Index {position})" : string.Empty);
// "S" + (char)0x00 + "o" + (char)0x00 + "l" + (char)0x00 + "i" + (char)0x00 + "d" + (char)0x00 + "s" + (char)0x00 + "h" + (char)0x00 + "i" + (char)0x00 + "e" + (char)0x00 + "l" + (char)0x00 + "d" + (char)0x00 + " " + (char)0x00 + "L" + (char)0x00 + "i" + (char)0x00 + "b" + (char)0x00 + "r" + (char)0x00 + "a" + (char)0x00 + "r" + (char)0x00 + "y"
check = new byte?[] { 0x53, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x69, 0x00, 0x64, 0x00, 0x73, 0x00, 0x68, 0x00, 0x69, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x64, 0x00, 0x20, 0x00, 0x4C, 0x00, 0x69, 0x00, 0x62, 0x00, 0x72, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79 };
if (fileContent.FirstPosition(check, out position))
var matchers = new List<Matcher>
{
string companyName = string.Empty;
if (file != null)
companyName = FileVersionInfo.GetVersionInfo(file).CompanyName.ToLower();
// D + (char)0x00 + V + (char)0x00 + M + (char)0x00 + + (char)0x00 + L + (char)0x00 + i + (char)0x00 + b + (char)0x00 + r + (char)0x00 + a + (char)0x00 + r + (char)0x00 + y + (char)0x00
new Matcher(new byte?[]
{
0x44, 0x00, 0x56, 0x00, 0x4D, 0x00, 0x20, 0x00,
0x4C, 0x00, 0x69, 0x00, 0x62, 0x00, 0x72, 0x00,
0x61, 0x00, 0x72, 0x00, 0x79, 0x00
}, Utilities.GetFileVersion, "SolidShield"),
if (companyName.Contains("solidshield") || companyName.Contains("tages"))
return $"SolidShield Core.dll {Utilities.GetFileVersion(file)}" + (includePosition ? $" (Index {position})" : string.Empty);
}
// S + (char)0x00 + o + (char)0x00 + l + (char)0x00 + i + (char)0x00 + d + (char)0x00 + s + (char)0x00 + h + (char)0x00 + i + (char)0x00 + e + (char)0x00 + l + (char)0x00 + d + (char)0x00 + + (char)0x00 + L + (char)0x00 + i + (char)0x00 + b + (char)0x00 + r + (char)0x00 + a + (char)0x00 + r + (char)0x00 + y + (char)0x00
new Matcher(new byte?[]
{
0x53, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x69, 0x00,
0x64, 0x00, 0x73, 0x00, 0x68, 0x00, 0x69, 0x00,
0x65, 0x00, 0x6C, 0x00, 0x64, 0x00, 0x20, 0x00,
0x4C, 0x00, 0x69, 0x00, 0x62, 0x00, 0x72, 0x00,
0x61, 0x00, 0x72, 0x00, 0x79, 0x00
}, GetFileVersion, "SolidShield Core.dll"),
// "S" + (char)0x00 + "o" + (char)0x00 + "l" + (char)0x00 + "i" + (char)0x00 + "d" + (char)0x00 + "s" + (char)0x00 + "h" + (char)0x00 + "i" + (char)0x00 + "e" + (char)0x00 + "l" + (char)0x00 + "d" + (char)0x00 + " " + (char)0x00 + "A" + (char)0x00 + "c" + (char)0x00 + "t" + (char)0x00 + "i" + (char)0x00 + "v" + (char)0x00 + "a" + (char)0x00 + "t" + (char)0x00 + "i" + (char)0x00 + "o" + (char)0x00 + "n" + (char)0x00 + " " + (char)0x00 + "L" + (char)0x00 + "i" + (char)0x00 + "b" + (char)0x00 + "r" + (char)0x00 + "a" + (char)0x00 + "r" + (char)0x00 + "y"
check = new byte?[] { 0x53, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x69, 0x00, 0x64, 0x00, 0x73, 0x00, 0x68, 0x00, 0x69, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x64, 0x00, 0x20, 0x00, 0x41, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x4C, 0x00, 0x69, 0x00, 0x62, 0x00, 0x72, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79 };
if (fileContent.FirstPosition(check, out position))
{
string companyName = string.Empty;
if (file != null)
companyName = FileVersionInfo.GetVersionInfo(file).CompanyName.ToLower();
// S + (char)0x00 + o + (char)0x00 + l + (char)0x00 + i + (char)0x00 + d + (char)0x00 + s + (char)0x00 + h + (char)0x00 + i + (char)0x00 + e + (char)0x00 + l + (char)0x00 + d + (char)0x00 + + (char)0x00 + A + (char)0x00 + c + (char)0x00 + t + (char)0x00 + i + (char)0x00 + v + (char)0x00 + a + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + L + (char)0x00 + i + (char)0x00 + b + (char)0x00 + r + (char)0x00 + a + (char)0x00 + r + (char)0x00 + y + (char)0x00
new Matcher(new byte?[]
{
0x53, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x69, 0x00,
0x64, 0x00, 0x73, 0x00, 0x68, 0x00, 0x69, 0x00,
0x65, 0x00, 0x6C, 0x00, 0x64, 0x00, 0x20, 0x00,
0x41, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00,
0x76, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00,
0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x4C, 0x00,
0x69, 0x00, 0x62, 0x00, 0x72, 0x00, 0x61, 0x00,
0x72, 0x00, 0x79, 0x00
}, GetFileVersion, "SolidShield Core.dll"),
if (companyName.Contains("solidshield") || companyName.Contains("tages"))
return $"SolidShield Core.dll {Utilities.GetFileVersion(file)}" + (includePosition ? $" (Index {position})" : string.Empty);
}
// (char)0xEF + (char)0xBE + (char)0xAD + (char)0xDE
new Matcher(new byte?[] { 0xEF, 0xBE, 0xAD, 0xDE }, GetExeWrapperVersion, "SolidShield"),
// (char)0xEF + (char)0xBE + (char)0xAD + (char)0xDE
check = new byte?[] { };
if (fileContent.FirstPosition(check, out position))
{
var id1 = new ArraySegment<byte>(fileContent, position + 5, 3);
var id2 = new ArraySegment<byte>(fileContent, position + 16, 4);
// A + (char)0x00 + c + (char)0x00 + t + (char)0x00 + i + (char)0x00 + v + (char)0x00 + a + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + M + (char)0x00 + a + (char)0x00 + n + (char)0x00 + a + (char)0x00 + g + (char)0x00 + e + (char)0x00 + r + (char)0x00
new Matcher(new byte?[]
{
0x41, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00,
0x76, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00,
0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x4d, 0x00,
0x61, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x67, 0x00,
0x65, 0x00, 0x72, 0x00
}, GetFileVersion, "SolidShield Activation Manager Module"),
if (id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 }) && id2.SequenceEqual(new byte[] { 0x00, 0x10, 0x00, 0x00 }))
return "SolidShield 1 (SolidShield EXE Wrapper)" + (includePosition ? $" (Index {position})" : string.Empty);
else if (id1.SequenceEqual(new byte[] { 0x2E, 0x6F, 0x26 }) && id2.SequenceEqual(new byte[] { 0xDB, 0xC5, 0x20, 0x3A, 0xB9 }))
return "SolidShield 2 (SolidShield v2 EXE Wrapper)" + (includePosition ? $" (Index {position})" : string.Empty); // TODO: Verify against other SolidShield 2 discs
}
// dvm.dll
new Matcher(new byte?[] { 0x64, 0x76, 0x6D, 0x2E, 0x64, 0x6C, 0x6C }, "SolidShield EXE Wrapper"),
// "A" + (char)0x00 + "c" + (char)0x00 + "t" + (char)0x00 + "i" + (char)0x00 + "v" + (char)0x00 + "a" + (char)0x00 + "t" + (char)0x00 + "i" + (char)0x00 + "o" + (char)0x00 + "n" + (char)0x00 + " " + (char)0x00 + "M" + (char)0x00 + "a" + (char)0x00 + "n" + (char)0x00 + "a" + (char)0x00 + "g" + (char)0x00 + "e" + (char)0x00 + "r"
check = new byte?[] { 0x41, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72 };
if (fileContent.FirstPosition(check, out position))
{
string companyName = string.Empty;
if (file != null)
companyName = FileVersionInfo.GetVersionInfo(file).CompanyName.ToLower();
// Placeholder for the complex SolidShield + TAGES check
if (companyName.Contains("solidshield") || companyName.Contains("tages"))
return $"SolidShield Activation Manager Module {Utilities.GetFileVersion(file)}" + (includePosition ? $" (Index {position})" : string.Empty);
}
// Solidshield
new Matcher(new byte?[]
{
0x53, 0x6F, 0x6C, 0x69, 0x64, 0x73, 0x68, 0x69,
0x65, 0x6C, 0x64
}, GetVersion, "SolidShield"),
// dvm.dll
check = new byte?[] { 0x64, 0x76, 0x6D, 0x2E, 0x64, 0x6C, 0x6C };
if (fileContent.FirstPosition(check, out position))
return $"SolidShield EXE Wrapper" + (includePosition ? $" (Index {position})" : string.Empty);
// B + (char)0x00 + I + (char)0x00 + N + (char)0x00 + (char)0x7 + (char)0x00 + I + (char)0x00 + D + (char)0x00 + R + (char)0x00 + _ + (char)0x00 + S + (char)0x00 + G + (char)0x00 + T + (char)0x00
new Matcher(new byte?[]
{
0x42, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x07, 0x00,
0x49, 0x00, 0x44, 0x00, 0x52, 0x00, 0x5F, 0x00,
0x53, 0x00, 0x47, 0x00, 0x54, 0x00
}, "SolidShield"),
};
string firstMatch = MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
if (firstMatch != null)
return firstMatch;
// (char)0xAD + (char)0xDE + (char)0xFE + (char)0xCA
check = new byte?[] { 0xAD, 0xDE, 0xFE, 0xCA };
if (fileContent.FirstPosition(check, out position))
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);
@@ -101,16 +114,6 @@ namespace BurnOutSharp.ProtectionType
}
}
// "Solidshield"
check = new byte?[] { 0x53, 0x6F, 0x6C, 0x69, 0x64, 0x73, 0x68, 0x69, 0x65, 0x6C, 0x64 };
if (fileContent.FirstPosition(check, out position))
return $"SolidShield {GetVersion(fileContent, position)}" + (includePosition ? $" (Index {position})" : string.Empty);
// "B" + (char)0x00 + "I" + (char)0x00 + "N" + (char)0x00 + (char)0x7 + (char)0x00 + "I" + (char)0x00 + "D" + (char)0x00 + "R" + (char)0x00 + "_" + (char)0x00 + "S" + (char)0x00 + "G" + (char)0x00 + "T" + (char)0x0
check = new byte?[] { 0x42, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x07, 0x00, 0x49, 0x00, 0x44, 0x00, 0x52, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x47, 0x00, 0x54, 0x00 };
if (fileContent.FirstPosition(check, out position))
return "SolidShield" + (includePosition ? $" (Index {position})" : string.Empty);
return null;
}
@@ -143,7 +146,32 @@ namespace BurnOutSharp.ProtectionType
return null;
}
private static string GetVersion(byte[] fileContent, int position)
public static string GetExeWrapperVersion(string file, byte[] fileContent, int position)
{
var id1 = new ArraySegment<byte>(fileContent, position + 5, 3);
var id2 = new ArraySegment<byte>(fileContent, position + 16, 4);
if (id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 }) && id2.SequenceEqual(new byte[] { 0x00, 0x10, 0x00, 0x00 }))
return "1 (SolidShield EXE Wrapper)";
else if (id1.SequenceEqual(new byte[] { 0x2E, 0x6F, 0x26 }) && id2.SequenceEqual(new byte[] { 0xDB, 0xC5, 0x20, 0x3A, 0xB9 }))
return "2 (SolidShield v2 EXE Wrapper)"; // TODO: Verify against other SolidShield 2 discs
return null;
}
public static string GetFileVersion(string file, byte[] fileContent, int position)
{
string companyName = string.Empty;
if (file != null)
companyName = FileVersionInfo.GetVersionInfo(file).CompanyName.ToLower();
if (companyName.Contains("solidshield") || companyName.Contains("tages"))
return Utilities.GetFileVersion(file);
return null;
}
public static string GetVersion(string file, byte[] fileContent, int position)
{
int index = position + 12; // Begin reading after "Solidshield"
char version = (char)fileContent[index];

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
@@ -47,22 +48,25 @@ namespace BurnOutSharp.ProtectionType
return $"StarForce {Utilities.GetFileVersion(file)}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
}
// ".sforce"
check = new byte?[] { 0x2E, 0x73, 0x66, 0x6F, 0x72, 0x63, 0x65 };
if (fileContent.FirstPosition(check, out position))
return "StarForce 3-5" + (includePosition ? $" (Index {position})" : string.Empty);
var matchers = new List<Matcher>
{
// .sforce
new Matcher(new byte?[] { 0x2E, 0x73, 0x66, 0x6F, 0x72, 0x63, 0x65 }, "StarForce 3-5"),
// ".brick"
check = new byte?[] { 0x2E, 0x62, 0x72, 0x69, 0x63, 0x6B };
if (fileContent.FirstPosition(check, out position))
return "StarForce 3-5" + (includePosition ? $" (Index {position})" : string.Empty);
// .brick
new Matcher(new byte?[] { 0x2E, 0x62, 0x72, 0x69, 0x63, 0x6B }, "StarForce 3-5"),
// "P" + (char)0x00 + "r" + (char)0x00 + "o" + (char)0x00 + "t" + (char)0x00 + "e" + (char)0x00 + "c" + (char)0x00 + "t" + (char)0x00 + "e" + (char)0x00 + "d" + (char)0x00 + " " + (char)0x00 + "M" + (char)0x00 + "o" + (char)0x00 + "d" + (char)0x00 + "u" + (char)0x00 + "l" + (char)0x00 + "e"
check = new byte?[] { 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x65 };
if (fileContent.FirstPosition(check, out position))
return "StarForce 5" + (includePosition ? $" (Index {position})" : string.Empty);
// P + (char)0x00 + r + (char)0x00 + o + (char)0x00 + t + (char)0x00 + e + (char)0x00 + c + (char)0x00 + t + (char)0x00 + e + (char)0x00 + d + (char)0x00 + + (char)0x00 + M + (char)0x00 + o + (char)0x00 + d + (char)0x00 + u + (char)0x00 + l + (char)0x00 + e + (char)0x00
new Matcher(new byte?[]
{
0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x74, 0x00,
0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x65, 0x00,
0x64, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00,
0x64, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x65, 0x00
}, "StarForce 5"),
};
return null;
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
/// <inheritdoc/>

View File

@@ -2,35 +2,39 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
// TODO: Figure out how to use GetContentMatches here
public class Tages : IContentCheck, IPathCheck
{
/// <inheritdoc/>
public string CheckContents(string file, byte[] fileContent, bool includePosition = false)
{
// "protected-tages-runtime.exe"
byte?[] check = new byte?[] { 0x70, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x2D, 0x74, 0x61, 0x67, 0x65, 0x73, 0x2D, 0x72, 0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x2E, 0x65, 0x78, 0x65 };
if (fileContent.FirstPosition(check, out int position))
return $"TAGES {Utilities.GetFileVersion(file)}" + (includePosition ? $" (Index {position})" : string.Empty);
// "tagesprotection.com"
check = new byte?[] { 0x74, 0x61, 0x67, 0x65, 0x73, 0x70, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x2E, 0x63, 0x6F, 0x6D };
if (fileContent.FirstPosition(check, out position))
return $"TAGES {Utilities.GetFileVersion(file)}" + (includePosition ? $" (Index {position})" : string.Empty);
// (char)0xE8 + "u" + (char)0x00 + (char)0x00 + (char)0x00 + (char)0xE8
check = new byte?[] { 0xE8, 0x75, 0x00, 0x00, 0x00, 0xE8 };
if (fileContent.FirstPosition(check, out position))
var matchers = new List<Matcher>
{
// (char)0xFF + (char)0xFF + "h"
if (new ArraySegment<byte>(fileContent, --position + 8, 3).SequenceEqual(new byte[] { 0xFF, 0xFF, 0x68 })) // TODO: Verify this subtract
return $"TAGES {GetVersion(fileContent, position)}" + (includePosition ? $" (Index {position})" : string.Empty);
}
// protected-tages-runtime.exe
new Matcher(new byte?[]
{
0x70, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74, 0x65,
0x64, 0x2D, 0x74, 0x61, 0x67, 0x65, 0x73, 0x2D,
0x72, 0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x2E,
0x65, 0x78, 0x65
}, Utilities.GetFileVersion, "TAGES"),
return null;
// tagesprotection.com
new Matcher(new byte?[]
{
0x74, 0x61, 0x67, 0x65, 0x73, 0x70, 0x72, 0x6F,
0x74, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x2E,
0x63, 0x6F, 0x6D
}, Utilities.GetFileVersion, "TAGES"),
// (char)0xE8 + u + (char)0x00 + (char)0x00 + (char)0x00 + (char)0xE8
new Matcher(new byte?[] { 0xE8, 0x75, 0x00, 0x00, 0x00, 0xE8 }, GetVersion, "TAGES"),
};
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
/// <inheritdoc/>
@@ -90,6 +94,15 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetVersion(string file, byte[] fileContent, int position)
{
// (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);
return null;
}
private static string GetVersion(byte[] fileContent, int position)
{
switch (fileContent[position + 7])

View File

@@ -4,46 +4,32 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
// TODO: Figure out how to use GetContentMatches here
public class VOBProtectCDDVD : IContentCheck, IPathCheck
{
/// <inheritdoc/>
public string CheckContents(string file, byte[] fileContent, bool includePosition = false)
{
// "VOB ProtectCD"
byte?[] check = new byte?[] { 0x56, 0x4F, 0x42, 0x20, 0x50, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74, 0x43, 0x44 };
if (fileContent.FirstPosition(check, out int position))
return $"VOB ProtectCD/DVD {GetOldVersion(fileContent, --position)}" + (includePosition ? $" (Index {position})" : string.Empty); // TODO: Verify this subtract
// "DCP-BOV" + (char)0x00 + (char)0x00
check = new byte?[] { 0x44, 0x43, 0x50, 0x2D, 0x42, 0x4F, 0x56, 0x00, 0x00 };
if (fileContent.FirstPosition(check, out position))
var matchers = new List<Matcher>
{
string version = GetVersion(fileContent, --position); // TODO: Verify this subtract
if (version.Length > 0)
return $"VOB ProtectCD/DVD {version}" + (includePosition ? $" (Index {position})" : string.Empty);
version = SearchProtectDiscVersion(file, fileContent);
if (version.Length > 0)
// VOB ProtectCD
new Matcher(new byte?[]
{
if (version.StartsWith("2"))
version = $"6{version.Substring(1)}";
0x56, 0x4F, 0x42, 0x20, 0x50, 0x72, 0x6F, 0x74,
0x65, 0x63, 0x74, 0x43, 0x44
}, GetOldVersion, "VOB ProtectCD/DVD"),
return $"VOB ProtectCD/DVD {version}" + (includePosition ? $" (Index {position})" : string.Empty);
}
// DCP-BOV + (char)0x00 + (char)0x00
new Matcher(new byte?[] { 0x44, 0x43, 0x50, 0x2D, 0x42, 0x4F, 0x56, 0x00, 0x00 }, GetVersion, "VOB ProtectCD/DVD"),
return $"VOB ProtectCD/DVD 5.9-6.0 {GetBuild(fileContent, position)}" + (includePosition ? $" (Index {position})" : string.Empty);
}
// .vob.pcd
new Matcher(new byte?[] { 0x2E, 0x76, 0x6F, 0x62, 0x2E, 0x70, 0x63, 0x64 }, "VOB ProtectCD"),
};
// ".vob.pcd"
check = new byte?[] { 0x2E, 0x76, 0x6F, 0x62, 0x2E, 0x70, 0x63, 0x64 };
if (fileContent.FirstPosition(check, out position))
return "VOB ProtectCD" + (includePosition ? $" (Index {position})" : string.Empty);
return null;
return MatchUtil.GetFirstContentMatch(file, fileContent, matchers, includePosition);
}
/// <inheritdoc/>
@@ -64,6 +50,34 @@ namespace BurnOutSharp.ProtectionType
return null;
}
public static string GetOldVersion(string file, byte[] fileContent, int position)
{
position--; // 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]}";
return "old";
}
public static string GetVersion(string file, byte[] fileContent, int position)
{
string version = GetVersion(fileContent, --position); // TODO: Verify this subtract
if (version.Length > 0)
return version;
version = SearchProtectDiscVersion(file, fileContent);
if (version.Length > 0)
{
if (version.StartsWith("2"))
version = $"6{version.Substring(1)}";
return version;
}
return $"5.9-6.0 {GetBuild(fileContent, position)}";
}
private static string GetBuild(byte[] fileContent, int position)
{
if (!char.IsNumber((char)fileContent[position - 13]))
@@ -73,15 +87,6 @@ namespace BurnOutSharp.ProtectionType
return $" (Build {build})";
}
private static string GetOldVersion(byte[] fileContent, int position)
{
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]}";
return "old";
}
private static string GetVersion(byte[] fileContent, int position)
{
if (fileContent[position - 2] == 5)