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 ;
2020-10-26 23:30:35 -07:00
using System.Text ;
2021-03-21 22:19:38 -07:00
using BurnOutSharp.Matching ;
2021-08-25 15:09:42 -07:00
using BurnOutSharp.Tools ;
2019-09-27 23:52:24 -07:00
namespace BurnOutSharp.ProtectionType
{
2021-02-26 01:26:49 -08:00
public class SecuROM : IContentCheck , IPathCheck
2019-09-27 23:52:24 -07:00
{
2021-07-17 23:40:16 -07:00
/// <inheritdoc/>
2021-08-25 19:37:32 -07:00
public List < ContentMatchSet > GetContentMatchSets ( )
2021-03-23 09:52:09 -07:00
{
2021-08-25 19:37:32 -07:00
return new List < ContentMatchSet >
2021-07-17 23:40:16 -07:00
{
// AddD + (char)0x03 + (char)0x00 + (char)0x00 + (char)0x00)
new ContentMatchSet ( new byte? [ ] { 0x41 , 0x64 , 0x64 , 0x44 , 0x03 , 0x00 , 0x00 , 0x00 } , GetV4Version , "SecuROM" ) ,
2021-03-23 09:52:09 -07:00
2021-07-17 23:40:16 -07:00
// (char)0xCA + (char)0xDD + (char)0xDD + (char)0xAC + (char)0x03
new ContentMatchSet ( new byte? [ ] { 0xCA , 0xDD , 0xDD , 0xAC , 0x03 } , GetV5Version , "SecuROM" ) ,
2021-03-23 09:52:09 -07:00
2021-07-17 23:40:16 -07:00
// .securom + (char)0xE0 + (char)0xC0
new ContentMatchSet ( new byte? [ ]
{
0x2E , 0x73 , 0x65 , 0x63 , 0x75 , 0x72 , 0x6F , 0x6D ,
0xE0 , 0xC0
} , GetV7Version , "SecuROM" ) ,
2021-03-23 09:52:09 -07:00
2021-07-17 23:40:16 -07:00
// .securom
new ContentMatchSet ( new byte? [ ] { 0x2E , 0x73 , 0x65 , 0x63 , 0x75 , 0x72 , 0x6F , 0x6D } , GetV7Version , "SecuROM" ) ,
2021-03-23 09:52:09 -07:00
2021-07-17 23:40:16 -07:00
// _and_play.dll + (char)0x00 + drm_pagui_doit
new ContentMatchSet ( new byte? [ ]
{
0x5F , 0x61 , 0x6E , 0x64 , 0x5F , 0x70 , 0x6C , 0x61 ,
0x79 , 0x2E , 0x64 , 0x6C , 0x6C , 0x00 , 0x64 , 0x72 ,
0x6D , 0x5F , 0x70 , 0x61 , 0x67 , 0x75 , 0x69 , 0x5F ,
0x64 , 0x6F , 0x69 , 0x74
} , Utilities . GetFileVersion , "SecuROM Product Activation" ) ,
2021-03-23 09:52:09 -07:00
2021-07-17 23:40:16 -07:00
// S + (char)0x00 + e + (char)0x00 + c + (char)0x00 + u + (char)0x00 + R + (char)0x00 + O + (char)0x00 + M + (char)0x00 + + (char)0x00 + P + (char)0x00 + A + (char)0x00
new ContentMatchSet ( new byte? [ ]
{
0x53 , 0x00 , 0x65 , 0x00 , 0x63 , 0x00 , 0x75 , 0x00 ,
0x52 , 0x00 , 0x4F , 0x00 , 0x4D , 0x00 , 0x20 , 0x00 ,
0x50 , 0x00 , 0x41 , 0x00
} , Utilities . GetFileVersion , "SecuROM Product Activation" ) ,
2021-07-17 23:06:11 -07:00
2021-07-17 23:40:16 -07:00
// .cms_t + (char)0x00
new ContentMatchSet ( new byte? [ ] { 0x2E , 0x63 , 0x6D , 0x73 , 0x5F , 0x74 , 0x00 } , "SecuROM 1-3" ) ,
2021-03-23 09:52:09 -07:00
2021-07-17 23:40:16 -07:00
// .cms_d + (char)0x00
new ContentMatchSet ( new byte? [ ] { 0x2E , 0x63 , 0x6D , 0x73 , 0x5F , 0x64 , 0x00 } , "SecuROM 1-3" ) ,
} ;
2021-08-25 19:37:32 -07:00
}
2021-03-23 09:52:09 -07:00
2021-08-25 19:37:32 -07:00
/// <inheritdoc/>
2021-08-25 20:26:43 -07:00
public string CheckContents ( string file , byte [ ] fileContent , bool includeDebug = false ) = > null ;
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
{
2021-03-23 10:36:14 -07:00
var matchers = new List < PathMatchSet >
2019-09-27 23:52:24 -07:00
{
2021-03-23 10:36:14 -07:00
// TODO: Verify if these are OR or AND
new PathMatchSet ( new PathMatch ( "CMS16.DLL" , useEndsWith : true ) , "SecuROM" ) ,
new PathMatchSet ( new PathMatch ( "CMS_95.DLL" , useEndsWith : true ) , "SecuROM" ) ,
new PathMatchSet ( new PathMatch ( "CMS_NT.DLL" , useEndsWith : true ) , "SecuROM" ) ,
new PathMatchSet ( new PathMatch ( "CMS32_95.DLL" , useEndsWith : true ) , "SecuROM" ) ,
new PathMatchSet ( new PathMatch ( "CMS32_NT.DLL" , useEndsWith : true ) , "SecuROM" ) ,
// TODO: Verify if these are OR or AND
new PathMatchSet ( new PathMatch ( "SINTF32.DLL" , useEndsWith : true ) , "SecuROM New" ) ,
new PathMatchSet ( new PathMatch ( "SINTF16.DLL" , useEndsWith : true ) , "SecuROM New" ) ,
new PathMatchSet ( new PathMatch ( "SINTFNT.DLL" , useEndsWith : true ) , "SecuROM New" ) ,
} ;
2021-03-23 13:35:12 -07:00
return MatchUtil . GetAllMatches ( files , matchers , any : true ) ;
2021-03-19 15:41:49 -07:00
}
/// <inheritdoc/>
public string CheckFilePath ( string path )
{
2021-03-23 10:36:14 -07:00
var matchers = new List < PathMatchSet >
2021-03-19 15:41:49 -07:00
{
2021-03-23 10:36:14 -07:00
new PathMatchSet ( new PathMatch ( "CMS16.DLL" , useEndsWith : true ) , "SecuROM" ) ,
new PathMatchSet ( new PathMatch ( "CMS_95.DLL" , useEndsWith : true ) , "SecuROM" ) ,
new PathMatchSet ( new PathMatch ( "CMS_NT.DLL" , useEndsWith : true ) , "SecuROM" ) ,
new PathMatchSet ( new PathMatch ( "CMS32_95.DLL" , useEndsWith : true ) , "SecuROM" ) ,
new PathMatchSet ( new PathMatch ( "CMS32_NT.DLL" , useEndsWith : true ) , "SecuROM" ) ,
new PathMatchSet ( new PathMatch ( "SINTF32.DLL" , useEndsWith : true ) , "SecuROM New" ) ,
new PathMatchSet ( new PathMatch ( "SINTF16.DLL" , useEndsWith : true ) , "SecuROM New" ) ,
new PathMatchSet ( new PathMatch ( "SINTFNT.DLL" , useEndsWith : true ) , "SecuROM New" ) ,
} ;
return MatchUtil . GetFirstMatch ( path , matchers , any : true ) ;
2019-09-27 23:52:24 -07:00
}
2021-03-22 11:43:51 -07:00
public static string GetV4Version ( string file , byte [ ] fileContent , List < int > positions )
2019-09-27 23:52:24 -07:00
{
2021-03-22 11:43:51 -07:00
int index = positions [ 0 ] + 8 ; // Begin reading after "AddD"
2020-09-10 21:10:32 -07:00
char version = ( char ) fileContent [ index ] ;
index + = 2 ;
2019-09-30 11:08:44 -07:00
2020-10-26 23:30:35 -07:00
string subVersion = Encoding . ASCII . GetString ( fileContent , index , 2 ) ;
2020-09-10 21:10:32 -07:00
index + = 3 ;
2020-10-26 23:30:35 -07:00
string subSubVersion = Encoding . ASCII . GetString ( fileContent , index , 2 ) ;
2020-09-10 21:10:32 -07:00
index + = 3 ;
2020-10-26 23:30:35 -07:00
string subSubSubVersion = Encoding . ASCII . GetString ( fileContent , index , 4 ) ;
2020-09-10 21:10:32 -07:00
if ( ! char . IsNumber ( version ) )
return "(very old, v3 or less)" ;
return $"{version}.{subVersion}.{subSubVersion}.{subSubSubVersion}" ;
2019-09-27 23:52:24 -07:00
}
2021-03-22 11:43:51 -07:00
public static string GetV5Version ( string file , byte [ ] fileContent , List < int > positions )
2019-09-27 23:52:24 -07:00
{
2021-03-22 11:43:51 -07:00
int index = positions [ 0 ] + 8 ; // Begin reading after "ÊÝݬ"
2020-09-10 21:10:32 -07:00
byte version = ( byte ) ( fileContent [ index ] & 0x0F ) ;
index + = 2 ;
byte [ ] subVersion = new byte [ 2 ] ;
subVersion [ 0 ] = ( byte ) ( fileContent [ index ] ^ 36 ) ;
index + + ;
subVersion [ 1 ] = ( byte ) ( fileContent [ index ] ^ 28 ) ;
index + = 2 ;
byte [ ] subSubVersion = new byte [ 2 ] ;
subSubVersion [ 0 ] = ( byte ) ( fileContent [ index ] ^ 42 ) ;
index + + ;
subSubVersion [ 0 ] = ( byte ) ( fileContent [ index ] ^ 8 ) ;
index + = 2 ;
byte [ ] subSubSubVersion = new byte [ 4 ] ;
subSubSubVersion [ 0 ] = ( byte ) ( fileContent [ index ] ^ 16 ) ;
index + + ;
subSubSubVersion [ 1 ] = ( byte ) ( fileContent [ index ] ^ 116 ) ;
index + + ;
subSubSubVersion [ 2 ] = ( byte ) ( fileContent [ index ] ^ 34 ) ;
index + + ;
subSubSubVersion [ 3 ] = ( byte ) ( fileContent [ index ] ^ 22 ) ;
if ( version = = 0 | | version > 9 )
2021-03-22 16:25:40 -07:00
return string . Empty ;
2020-09-10 21:10:32 -07:00
return $"{version}.{subVersion[0]}{subVersion[1]}.{subSubVersion[0]}{subSubVersion[1]}.{subSubSubVersion[0]}{subSubSubVersion[1]}{subSubSubVersion[2]}{subSubSubVersion[3]}" ;
2019-09-27 23:52:24 -07:00
}
2021-03-22 11:43:51 -07:00
public static string GetV7Version ( string file , byte [ ] fileContent , List < int > positions )
2019-09-27 23:52:24 -07:00
{
2020-09-10 21:10:32 -07:00
int index = 236 ;
2020-10-26 23:30:35 -07:00
byte [ ] bytes = new ReadOnlySpan < byte > ( fileContent , index , 4 ) . ToArray ( ) ;
2020-09-10 21:10:32 -07:00
//SecuROM 7 new and 8
if ( bytes [ 3 ] = = 0x5C ) // if (bytes[0] == 0xED && bytes[3] == 0x5C {
{
return $"{bytes[0] ^ 0xEA}.{bytes[1] ^ 0x2C:00}.{bytes[2] ^ 0x8:0000}" ;
}
2019-09-30 11:08:44 -07:00
2020-09-10 21:10:32 -07:00
// SecuROM 7 old
else
2019-09-27 23:52:24 -07:00
{
2020-09-10 21:10:32 -07:00
index = 122 ;
2020-10-26 23:30:35 -07:00
bytes = new ReadOnlySpan < byte > ( fileContent , index , 2 ) . ToArray ( ) ;
2020-09-10 21:10:32 -07:00
return $"7.{bytes[0] ^ 0x10:00}.{bytes[1] ^ 0x10:0000}" ; //return "7.01-7.10"
2019-09-27 23:52:24 -07:00
}
}
}
}