Skip to content

Commit d2eebd0

Browse files
committed
Cleanup
1 parent a281e83 commit d2eebd0

File tree

13 files changed

+533
-559
lines changed

13 files changed

+533
-559
lines changed

BinaryObjectScanner/Data/StaticChecks.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public static IContentCheck[] ContentCheckClasses
2323
}
2424

2525
/// <summary>
26-
/// Cache for all IISOCheck<ISO> types
26+
/// Cache for all IDiskImageCheck<ISO9660> types
2727
/// </summary>
2828
public static IDiskImageCheck<ISO9660>[] ISO9660CheckClasses
2929
{
@@ -33,7 +33,7 @@ public static IDiskImageCheck<ISO9660>[] ISO9660CheckClasses
3333
return iso9660CheckClasses;
3434
}
3535
}
36-
36+
3737
/// <summary>
3838
/// Cache for all IExecutableCheck<LinearExecutable> types
3939
/// </summary>
@@ -103,12 +103,11 @@ public static IExecutableCheck<PortableExecutable>[] PortableExecutableCheckClas
103103
/// </summary>
104104
private static IContentCheck[]? contentCheckClasses;
105105

106-
107106
/// <summary>
108107
/// Cache for all IISOCheck<ISO9660> types
109108
/// </summary>
110109
private static IDiskImageCheck<ISO9660>[]? iso9660CheckClasses;
111-
110+
112111
/// <summary>
113112
/// Cache for all IExecutableCheck<LinearExecutable> types
114113
/// </summary>
@@ -169,7 +168,7 @@ private static T[] InitCheckClasses<T>(Assembly assembly)
169168
if (assemblyTypes.Length == 0)
170169
return [];
171170

