diff --git a/DICUI/DICUI.csproj b/DICUI/DICUI.csproj index 64a8dd6f..b0f55549 100644 --- a/DICUI/DICUI.csproj +++ b/DICUI/DICUI.csproj @@ -98,9 +98,10 @@ Designer - + + - + @@ -179,6 +180,15 @@ Always + + Always + + + Always + + + Always + \ No newline at end of file diff --git a/DICUI/External/EVORE.cs b/DICUI/External/BurnOut/EVORE.cs similarity index 99% rename from DICUI/External/EVORE.cs rename to DICUI/External/BurnOut/EVORE.cs index f8aecb83..7ddafc13 100644 --- a/DICUI/External/EVORE.cs +++ b/DICUI/External/BurnOut/EVORE.cs @@ -21,7 +21,7 @@ using System.IO; using System.Text; using System.Threading; -namespace DICUI.External +namespace DICUI.External.BurnOut { struct Section { diff --git a/DICUI/External/ProtectionFind.cs b/DICUI/External/BurnOut/ProtectionFind.cs similarity index 95% rename from DICUI/External/ProtectionFind.cs rename to DICUI/External/BurnOut/ProtectionFind.cs index 9d490319..6a479b32 100644 --- a/DICUI/External/ProtectionFind.cs +++ b/DICUI/External/BurnOut/ProtectionFind.cs @@ -21,9 +21,10 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Text; +using DICUI.External.iXcomp; using LibMSPackN; -namespace DICUI.External +namespace DICUI.External.BurnOut { public static class ProtectionFind { @@ -89,7 +90,7 @@ namespace DICUI.External /// Scan an individual file for copy protection /// /// - /// TODO: Handle archives (zip, arc, cab[is]) + /// TODO: Handle archives (zip, arc) /// TODO: Find protection mentions in text files /// TODO: Might have to work on Streams instead to later support archives /// @@ -150,9 +151,8 @@ namespace DICUI.External return "LaserLock " + GetLaserLockVersion(FileContent, --position) + " " + GetLaserLockBuild(FileContent, false); // ProtectDisc - if ((FileContent.IndexOf("HúMETINF")) > -1) + if ((position = FileContent.IndexOf("HúMETINF")) > -1) { - position--; string version = EVORE.SearchProtectDiscVersion(file); if (version.Length > 0) { @@ -167,11 +167,9 @@ namespace DICUI.External } } - if ((FileContent.IndexOf("ACE-PCD")) > -1) + if ((position = FileContent.IndexOf("ACE-PCD")) > -1) { - position--; - string version; - version = EVORE.SearchProtectDiscVersion(file); + string version = EVORE.SearchProtectDiscVersion(file); if (version.Length > 0) { string[] astrVersionArray = version.Split('.'); @@ -182,6 +180,14 @@ namespace DICUI.External } // SafeDisc / SafeCast + if ((position = FileContent.IndexOf("BoG_ *90.0&!! Yy>")) > -1) + { + if (FileContent.IndexOf("product activation library") > 0) + return "SafeCast " + GetSafeDiscVersion(file, position); + else + return "SafeDisc " + GetSafeDiscVersion(file, position); + } + if (FileContent.Contains((char)0x00 + (char)0x00 + "BoG_") || FileContent.Contains("stxt774") || FileContent.Contains("stxt371")) @@ -193,15 +199,6 @@ namespace DICUI.External return "SafeDisc 3.20-4.xx (version removed)"; } - if ((FileContent.IndexOf("BoG_ *90.0&!! Yy>")) > -1) - { - position--; - if (FileContent.IndexOf("product activation library") > 0) - return "SafeCast " + GetSafeDiscVersion(file, position); - else - return "SafeDisc " + GetSafeDiscVersion(file, position); - } - // SecuROM if ((position = FileContent.IndexOf("AddD" + (char)0x03 + (char)0x00 + (char)0x00 + (char)0x00)) > -1) return "SecuROM " + GetSecuROM4Version(file, position); @@ -223,7 +220,7 @@ namespace DICUI.External if ((position = FileContent.IndexOf("" + (char)0xEF + (char)0xBE + (char)0xAD + (char)0xDE)) > -1) { - position--; + position--; // TODO: Verify this subtract if (FileContent.Substring(position + 5, 3) == "" + (char)0x00 + (char)0x00 + (char)0x00 && FileContent.Substring(position + 16, 4) == "" + (char)0x00 + (char)0x10 + (char)0x00 + (char)0x00) return "SolidShield 1"; @@ -241,7 +238,7 @@ namespace DICUI.External position = position == -1 ? FileContent.IndexOf("" + (char)0xAD + (char)0xDE + (char)0xFE + (char)0xCA + (char)0x5) : position; if (position > -1) { - position--; + position--; // TODO: Verify this subtract if (FileContent.Substring(position + 5, 3) == "" + (char)0x00 + (char)0x00 + (char)0x00 && FileContent.Substring(position + 16, 4) == "" + (char)0x00 + (char)0x10 + (char)0x00 + (char)0x00) { @@ -298,16 +295,16 @@ namespace DICUI.External return "TAGES " + GetFileVersion(file); if ((position = FileContent.IndexOf("" + (char)0xE8 + "u" + (char)0x00 + (char)0x00 + (char)0x00 + (char)0xE8)) > -1 - && FileContent.Substring(--position + 8, 3) == "" + (char)0xFF + (char)0xFF + "h") + && FileContent.Substring(--position + 8, 3) == "" + (char)0xFF + (char)0xFF + "h") // TODO: Verify this subtract return "TAGES " + GetTagesVersion(file, position); // VOB ProtectCD/DVD if ((position = FileContent.IndexOf("VOB ProtectCD")) > -1) - return "VOB ProtectCD/DVD " + GetProtectCDoldVersion(file, --position); + return "VOB ProtectCD/DVD " + GetProtectCDoldVersion(file, --position); // TODO: Verify this subtract if ((position = FileContent.IndexOf("DCP-BOV" + (char)0x00 + (char)0x00)) > -1) { - string version = GetVOBProtectCDDVDVersion(file, --position); + string version = GetVOBProtectCDDVDVersion(file, --position); // TODO: Verify this subtract if (version.Length > 0) { return "VOB ProtectCD/DVD " + version; @@ -365,23 +362,54 @@ namespace DICUI.External try { - MSCabinet cabfile = new MSCabinet(file); - foreach (var sub in cabfile.GetFiles()) + // Read the first 4 bytes to get the archive type + string magic = ""; + using (BinaryReader br = new BinaryReader(File.OpenRead(file))) { - string tempfile = Path.Combine(tempPath, sub.Filename); - sub.ExtractTo(tempfile); - string protection = ScanInFile(tempfile); - File.Delete(tempfile); + magic = new String(br.ReadChars(4)); + } - if (!String.IsNullOrEmpty(protection)) + // Microsoft CAB - "MSCF" + if (magic.StartsWith("MSCF")) + { + MSCabinet cabfile = new MSCabinet(file); + foreach (var sub in cabfile.GetFiles()) { - return protection; + string tempfile = Path.Combine(tempPath, sub.Filename); + sub.ExtractTo(tempfile); + string protection = ScanInFile(tempfile); + File.Delete(tempfile); + + if (!String.IsNullOrEmpty(protection)) + { + return protection; + } + } + } + // InstallShield CAB - "ISc" + else if (magic.StartsWith("ISc")) + { + IXComp.ListFiles(file, out int version); + IXComp.ExtractAll(file, tempPath, version); + var files = Directory.GetFiles(tempPath, "*", SearchOption.AllDirectories); + files.Select(f => (new FileInfo(f).IsReadOnly = false)); + foreach (var sub in files) + { + string protection = ScanInFile(sub); + try + { + File.Delete(sub); + } + catch { } + + if (!String.IsNullOrEmpty(protection)) + return protection; } } } catch { - // We assume it's an InstallShield CAB and ignore + // We had access issues so we ignore } finally { diff --git a/DICUI/External/iXcomp/IXComp.cs b/DICUI/External/iXcomp/IXComp.cs new file mode 100644 index 00000000..a003d7f7 --- /dev/null +++ b/DICUI/External/iXcomp/IXComp.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; + +namespace DICUI.External.iXcomp +{ + // TODO: Replace this with a C# implementation based on Unshield + public class IXComp + { + /// + /// List all files found within an InstallShield CAB file + /// + /// CAB file to check + /// Output tool version + /// List of files found in the CAB + public static List ListFiles(string input, out int version) + { + // Version 6 + version = 6; + Process p = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Programs", "i6comp.exe"), + Arguments = "l -o -r -d \"" + input + "\"", + CreateNoWindow = true, + UseShellExecute = false, + RedirectStandardOutput = true, + }, + }; + p.Start(); + p.WaitForExit(1000); + var i6output = p.StandardOutput.ReadToEnd().Replace("\r\n", "\n").Split('\n').Where(s => s.Length > 50).Select(s => s.Substring(50)).ToList(); + + if (i6output.Count() > 0) + return i6output; + + // Version 5 + version = 5; + p = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Programs", "i5comp.exe"), + Arguments = "l -o -r -d \"" + input + "\"", + CreateNoWindow = true, + UseShellExecute = false, + RedirectStandardOutput = true, + }, + }; + p.Start(); + p.WaitForExit(1000); + var i5output = p.StandardOutput.ReadToEnd().Replace("\r\n", "\n").Split('\n').Where(s => s.Length > 47).Select(s => s.Substring(47)).ToList(); + + if (i5output.Count() > 0) + return i6output; + + version = -1; + return new List(); + } + + /// + /// Extract all files found within an InstallShield CAB file + /// + /// CAB file to check + /// Output directory to extract to + /// Tool version + /// True if the files extracted succesfully, false otherwise + public static bool ExtractAll(string cabfile, string outDir, int version) + { + string exe = null; + switch(version) + { + case 6: + exe = "i6comp.exe"; + break; + case 5: + exe = "i5comp.exe"; + break; + } + + if (exe == null) + return false; + + Process p = new Process + { + StartInfo = new ProcessStartInfo + { + WorkingDirectory = outDir, + FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Programs", exe), + Arguments = "x -r -d \"" + cabfile + "\"", + CreateNoWindow = true, + UseShellExecute = false, + RedirectStandardOutput = true, + }, + }; + p.Start(); + p.WaitForExit(); + return true; + } + } +} diff --git a/DICUI/Programs/ZD50149.DLL b/DICUI/Programs/ZD50149.DLL new file mode 100644 index 00000000..79ae76dd Binary files /dev/null and b/DICUI/Programs/ZD50149.DLL differ diff --git a/DICUI/Programs/ZD51145.DLL b/DICUI/Programs/ZD51145.DLL new file mode 100644 index 00000000..1c5c3bcf Binary files /dev/null and b/DICUI/Programs/ZD51145.DLL differ diff --git a/DICUI/Programs/ZD55131.DLL b/DICUI/Programs/ZD55131.DLL new file mode 100644 index 00000000..d6e92449 Binary files /dev/null and b/DICUI/Programs/ZD55131.DLL differ diff --git a/DICUI/Programs/i3comp.exe b/DICUI/Programs/i3comp.exe new file mode 100644 index 00000000..32ca4fc7 Binary files /dev/null and b/DICUI/Programs/i3comp.exe differ diff --git a/DICUI/Programs/i5comp.exe b/DICUI/Programs/i5comp.exe new file mode 100644 index 00000000..5f92cac8 Binary files /dev/null and b/DICUI/Programs/i5comp.exe differ diff --git a/DICUI/Programs/i6comp.exe b/DICUI/Programs/i6comp.exe new file mode 100644 index 00000000..1b1cb0b5 Binary files /dev/null and b/DICUI/Programs/i6comp.exe differ diff --git a/DICUI/Utilities/Validators.cs b/DICUI/Utilities/Validators.cs index 18099374..eee27280 100644 --- a/DICUI/Utilities/Validators.cs +++ b/DICUI/Utilities/Validators.cs @@ -7,7 +7,7 @@ using System.Runtime.InteropServices; using System.Threading.Tasks; using IMAPI2; using DICUI.Data; -using DICUI.External; +using DICUI.External.BurnOut; namespace DICUI.Utilities {