Skip to content
Merged
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 141 additions & 7 deletions BinaryObjectScanner/Protection/SecuROM.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Text;
using BinaryObjectScanner.Interfaces;
Expand All @@ -21,13 +21,14 @@
if (paModule != null)
return paModule;

// Get the matrosch section, if it exists
if (exe.ContainsSection("matrosch", exact: true))
return $"SecuROM Matroschka Package";
// Check if executable contains a SecuROM Matroschka Package

// Get the rcpacker section, if it exists
if (exe.ContainsSection("rcpacker", exact: true))
return $"SecuROM Release Control";
if (exe.MatroschkaPackage != null)
{
var matroschka = CheckMatroschkaPackage(exe, includeDebug);
if (matroschka != null)
return matroschka;
}

if (exe.ContainsSection(".dsstext", exact: true))
return $"SecuROM 8.03.03+";
Expand Down Expand Up @@ -341,5 +342,138 @@

return null;
}

/// <summary>
/// Helper method to run checks on a SecuROM Matroschka Package
/// </summary>
private static string? CheckMatroschkaPackage(PortableExecutable exe, bool includeDebug)
{
var matroschka = exe.MatroschkaPackage;
if (matroschka == null)
return null;

// Check for all 0x00 required, as at least one known non-RC matroschka has the field, just empty.
if (matroschka.KeyHexString == null || matroschka.KeyHexString == "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
return "SecuROM Matroschka Package";

// TODO: I know this reads like debug output, but this should never happen, so I think I'd always want it there?
if (matroschka.Entries == null)
return "SecuROM Matroschka Package - No Entries? Please report";

var entry = matroschka.Entries[1];

// TODO: I know this reads like debug output, but this should never happen, so I think I'd always want it there?
if (entry.MD5 == null)
return "SecuROM Matroschka Package - No MD5? Please report";

string md5String = BitConverter.ToString(entry.MD5!);
md5String = md5String.ToUpperInvariant().Replace("-", string.Empty);

// Check if encrypted executable is known via hash
string gameName;
var fileData = matroschka.ReadFileData(entry, includeDebug); // Not used yet, but will be in the future

if (MatroschkaHashDictionary.TryGetValue(md5String, out gameName))

Check warning on line 376 in BinaryObjectScanner/Protection/SecuROM.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 376 in BinaryObjectScanner/Protection/SecuROM.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 376 in BinaryObjectScanner/Protection/SecuROM.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 376 in BinaryObjectScanner/Protection/SecuROM.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 376 in BinaryObjectScanner/Protection/SecuROM.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 376 in BinaryObjectScanner/Protection/SecuROM.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 376 in BinaryObjectScanner/Protection/SecuROM.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 376 in BinaryObjectScanner/Protection/SecuROM.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 376 in BinaryObjectScanner/Protection/SecuROM.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 376 in BinaryObjectScanner/Protection/SecuROM.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.
{
// Returning "SecuROM Matroschka Package" technically redundant since implied.
// Since non-debug is more common, return first
if (!includeDebug)
return "SecuROM Release Control";

// TODO: I'd like to have this debug output be the normal output, but I assume I'm not allowed to do that
return $"SecuROM Release Control - {gameName}";
}

// If not known, check if encrypted executable is likely an alt signing of a known executable
// Filetime could be checked here, but if it was signed at a different time, the time will vary anyways
var readPathBytes = entry.Path;
if (readPathBytes == null)
readPathBytes = [];

string? pathName;
if (MatroschkaSizeFilenameDictionary.TryGetValue(entry.Size, out pathName) && pathName == Encoding.ASCII.GetString(readPathBytes).TrimEnd('\0'))
return $"SecuROM Release Control - Unknown possible alt executable of size {entry.Size}, please report to us on Github!";

var readPathName = Encoding.ASCII.GetString(readPathBytes);
return $"SecuROM Release Control - Unknown executable {exe.Filename},{readPathName},{md5String},{entry.Size}, PLEASE REPORT ON GITHUB IMMEDIATELY!!!";
}

// Matches hash of the Release Control-encrypted executable to known hashes
public static readonly Dictionary<string, string> MatroschkaHashDictionary = new Dictionary<string, string>()
{ // Allegedly, some version of Runaway: A Twist of Fate has RC
{"C6DFF6B08EE126893840E107FD4EC9F6", "Alice - Madness Returns (USA)+(Europe)"},
{"D7703D32B72185358D58448B235BD55E", "Arcania - Gothic 4 - Not in redump yet"},
{"FAF6DD75DDB335101CB77A714793DC28", "Batman - Arkham City - Game of the Year Edition (UK)"},
{"77999579EE4378BDFAC9438CC9CDB44E", "Batman - Arkham City (USA)+(Europe)"},
{"73114CF3DEEDD0FA2BF52ACB70B048BC", "Battlefield - Bad Company 2 (GFWM)"},
{"56C23D930F885BA5BF026FEABFC31856", "Battlefield 3 (USA)+(Europe, Asia)"},
{"631C0ACE596722488E3393BD1AFCE731", "Battlefield 3 (Russia)"},
{"6E481CDEBDB30B8889340CEC3300C931", "Battlefield 3 (UK)"},
{"C5AB3931A3CBB0141CC5A4638C391F4F", "BioShock 2 (Argentina)+(Europe, Australia)+(Europe)+(Europe) (Alt)+(Netherlands)+(USA) - Multiplayer executable"},
{"73DB35419A651CB69E78A641BBC88A4C", "BioShock 2 (Argentina)+(Europe, Australia)+(Europe)+(Europe) (Alt)+(Netherlands)+(USA) - Singleplayer executable"},
{"E5D63D369023A1D1074E7B13952FA0F2", "BioShock 2 (Russia) - Multiplayer executable"},
{"C39F3BCB74EA8E1215D39AC308F64229", "BioShock 2 (Russia) - Singleplayer executable"},
{"3C340B2D4DA25039C136FEE1DC2DDE17", "Borderlands (USA)+(Europe) (En,Fr,De,Es,It)"},
{"D35122E0E3F7B35C98BEFD706C260F83", "Crysis Warhead (Europe)+(Russia)+(USA)+(USA) (Alt)"},
{"D9254D3353AB229806A806FCFCEABDBD", "Crysis Warhead (Japan)"},
{"D69798C9198A6DB6A265833B350AC544", "Crysis Warhead (Turkey)"},
{"9F574D56F1A4D7847C6A258DC2AF61A5", "Crysis Wars (Europe)+(Japan)+(Russia)+(Turkey)+(USA)+(USA) (Rerelease)"},
{"C200ABC342A56829A5356AA0BEA5F2DF", "Dead Space 2 (Europe)+(Russia)+(USA)"},
{"81B3415AF21C8691A1CD55A422BA64D5", "Disney TRON - Evolution (Europe) (En,Fr,De,Es,It,Nl)"},
{"DF9609EDE95A1F89F7A39A08778CC3B8", "Disney Tron - Evolution (Europe) (Pl,Cs)"},
{"B8698C7C05D7F9E049DC038B9868FCF7", "Disney TRON - Evolution (Russia) (En,Ru)"},
{"0D5800F94643633CD3F025CFFD968DF2", "Dragon Age II (Europe)+(USA) - PC executable"},
{"3F1AFA4783F9001AACF0379A2A432A13", "Dragon Age II (Europe)+(USA) - Mac executable"},
{"530A3EB454570EEE5519ABE6BAE0187C", "Far Cry 2 (Europe)+(USA) (En,Fr,De,Es,It)"},
{"4B3B130A70F3711BFA8AF06195FE4250", "FIFA 12 (Europe)"},
{"F43F777696B0FAD3A331298C48104B31", "FIFA 13 (Europe)"},
{"1DF0E096068839C12E4B353AC50E41FA", "Grand Theft Auto - Episodes from Liberty City (Russia)"},
{"F3ADC6D08BEC42FB988F2F62B5C731FA", "Grand Theft Auto - Episodes from Liberty City (USA)"},
{"5B90D42A650A8F08095984AEE3D961B9", "Grand Theft Auto IV (Europe, Asia)+(Europe)+(Latin America)+(USA) (Rev 1)"},
{"4510F0BDD58D30D072952E225E294F9B", "Grand Theft Auto IV (USA)"},
{"2AC9616A7FE46D142F653D798EAA07FD", "Harry Potter and the Deathly Hallows Part 2 (GFWM)"},
{"AE144755FB12062780E4E4CCD29B5296", "Kingdoms of Amalur - Reckoning (Germany)"},
{"6E4AB6416D91F85954150BC50D02688E", "Kingdoms of Amalur - Reckoning (USA) (En,Fr,Es,It,Nl)"},
{"935103B1600F1C743AF892A0DD761913", "Mass Effect 2 (GFWM)"},
{"EEB2AE163AEEF6BE54C5A9BDD38C600E", "Mass Effect 3 (Europe, Australia)+(USA)"},
{"2D08B73217B722A4F9E01523F07E118E", "Mass Effect 3 (UK)"},
{"4EA3CE0670DECD0A74FA312714C22025", "Need for Speed - The Run (Europe)"},
{"88AB0D4A4EE7867F740AD063400FCDB5", "Need for Speed - The Run (Russia)"},
{"EAD8E224D0F44706BA92BD9B27FEBA7D", "Need for Speed - The Run (USA)"},
{"316FF217BD129F9EEBD05A321A8FBE60", "Syndicate (USA)+(Europe) (En,Fr,De,Es,It,Ru)"},
};

// If hash isn't currently known, check size and pathname of the encrypted executable to determine if alt or entirely missing
public static readonly Dictionary<uint, string> MatroschkaSizeFilenameDictionary = new Dictionary<uint, string>()
{
{4646091, "hp8.aec"},
{5124592, "output\\LaunchGTAIV.aec"},
{5445032, "output\\Crysis.aec"},
{5531004, "output\\FarCry2.aec"},
{6716108, "LaunchEFLC.aec"},
{6728396, "./Bioshock2Launcher.aec"},
{6732492, "./BioShock2Launcher.aec"},
{7150283, "GridGameLauncher.aec"},
{7154379, "GridGameLauncher.aec"},
{8705763, "temp0.aec"},
{12137051, "dragonage2.aec"},
{12896904, "output\\crysis.aec"},
{12917384, "output\\crysis.aec"},
{12925576, "output\\crysis.aec"},
{16415836, "output\\MassEffect2.aec"},
{17199339, "AliceMadnessReturns.aec"},
{22357747, "MassEffect3.aec"},
{23069931, "fifa.aec"},
{25823091, "Arcania.aec"},
{27564780, "output\\BFBC2Game.aec"},
{30470419, "temp0.aec"},
{32920811, "temp0.aec"},
{35317996, "output\\ShippingPC-WillowGame-SecuROM.aec"},
{35610875, "temp0.aec"},
{37988075, "temp0.aec"},
{43612419, "BatmanAC.aec"},
{45211355, "BatmanAC.aec"},
{48093043, "deadspace_f.aec"},
};
}
}