172-
// Loop through all types
171+
// Loop through all types
173172
List<T> classTypes = [];
174173
foreach (Type? type in assemblyTypes)
175174
{

BinaryObjectScanner/FileType/DiskImage.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System;
21
using System.Collections.Generic;
3-
using System.IO;
42
using BinaryObjectScanner.Data;
53
using BinaryObjectScanner.Interfaces;
64
using SabreTools.IO.Extensions;
@@ -20,13 +18,13 @@ public DiskImage(T wrapper) : base(wrapper) { }
2018
#region Check Runners
2119

2220
/// <summary>
23-
/// Handle a single file based on all ISO check implementations
21+
/// Handle a single file based on all disk image check implementations
2422
/// </summary>
25-
/// <param name="file">Name of the source file of the ISO, for tracking</param>
23+
/// <param name="file">Name of the source file of the disk image, for tracking</param>
2624
/// <param name="checks">Set of checks to use</param>
2725
/// <param name="includeDebug">True to include debug data, false otherwise</param>
2826
/// <returns>Set of protections in file, empty on error</returns>
29-
protected IDictionary<U, string> RunISOChecks<U>(string file, U[] checks, bool includeDebug)
27+
protected IDictionary<U, string> RunDiskImageChecks<U>(string file, U[] checks, bool includeDebug)
3028
where U : IDiskImageCheck<T>
3129
{
3230
// Create the output dictionary

BinaryObjectScanner/FileType/ISO9660.cs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public ISO9660(SabreTools.Serialization.Wrappers.ISO9660 wrapper) : base(wrapper
2525

2626
// Standard checks
2727
var subProtections
28-
= RunISOChecks(file, StaticChecks.ISO9660CheckClasses, includeDebug);
28+
= RunDiskImageChecks(file, StaticChecks.ISO9660CheckClasses, includeDebug);
2929
protections.Append(file, subProtections.Values);
3030

3131
// If there are no protections
@@ -43,51 +43,51 @@ var subProtections
4343
}
4444

4545
/// <summary>
46-
/// Checks whether the sequence of bytes is pure data (as in, not empty, not text, just high-entropy data)
46+
/// Checks whether the sequence of bytes is pure data (as in, not empty,
47+
/// not text, just high-entropy data)
4748
/// </summary>
4849
public static bool IsPureData(byte[] bytes)
4950
{
5051
// Check if there are three 0x00s in a row. Two seems like pushing it
51-
byte[] containedZeroes = {0x00, 0x00, 0x00};
5252
int index = 0;
53-
for (int i = 0; i < bytes.Length; ++i)
53+
for (int i = 0; i < bytes.Length; ++i)
5454
{
55-
if (bytes[i] == containedZeroes[index])
55+
if (bytes[i] == 0x00)
5656
{
57-
if (++index >= containedZeroes.Length)
58-
return false;
57+
if (++index >= 3)
58+
return false;
5959
}
6060
else
6161
{
62-
index = 0;
62+
index = 0;
6363
}
6464
}
65-
65+
6666
// Checks if there are strings in the data
6767
// TODO: is this too dangerous, or too faulty?
6868
// Currently-found worst cases:
6969
// "Y:1BY:1BC" in Redump ID 23339
7070
var strings = bytes.ReadStringsWithEncoding(charLimit: 7, Encoding.ASCII);
71-
Regex rgx = new Regex("[^a-zA-Z0-9 -'!,.]");
71+
var rgx = new Regex("[^a-zA-Z0-9 -'!,.]");
7272
foreach (string str in strings)
7373
{
7474
if (rgx.Replace(str, "").Length > 7)
7575
return false;
7676
}
77-
77+
7878
return true;
7979
}
80-
81-
// TODO: can these 2 "noteworthy" functions be cached?
80+
8281
/// <summary>
8382
/// Checks whether the Application Use data is "noteworthy" enough to be worth checking for protection.
8483
/// </summary>
84+
/// TODO: can these 2 "noteworthy" functions be cached?
8585
public static bool NoteworthyApplicationUse(PrimaryVolumeDescriptor pvd)
8686
{
8787
var applicationUse = pvd.ApplicationUse;
8888
if (Array.TrueForAll(applicationUse, b => b == 0x00))
8989
return false;
90-
90+
9191
int offset = 0;
9292
string? potentialAppUseString = applicationUse.ReadNullTerminatedAnsiString(ref offset);
9393
if (potentialAppUseString != null && potentialAppUseString.Length > 0) // Some image authoring programs add a starting string to AU data
@@ -100,20 +100,21 @@ public static bool NoteworthyApplicationUse(PrimaryVolumeDescriptor pvd)
100100
return false;
101101
else if (Array.TrueForAll(Encoding.ASCII.GetBytes(potentialAppUseString), b => b == 0x20))
102102
return false;
103+
103104
// TODO: Unhandled "norb" mastering that puts stuff everywhere, inconsistently. See RID 103641
104105
// More things will have to go here as more disc authoring softwares are found that do this.
105106
// Redump ID 24478 has a bunch of 0x20 with norb in the middle, some discs have 0x20 that ends in a "/"
106107
// character. If these are found to be causing issues they can be added.
107108
}
108-
109+
109110
offset = 141;
110111
potentialAppUseString = applicationUse.ReadNullTerminatedAnsiString(ref offset);
111-
if (potentialAppUseString == "CD-XA001")
112-
return false;
113-
112+
if (potentialAppUseString == "CD-XA001")
113+
return false;
114+
114115
return true;
115116
}
116-
117+
117118
/// <summary>
118119
/// Checks whether the Reserved 653 Bytes are "noteworthy" enough to be worth checking for protection.
119120
/// </summary>
@@ -123,8 +124,9 @@ public static bool NoteworthyReserved653Bytes(PrimaryVolumeDescriptor pvd)
123124
var noteworthyReserved653Bytes = true;
124125
if (Array.TrueForAll(reserved653Bytes, b => b == 0x00))
125126
noteworthyReserved653Bytes = false;
127+
126128
// Unsure if more will be needed
127129
return noteworthyReserved653Bytes;
128130
}
129131
}
130-
}
132+
}

