2020-09-10 21:10:32 -07:00
using System ;
2023-03-13 16:17:21 -04:00
using System.Collections.Generic ;
2020-09-10 21:10:32 -07:00
using System.IO ;
using System.Text ;
2023-03-13 16:17:21 -04:00
using BinaryObjectScanner.Interfaces ;
2020-09-10 21:10:32 -07:00
2023-03-13 16:17:21 -04:00
namespace BinaryObjectScanner.FileType
2020-09-10 21:10:32 -07:00
{
2022-12-08 21:32:52 -08:00
/// <summary>
/// Various generic textfile formats
/// </summary>
2023-03-13 16:17:21 -04:00
public class Textfile : IDetectable
2020-09-10 21:10:32 -07:00
{
2021-02-26 09:26:23 -08:00
/// <inheritdoc/>
2023-09-17 00:18:04 -04:00
public string? Detect ( string file , bool includeDebug )
2021-02-26 09:26:23 -08:00
{
if ( ! File . Exists ( file ) )
return null ;
2023-12-13 15:52:03 -05:00
using var fs = File . Open ( file , FileMode . Open , FileAccess . Read , FileShare . ReadWrite ) ;
2023-11-22 12:22:01 -05:00
return Detect ( fs , file , includeDebug ) ;
2021-02-26 09:26:23 -08:00
}
/// <inheritdoc/>
2023-09-17 00:18:04 -04:00
public string? Detect ( Stream stream , string file , bool includeDebug )
2020-09-10 21:10:32 -07:00
{
2021-02-26 09:26:23 -08:00
// Files can be protected in multiple ways
2023-03-13 16:17:21 -04:00
var protections = new List < string > ( ) ;
2020-09-10 21:10:32 -07:00
try
{
// Load the current file content
2023-09-17 23:11:32 -04:00
var fileContent = string . Empty ;
2023-11-22 12:22:01 -05:00
#if NET20 | | NET35 | | NET40
2023-11-14 16:10:10 -05:00
using ( var sr = new StreamReader ( stream , Encoding . Default , true , 1024 * 1024 ) )
#else
2020-11-03 14:57:23 -08:00
using ( var sr = new StreamReader ( stream , Encoding . Default , true , 1024 * 1024 , true ) )
2023-11-14 16:10:10 -05:00
#endif
2020-09-10 21:10:32 -07:00
{
fileContent = sr . ReadToEnd ( ) ;
}
2022-08-13 21:03:27 -06:00
// 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." ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "AegiSoft License Manager" ) ;
2022-08-13 21:03:27 -06:00
2020-09-10 21:10:32 -07:00
// CD-Key
2020-11-03 14:41:05 -08:00
if ( fileContent . Contains ( "a valid serial number is required" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "CD-Key / Serial" ) ;
2020-11-03 14:41:05 -08:00
else if ( fileContent . Contains ( "serial number is located" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "CD-Key / Serial" ) ;
2023-02-07 08:00:04 -07:00
// Found in "Setup.Ins" ("Word Point 2002" in IA item "advantage-language-french-beginner-langmaster-2005").
else if ( fileContent . Contains ( "Please enter a valid registration number" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "CD-Key / Serial" ) ;
2022-11-06 22:30:59 -07:00
2024-07-12 10:35:26 -06:00
// Channelware
// Found in "README.TXT" in Redump entry 116358.
if ( fileContent . Contains ( "This application is a Channelware-activated product." ) )
protections . Add ( "Channelware" ) ;
// Found in "Swr.dat" in the "TOYSTORY" installation folder from Redump entry 12354.
if ( fileContent . Contains ( "cwsw.com/authts" ) )
protections . Add ( "Channelware" ) ;
2024-01-25 22:19:16 -07:00
// CopyKiller
// Found in "autorun.dat" in CopyKiller versions 3.62 and 3.64.
if ( fileContent . Contains ( "CopyKiller CD-Protection V3.6x" ) )
protections . Add ( "CopyKiller V3.62-V3.64" ) ;
// Found in "autorun.dat" in CopyKiller versions 3.99 and 3.99a.
else if ( fileContent . Contains ( "CopyKiller V4 CD / DVD-Protection" ) )
protections . Add ( "CopyKiller V3.99+" ) ;
// Found in "engine.wzc" in CopyKiller versions 3.62 and 3.64.
else if ( fileContent . Contains ( "CopyKiller V3.6x Protection Engine" ) )
protections . Add ( "CopyKiller V3.62-V3.64" ) ;
// Found in "engine.wzc" in CopyKiller versions 3.99 and 3.99a.
else if ( fileContent . Contains ( "CopyKiller V3.99x Protection Engine" ) )
2024-12-02 11:07:01 -05:00
protections . Add ( "CopyKiller V3.99+" ) ;
2024-01-25 22:19:16 -07:00
2022-11-06 22:30:59 -07:00
// Freelock
// Found in "FILE_ID.DIZ" distributed with Freelock.
if ( fileContent . Contains ( "FREELOCK 1.0" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "Freelock 1.0" ) ;
2022-11-06 22:30:59 -07:00
else if ( fileContent . Contains ( "FREELOCK 1.2" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "Freelock 1.2" ) ;
2022-11-06 22:30:59 -07:00
else if ( fileContent . Contains ( "FREELOCK 1.2a" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "Freelock 1.2a" ) ;
2022-11-06 22:30:59 -07:00
else if ( fileContent . Contains ( "FREELOCK 1.3" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "Freelock 1.3" ) ;
2022-11-06 22:30:59 -07:00
else if ( fileContent . Contains ( "FREELOCK" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "Freelock" ) ;
2020-11-03 14:41:05 -08:00
2022-07-27 14:06:52 -06:00
// MediaCloQ
if ( fileContent . Contains ( "SunnComm MediaCloQ" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "MediaCloQ" ) ;
2022-07-27 14:06:52 -06:00
else if ( fileContent . Contains ( "http://download.mediacloq.com/" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "MediaCloQ" ) ;
2022-07-27 14:06:52 -06:00
else if ( fileContent . Contains ( "http://www.sunncomm.com/mediacloq/" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "MediaCloQ" ) ;
2022-07-27 14:06:52 -06:00
2020-11-03 14:41:05 -08:00
// MediaMax
if ( fileContent . Contains ( "MediaMax technology" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "MediaMax CD-3" ) ;
2022-06-29 15:28:46 -06:00
else if ( fileContent . Contains ( "exclusive Cd3 technology" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "MediaMax CD-3" ) ;
2022-06-29 15:28:46 -06:00
else if ( fileContent . Contains ( "<PROTECTION-VENDOR>MediaMAX</PROTECTION-VENDOR>" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "MediaMax CD-3" ) ;
2022-06-29 15:28:46 -06:00
else if ( fileContent . Contains ( "MediaMax(tm)" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "MediaMax CD-3" ) ;
2021-07-01 21:51:40 -06:00
2022-06-16 23:13:02 -06:00
// phenoProtect
2024-07-04 20:16:11 -06:00
// Found in Redump entry 84082.
2022-06-16 23:13:02 -06:00
if ( fileContent . Contains ( "phenoProtect" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "phenoProtect" ) ;
2024-07-04 20:16:11 -06:00
// Additional check to minimize overmatching.
if ( fileContent . Contains ( "InstallSHIELD Software Coporation" ) )
// Found in Redump entry 102493.
if ( fileContent . Contains ( "COPYPROTECTION_FAILEDR" ) )
protections . Add ( "phenoProtect" ) ;
2022-06-16 23:13:02 -06:00
2022-11-06 22:03:23 -07:00
// Rainbow Sentinel
// Found in "SENTW95.HLP" and "SENTINEL.HLP" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]".
if ( fileContent . Contains ( "Rainbow Sentinel Driver Help" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "Rainbow Sentinel" ) ;
2024-04-07 17:15:30 -06:00
// Found in "\disc4\cad\sdcc_200.zip\DISK1\_USER1.HDR\Language_Independent_Intel_32_Files\SNTNLUSB.INF" in "CICA 32 For Windows CD-ROM (Walnut Creek) (October 1999) (Disc 4).iso" in IA item "CICA_32_For_Windows_CD-ROM_Walnut_Creek_October_1999".
if ( fileContent . Contains ( "SNTNLUSB.SvcDesc=\"Rainbow Security Device\"" ) )
protections . Add ( "Rainbow Sentinel USB Driver" ) ;
if ( fileContent . Contains ( "SntUsb95.SvcDesc=\"Rainbow Security Device\"" ) )
protections . Add ( "Rainbow Sentinel USB Driver" ) ;
2022-11-06 22:03:23 -07:00
// Found in "OEMSETUP.INF" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]".
if ( fileContent . Contains ( "Sentinel Driver Disk" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "Rainbow Sentinel" ) ;
2022-11-06 22:03:23 -07:00
2024-10-30 05:28:21 -06:00
// SafeCast
// Found in "AdlmLog.xml" in IA item game-programming-in-c-start-to-finish-2006 after installing "3dsMax8_Demo.zip".
if ( fileContent . Contains ( "<NAME>SAFECAST</NAME>" ) )
protections . Add ( "SafeCast" ) ;
2023-12-01 18:42:03 -07:00
// SafeDisc
// TODO: Add better version parsing.
// Found in "Info.plist" in Redump entries 23983, 42762, 72713, 73070, and 89603.
if ( fileContent . Contains ( "<string>com.europevisionmacro.SafeDiscDVD</string>" ) )
{
if ( fileContent . Contains ( "<string>2.90.032</string>" ) )
protections . Add ( "SafeDiscDVD for Macintosh 2.90.032" ) ;
else
protections . Add ( "SafeDiscDVD for Macintosh (Unknown Version - Please report to us on GitHub)" ) ;
}
// Found in "Info.plist" in Redump entry 89649.
if ( fileContent . Contains ( "<string>com.macrovisioneurope.SafeDiscLT</string>" ) )
{
// TODO: Investigate why "CFBundleGetInfoString" and "CFBundleShortVersionString" say version 2.70.020, but "CFBundleVersion" says version 2.70.010.
if ( fileContent . Contains ( "<string>2.70.020</string" ) )
protections . Add ( "SafeDiscLT for Macintosh 2.70.020" ) ;
else
protections . Add ( "SafeDiscLT for Macintosh (Unknown Version - Please report to us on GitHub)" ) ;
}
2022-03-14 09:03:43 -07:00
// The full line from a sample is as follows:
//
// The files securom_v7_01.dat and securom_v7_01.bak have been created during the installation of a SecuROM protected application.
//
// TODO: Use the filenames in this line to get the version out of it
// SecuROM
if ( fileContent . Contains ( "SecuROM protected application" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "SecuROM" ) ;
2022-03-14 09:03:43 -07:00
2022-06-30 17:18:12 -06:00
// Steam
if ( fileContent . Contains ( "All use of the Program is governed by the terms of the Steam Agreement as described below." ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "Steam" ) ;
2022-06-30 17:18:12 -06:00
2021-07-01 21:51:40 -06:00
// XCP
if ( fileContent . Contains ( "http://cp.sonybmg.com/xcp/" ) )
2023-03-13 16:17:21 -04:00
protections . Add ( "XCP" ) ;
2020-09-10 21:10:32 -07:00
}
2022-05-15 20:58:27 -07:00
catch ( Exception ex )
2020-09-10 21:10:32 -07:00
{
2025-07-31 09:14:21 -04:00
if ( includeDebug ) Console . Error . WriteLine ( ex ) ;
2020-09-10 21:10:32 -07:00
}
2024-12-02 11:07:01 -05:00
// Only return if there are protections found
if ( protections . Count > 0 )
return string . Join ( ";" , [ . . protections ] ) ;
return null ;
2020-09-10 21:10:32 -07:00
}
}
}