2019-09-27 23:52:24 -07:00
using System ;
2021-07-18 09:44:23 -07:00
using System.Collections.Concurrent ;
2019-09-27 23:52:24 -07:00
using System.Collections.Generic ;
using System.IO ;
2023-03-09 11:52:28 -05:00
using BinaryObjectScanner.Interfaces ;
2023-03-07 16:59:14 -05:00
using BinaryObjectScanner.Matching ;
using BinaryObjectScanner.Wrappers ;
2019-09-27 23:52:24 -07:00
namespace BurnOutSharp.ProtectionType
{
2022-05-01 17:23:00 -07:00
public class TAGES : IPathCheck , IPortableExecutableCheck
2019-09-27 23:52:24 -07:00
{
2022-03-14 11:20:11 -07:00
/// <inheritdoc/>
2022-05-01 17:17:15 -07:00
public string CheckPortableExecutable ( string file , PortableExecutable pex , bool includeDebug )
2021-09-07 21:02:19 -07:00
{
// Get the sections from the executable, if possible
var sections = pex ? . SectionTable ;
if ( sections = = null )
return null ;
2022-03-09 14:35:38 -08:00
// Known TAGES Driver Setup filenames:
// - DrvSetup.exe
// - DrvSetup_x64.exe
// - TagesSetup.exe
// - TagesSetup_x64.exe
// Known TAGES Activation Client filenames:
// - TagesClient.exe
// - TagesClient.dat (Does not always exist)
2022-04-02 16:12:23 -07:00
string name = pex . FileDescription ;
2022-08-21 20:34:59 -07:00
if ( name ? . StartsWith ( "TagesSetup" , StringComparison . OrdinalIgnoreCase ) = = true )
2022-03-09 15:00:33 -07:00
return $"TAGES Driver Setup {GetVersion(pex)}" ;
2022-08-21 20:34:59 -07:00
else if ( name ? . StartsWith ( "Tagès activation client" , StringComparison . OrdinalIgnoreCase ) = = true )
2022-03-09 15:00:33 -07:00
return $"TAGES Activation Client {GetVersion(pex)}" ;
2021-09-07 21:02:19 -07:00
2022-04-02 16:12:23 -07:00
name = pex . ProductName ;
2022-08-21 20:34:59 -07:00
if ( name ? . StartsWith ( "Application TagesSetup" , StringComparison . OrdinalIgnoreCase ) = = true )
2022-03-09 15:00:33 -07:00
return $"TAGES Driver Setup {GetVersion(pex)}" ;
2022-08-21 20:34:59 -07:00
else if ( name ? . StartsWith ( "T@GES" , StringComparison . OrdinalIgnoreCase ) = = true )
2022-03-09 15:00:33 -07:00
return $"TAGES Activation Client {GetVersion(pex)}" ;
2021-09-07 21:02:19 -07:00
2022-06-22 10:17:56 -07:00
// TODO: Add entry point check
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/Tages.2.sg
2022-12-03 22:17:48 -08:00
// Get the .data/DATA section, if it exists
var dataSectionRaw = pex . GetFirstSectionData ( ".data" ) ? ? pex . GetFirstSectionData ( "DATA" ) ;
if ( dataSectionRaw ! = null )
2022-03-15 15:05:08 -07:00
{
var matchers = new List < ContentMatchSet >
{
2022-03-17 12:13:11 -07:00
// (char)0xE8 + u + (char)0x00 + (char)0x00 + (char)0x00 + (char)0xE8 + ?? + ?? + (char)0xFF + (char)0xFF + "h"
new ContentMatchSet ( new byte? [ ] { 0xE8 , 0x75 , 0x00 , 0x00 , 0x00 , 0xE8 , null , null , 0xFF , 0xFF , 0x68 } , GetVersion , "TAGES" ) ,
2022-03-15 15:05:08 -07:00
} ;
2022-12-03 22:17:48 -08:00
string match = MatchUtil . GetFirstMatch ( file , dataSectionRaw , matchers , includeDebug ) ;
2022-03-15 15:05:08 -07:00
if ( ! string . IsNullOrWhiteSpace ( match ) )
return match ;
}
2022-03-02 08:56:26 -08:00
return null ;
2021-09-07 21:02:19 -07:00
}
2019-09-27 23:52:24 -07:00
2021-02-26 00:32:09 -08:00
/// <inheritdoc/>
2021-07-18 09:44:23 -07:00
public ConcurrentQueue < string > CheckDirectoryPath ( string path , IEnumerable < string > files )
2019-09-27 23:52:24 -07:00
{
2022-03-09 15:00:33 -07:00
var matchers = new List < PathMatchSet >
2021-03-19 15:41:49 -07:00
{
2022-06-13 01:12:34 -06:00
// So far, only known to exist in early versions of "Moto Racer 3" (Redump entries 31578 and 34669).
2022-03-09 14:35:38 -08:00
new PathMatchSet ( new List < PathMatch >
2022-03-09 15:00:33 -07:00
{
2022-03-09 14:35:38 -08:00
// d37f70489207014d7d0fbaa43b081a93e8030498
new PathMatch ( Path . Combine ( "Sys" , "Devx.sys" ) . Replace ( "\\" , "/" ) , useEndsWith : true ) ,
// a0acbc2f8e321e4f30c913c095e28af444058249
new PathMatch ( Path . Combine ( "Sys" , "VtPr.sys" ) . Replace ( "\\" , "/" ) , useEndsWith : true ) ,
// SHA-1 is variable, file size is 81,920 bytes
new PathMatch ( "Wave.aif" , useEndsWith : true ) ,
// f82339d797be6da92f5d9dadeae9025385159057
new PathMatch ( "Wave.alf" , useEndsWith : true ) ,
// 0351d0f3d4166362a1a9d838c9390a3d92945a44
new PathMatch ( "Wave.apt" , useEndsWith : true ) ,
// SHA-1 is variable, file size is 61,440 bytes
new PathMatch ( "Wave.axt" , useEndsWith : true ) ,
2022-03-09 15:00:33 -07:00
} , "TAGES" ) ,
2019-09-28 01:51:06 -07:00
2022-06-13 01:12:34 -06:00
// Currently only found in "Robocop" (Redump entry 35932).
// Found in a directory named "System", with an executable named "Setup.exe".
new PathMatchSet ( new List < PathMatch >
{
// f82339d797be6da92f5d9dadeae9025385159057
new PathMatch ( Path . Combine ( "9x" , "Tamlx.alf" ) . Replace ( "\\" , "/" ) , useEndsWith : true ) ,
// 933c004d3043863f019f5ffaf63402a30e65026c
new PathMatch ( Path . Combine ( "9x" , "Tamlx.apt" ) . Replace ( "\\" , "/" ) , useEndsWith : true ) ,
// d45745fa6b0d23fe0ee12e330ab85d5bf4e0e776
new PathMatch ( Path . Combine ( "NT" , "enodpl.sys" ) . Replace ( "\\" , "/" ) , useEndsWith : true ) ,
// f111eba05ca6e9061c557547420847d7fdee657d
new PathMatch ( Path . Combine ( "NT" , "litdpl.sys" ) . Replace ( "\\" , "/" ) , useEndsWith : true ) ,
} , "TAGES" ) ,
// Currently only known to exist in "XIII" and "Beyond Good & Evil" (Redump entries 8774-8776, 45940-45941, 18690-18693, and presumably 21320, 21321, 21323, and 36124).
2022-03-09 14:35:38 -08:00
new PathMatchSet ( new List < PathMatch >
2022-03-09 15:00:33 -07:00
{
2022-03-09 14:35:38 -08:00
new PathMatch ( "enodpl.sys" , useEndsWith : true ) ,
new PathMatch ( "ENODPL.VXD" , useEndsWith : true ) ,
new PathMatch ( "tandpl.sys" , useEndsWith : true ) ,
new PathMatch ( "TANDPL.VXD" , useEndsWith : true ) ,
2022-03-09 15:00:33 -07:00
} , "TAGES" ) ,
2022-03-09 14:35:38 -08:00
// The directory of these files has been seen to be named two different things, with two different accompanying executables in the root of the directory.
2022-06-13 01:12:34 -06:00
// In the example where the directory is named "Drivers", the executable is named "Silent.exe" (Redump entry 51763).
// In the example where the directory is named "ELBdrivers", the executable is name "ELBDrivers.exe" (Redump entry 91090).
2022-03-09 14:35:38 -08:00
// The name and file size of the included executable vary, but there should always be one here.
new PathMatchSet ( new List < PathMatch >
2022-03-09 15:00:33 -07:00
{
2022-03-09 14:35:38 -08:00
// 40826e95f3ad8031b6debe15aca052c701288e04
new PathMatch ( Path . Combine ( "9x" , "hwpsgt.vxd" ) . Replace ( "\\" , "/" ) , useEndsWith : true ) ,
// f82339d797be6da92f5d9dadeae9025385159057
new PathMatch ( Path . Combine ( "9x" , "lemsgt.vxd" ) . Replace ( "\\" , "/" ) , useEndsWith : true ) ,
// 43f407ecdc0d87a3713126b757ccaad07ade285f
new PathMatch ( Path . Combine ( "NT" , "hwpsgt.sys" ) . Replace ( "\\" , "/" ) , useEndsWith : true ) ,
// 548dd6359abbcc8c84ce346d078664eeedc716f7
new PathMatch ( Path . Combine ( "NT" , "lemsgt.sys" ) . Replace ( "\\" , "/" ) , useEndsWith : true ) ,
2022-03-09 15:00:33 -07:00
} , "TAGES" ) ,
2022-03-09 14:35:38 -08:00
2022-06-13 01:12:34 -06:00
// The following files are supposed to only be found inside the driver setup executables, and are present in at least version 5.2.0.1 (Redump entry 15976).
2022-03-09 14:35:38 -08:00
new PathMatchSet ( new PathMatch ( "ithsgt.sys" , useEndsWith : true ) , "TAGES Driver" ) ,
new PathMatchSet ( new PathMatch ( "lilsgt.sys" , useEndsWith : true ) , "TAGES Driver" ) ,
2022-06-13 01:12:34 -06:00
// The following files are supposed to only be found inside the driver setup executables in versions 5.5.0.1+.
2022-03-09 14:35:38 -08:00
new PathMatchSet ( new PathMatch ( "atksgt.sys" , useEndsWith : true ) , "TAGES Driver" ) ,
new PathMatchSet ( new PathMatch ( "lirsgt.sys" , useEndsWith : true ) , "TAGES Driver" ) ,
2022-06-13 01:12:34 -06:00
// The following files appear to be container formats for TAGES, but little is currently known about them (Redump entries 85313 and 85315).
2022-03-09 14:35:38 -08:00
new PathMatchSet ( new PathMatch ( "GameModule.elb" , useEndsWith : true ) , "TAGES/SolidShield Game Executable Container" ) ,
new PathMatchSet ( new PathMatch ( "InstallModule.elb" , useEndsWith : true ) , "TAGES/SolidShield Installer Container" ) ,
2022-06-13 01:12:34 -06:00
// Not much is known about this file, but it seems to be related to what PiD reports as "protection level: Tages BASIC" (Redump entry 85313).
2022-03-09 14:35:38 -08:00
// Seems to always be found with other KWN files.
new PathMatchSet ( new PathMatch ( "GAME.KWN" , useEndsWith : true ) , "TAGES (BASIC?)" ) ,
2022-03-09 15:00:33 -07:00
} ;
2022-12-13 12:42:55 -07:00
return MatchUtil . GetAllMatches ( files , matchers , any : false ) ;
2021-03-19 15:41:49 -07:00
}
2019-09-28 01:51:06 -07:00
2021-03-19 15:41:49 -07:00
/// <inheritdoc/>
public string CheckFilePath ( string path )
{
2022-03-09 15:00:33 -07:00
var matchers = new List < PathMatchSet >
2021-03-19 15:41:49 -07:00
{
2022-06-13 01:12:34 -06:00
// So far, only known to exist in early versions of "Moto Racer 3" (Redump entries 31578 and 34669).
2022-03-09 15:00:33 -07:00
new PathMatchSet ( new PathMatch ( "Devx.sys" , useEndsWith : true ) , "TAGES Driver" ) ,
new PathMatchSet ( new PathMatch ( "VtPr.sys" , useEndsWith : true ) , "TAGES Driver" ) ,
2022-03-09 14:35:38 -08:00
// These are removed because they can potentially overmatch
// new PathMatchSet(new PathMatch("Wave.aif", useEndsWith: true), "TAGES Driver"),
// new PathMatchSet(new PathMatch("Wave.alf", useEndsWith: true), "TAGES Driver"),
// new PathMatchSet(new PathMatch("Wave.apt", useEndsWith: true), "TAGES Driver"),
// new PathMatchSet(new PathMatch("Wave.axt", useEndsWith: true), "TAGES Driver"),
2022-06-13 01:12:34 -06:00
// Currently only found in "Robocop" (Redump entry 35932).
// Found in a directory named "System", with an executable named "Setup.exe".
new PathMatchSet ( new PathMatch ( "Tamlx.apt" , useEndsWith : true ) , "TAGES 9x Driver" ) ,
new PathMatchSet ( new PathMatch ( "Tamlx.alf" , useEndsWith : true ) , "TAGES 9x Driver" ) ,
new PathMatchSet ( new PathMatch ( "enodpl.sys" , useEndsWith : true ) , "TAGES NT Driver" ) ,
new PathMatchSet ( new PathMatch ( "litdpl.sys" , useEndsWith : true ) , "TAGES NT Driver" ) ,
// Currently only known to exist in "XIII" and "Beyond Good & Evil" (Redump entries 8774-8776, 45940-45941, 18690-18693, and presumably 21320, 21321, 21323, and 36124).
2022-03-09 15:00:33 -07:00
new PathMatchSet ( new PathMatch ( "enodpl.sys" , useEndsWith : true ) , "TAGES NT Driver" ) ,
2022-03-09 14:35:38 -08:00
new PathMatchSet ( new PathMatch ( "ENODPL.VXD" , useEndsWith : true ) , "TAGES 9x Driver" ) ,
2022-03-09 15:00:33 -07:00
new PathMatchSet ( new PathMatch ( "tandpl.sys" , useEndsWith : true ) , "TAGES NT Driver" ) ,
2022-03-09 14:35:38 -08:00
new PathMatchSet ( new PathMatch ( "TANDPL.VXD" , useEndsWith : true ) , "TAGES 9x Driver" ) ,
// The directory of these files has been seen to be named two different things, with two different accompanying executables in the root of the directory.
2022-06-13 01:12:34 -06:00
// In the example where the directory is named "Drivers", the executable is named "Silent.exe" (Redump entry 51763).
// In the example where the directory is named "ELBdrivers", the executable is name "ELBDrivers.exe" (Redump entry 91090).
2022-03-09 14:35:38 -08:00
// The name and file size of the included executable vary, but there should always be one here.
2022-03-09 15:00:33 -07:00
new PathMatchSet ( new PathMatch ( "hwpsgt.vxd" , useEndsWith : true ) , "TAGES 9x Driver" ) ,
new PathMatchSet ( new PathMatch ( "lemsgt.vxd" , useEndsWith : true ) , "TAGES 9x Driver" ) ,
new PathMatchSet ( new PathMatch ( "hwpsgt.sys" , useEndsWith : true ) , "TAGES NT Driver" ) ,
new PathMatchSet ( new PathMatch ( "lemsgt.sys" , useEndsWith : true ) , "TAGES NT Driver" ) ,
2019-09-27 23:52:24 -07:00
2022-06-13 01:12:34 -06:00
// The following files are supposed to only be found inside the driver setup executables, and are present in at least version 5.2.0.1 (Redump entry 15976).
2022-03-09 15:00:33 -07:00
new PathMatchSet ( new PathMatch ( "ithsgt.sys" , useEndsWith : true ) , "TAGES Driver" ) ,
new PathMatchSet ( new PathMatch ( "lilsgt.sys" , useEndsWith : true ) , "TAGES Driver" ) ,
2022-06-13 01:12:34 -06:00
// The following files are supposed to only be found inside the driver setup executables in versions 5.5.0.1+.
2022-03-09 15:00:33 -07:00
new PathMatchSet ( new PathMatch ( "atksgt.sys" , useEndsWith : true ) , "TAGES Driver" ) ,
new PathMatchSet ( new PathMatch ( "lirsgt.sys" , useEndsWith : true ) , "TAGES Driver" ) ,
2022-06-13 01:12:34 -06:00
// The following files appear to be container formats for TAGES, but little is currently known about them (Redump entries 85313 and 85315).
2022-03-09 15:00:33 -07:00
new PathMatchSet ( new PathMatch ( "GameModule.elb" , useEndsWith : true ) , "TAGES/SolidShield Game Executable Container" ) ,
new PathMatchSet ( new PathMatch ( "InstallModule.elb" , useEndsWith : true ) , "TAGES/SolidShield Installer Container" ) ,
2022-06-13 01:12:34 -06:00
// Not much is known about this file, but it seems to be related to what PiD reports as "protection level: Tages BASIC" (Redump entry 85313).
2022-03-09 14:35:38 -08:00
// Seems to always be found with other KWN files.
2022-03-09 15:00:33 -07:00
new PathMatchSet ( new PathMatch ( "GAME.KWN" , useEndsWith : true ) , "TAGES (BASIC?)" ) ,
} ;
return MatchUtil . GetFirstMatch ( path , matchers , any : true ) ;
}
private string GetVersion ( PortableExecutable pex )
{
2022-04-01 10:16:31 -07:00
// Check the internal versions
2023-03-09 23:19:27 -05:00
string version = pex . GetInternalVersion ( ) ;
2022-03-09 15:00:33 -07:00
if ( ! string . IsNullOrEmpty ( version ) )
return version ;
return "(Unknown Version)" ;
2019-09-27 23:52:24 -07:00
}
2021-03-22 11:43:51 -07:00
public static string GetVersion ( string file , byte [ ] fileContent , List < int > positions )
2021-03-22 11:13:14 -07:00
{
2022-03-17 12:16:41 -07:00
// TODO: Determine difference between API and BASIC
byte typeByte = fileContent [ positions [ 0 ] + 6 ] ;
byte versionByte = fileContent [ positions [ 0 ] + 7 ] ;
switch ( versionByte )
2019-09-27 23:52:24 -07:00
{
2022-03-15 23:04:10 -07:00
case 0x1E :
return "5.2" ;
2020-09-10 21:10:32 -07:00
case 0x1B :
return "5.3-5.4" ;
case 0x14 :
return "5.5.0" ;
2022-03-15 23:04:10 -07:00
case 0x04 :
2020-09-10 21:10:32 -07:00
return "5.5.2" ;
2021-03-22 16:25:40 -07:00
default :
return string . Empty ;
2019-09-27 23:52:24 -07:00
}
}
}
}