BinaryObjectScanner/Interfaces/IDiskImageCheck.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ public interface IDiskImageCheck<T> where T : WrapperBase
1111
/// Check a path for protections based on file contents
1212
/// </summary>
1313
/// <param name="file">File to check for protection indicators</param>
14-
/// <param name="diskImage"></param>
14+
/// <param name="diskImage">Disk image representing the read-in file</param>
1515
/// <param name="includeDebug">True to include debug data, false otherwise</param>
1616
/// <returns>String containing any protections found in the file</returns>
1717
string? CheckDiskImage(string file, T diskImage, bool includeDebug);
1818
}
19-
}
19+
}

BinaryObjectScanner/Protection/AlphaROM.cs

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace BinaryObjectScanner.Protection
1010
/// <summary>
1111
/// Alpha-ROM is a form of copy protection created by SETTEC. It is known to make use of twin sectors as well as region locking.
1212
/// Later forms of Alpha-ROM appear to be digital only, and it's currently unsure what forms of protection the digital only version includes, except that it does make use of region locking.
13-
/// It seems that Alpha-ROM was used in Visual Novels using certain game engines, most notably RealLive and Siglus (https://forums.fuwanovel.net/topic/20927-cannot-crack-siglus-engine-with-alpharom/).
13+
/// It seems that Alpha-ROM was used in Visual Novels using certain game engines, most notably RealLive and Siglus (https://forums.fuwanovel.net/topic/20927-cannot-crack-siglus-engine-with-alpharom/).
1414
/// Not every Siglus engine game uses Alpha-ROM (Source: https://sample9.dmm.co.jp/digital/pcgame/vsat_0263/vsat_0263t.zip {Official trial mirror}).
1515
/// Not every RealLive engine game uses Alpha-ROM (Source: IA item "Kanon_Standard_Edition_Japan").
1616
/// Alpha-ROM also seems to have made use of something called "Alpha-DPS" for non-executable data files (http://www.gonsuke.co.jp/protect.html).
@@ -43,12 +43,57 @@ namespace BinaryObjectScanner.Protection
4343
// - SETTEC0000SETTEC1111
4444
// - SOFTWARE\SETTEC
4545
// TODO: Are there version numbers?
46-
public class AlphaROM : IExecutableCheck<PortableExecutable>, IDiskImageCheck<ISO9660>
46+
public class AlphaROM : IDiskImageCheck<ISO9660>, IExecutableCheck<PortableExecutable>
4747
{
48+
/// <inheritdoc/>
49+
public string? CheckDiskImage(string file, ISO9660 diskImage, bool includeDebug)
50+
{
51+
// Checks can be made even easier once UDF support exists, as most (although not all, some early discs like
52+
// redump ID 124111 have no UDF partition) discs have "Settec" slathered over every field UDF lets them.
53+
54+
if (diskImage.VolumeDescriptorSet.Length == 0)
55+
return null;
56+
if (diskImage.VolumeDescriptorSet[0] is not PrimaryVolumeDescriptor pvd)
57+
return null;
58+
59+
// Alpharom disc check #1: disc has varying (but observed to at least always be larger than 14) length
60+
// string made up of numbers and capital letters.
61+
// TODO: triple-check that length is never below 14
62+
int offset = 0;
63+
var applicationIdentifierString = pvd.ApplicationIdentifier.ReadNullTerminatedAnsiString(ref offset)?.Trim();
64+
if (applicationIdentifierString == null || applicationIdentifierString.Length < 14)
65+
return null;
66+
67+
if (!Regex.IsMatch(applicationIdentifierString, "^[A-Z0-9]*$"))
68+
return null;
69+
70+
// Alpharom disc check #2: disc has publisher identifier filled with varying amount of data (26-50 bytes
71+
// have been observed) followed by spaces. There's a decent chance this is just a Japanese text string, but
72+
// UTF, Shift-JIS, and EUC-JP all fail to display anything but garbage.
73+
74+
var publisherIdentifier = pvd.PublisherIdentifier;
75+
int firstSpace = Array.FindIndex(publisherIdentifier, b => b == 0x20);
76+
if (firstSpace <= 10 || firstSpace >= 120)
77+
return null;
78+
79+
var publisherData = new byte[firstSpace];
80+
var publisherSpaces = new byte[publisherData.Length - firstSpace];
81+
Array.Copy(publisherIdentifier, 0, publisherData, 0, firstSpace);
82+
Array.Copy(publisherIdentifier, firstSpace, publisherSpaces, 0, publisherData.Length - firstSpace);
83+
84+
if (!Array.TrueForAll(publisherSpaces, b => b == 0x20))
85+
return null;
86+
87+
if (!FileType.ISO9660.IsPureData(publisherData))
88+
return null;
89+
90+
return "AlphaROM";
91+
}
92+
4893
/// <inheritdoc/>
4994
public string? CheckExecutable(string file, PortableExecutable exe, bool includeDebug)
5095
{
51-
// TODO: Add support for detecting Alpha-ROM found in older games made with the RealLive engine.
96+
// TODO: Add support for detecting Alpha-ROM found in older games made with the RealLive engine.
5297
// TODO: Add version detection for Alpha-ROM.
5398

5499
// Get the .data/DATA section strings, if they exist
@@ -88,51 +133,5 @@ public class AlphaROM : IExecutableCheck<PortableExecutable>, IDiskImageCheck<IS
88133

89134
return null;
90135
}
91-
92-
/// <inheritdoc/>
93-
public string? CheckDiskImage(string file, ISO9660 diskImage, bool includeDebug)
94-
{
95-
// Checks can be made even easier once UDF support exists, as most (although not all, some early discs like
96-
// redump ID 124111 have no UDF partition) discs have "Settec" slathered over every field UDF lets them.
97-
98-
if (diskImage.VolumeDescriptorSet.Length == 0)
99-
return null;
100-
101-
if (diskImage.VolumeDescriptorSet[0] is not PrimaryVolumeDescriptor pvd)
102-
return null;
103-
104-
// Alpharom disc check #1: disc has varying (but observed to at least always be larger than 14) length
105-
// string made up of numbers and capital letters.
106-
// TODO: triple-check that length is never below 14
107-
int offset = 0;
108-
var applicationIdentifierString = pvd.ApplicationIdentifier.ReadNullTerminatedAnsiString(ref offset)?.Trim();
109-
if (applicationIdentifierString == null || applicationIdentifierString.Length < 14)
110-
return null;
111-
112-
if (!Regex.IsMatch(applicationIdentifierString, "^[A-Z0-9]*$"))
113-
return null;
114-
115-
// Alpharom disc check #2: disc has publisher identifier filled with varying amount of data (26-50 bytes
116-
// have been observed) followed by spaces. There's a decent chance this is just a Japanese text string, but
117-
// UTF, Shift-JIS, and EUC-JP all fail to display anything but garbage.
118-
119-
var publisherIdentifier = pvd.PublisherIdentifier;
120-
int firstSpace = Array.FindIndex(publisherIdentifier, b => b == 0x20);
121-
if (firstSpace <= 10 || firstSpace >= 120)
122-
return null;
123-
124-
var publisherData = new byte[firstSpace];
125-
var publisherSpaces = new byte[publisherData.Length - firstSpace];
126-
Array.Copy(publisherIdentifier, 0, publisherData, 0, firstSpace);
127-
Array.Copy(publisherIdentifier, firstSpace, publisherSpaces, 0, publisherData.Length - firstSpace);
128-
129-
if (!Array.TrueForAll(publisherSpaces, b => b == 0x20))
130-
return null;
131-
132-
if (!FileType.ISO9660.IsPureData(publisherData))
133-
return null;
134-
135-
return "AlphaROM";
136-
}
137136
}
138137
}

0 commit comments

Comments
 (0)