mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-02-17 05:45:14 +00:00
MSI was really CFB all along
This commit is contained in:
@@ -25,6 +25,11 @@
|
||||
/// </summary>
|
||||
BZip2,
|
||||
|
||||
/// <summary>
|
||||
/// Compound File Binary
|
||||
/// </summary>
|
||||
CFB,
|
||||
|
||||
/// <summary>
|
||||
/// CTR Importable Archive
|
||||
/// </summary>
|
||||
@@ -80,11 +85,6 @@
|
||||
/// </summary>
|
||||
MPQ,
|
||||
|
||||
/// <summary>
|
||||
/// Microsoft installation package
|
||||
/// </summary>
|
||||
MSI,
|
||||
|
||||
/// <summary>
|
||||
/// Nintendo 3DS cart image
|
||||
/// </summary>
|
||||
|
||||
@@ -9,9 +9,9 @@ using static BurnOutSharp.Utilities.Dictionary;
|
||||
namespace BurnOutSharp.FileType
|
||||
{
|
||||
/// <summary>
|
||||
/// Microsoft installation package
|
||||
/// Compound File Binary
|
||||
/// </summary>
|
||||
public class MSI : IScannable
|
||||
public class CFB : IScannable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
|
||||
@@ -427,6 +427,14 @@ namespace BurnOutSharp
|
||||
AppendToDictionary(protections, subProtections);
|
||||
}
|
||||
|
||||
// CFB
|
||||
if (fileName != null && scannable is CFB)
|
||||
{
|
||||
var subProtections = scannable.Scan(this, fileName);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
AppendToDictionary(protections, subProtections);
|
||||
}
|
||||
|
||||
// GCF
|
||||
if (scannable is GCF)
|
||||
{
|
||||
@@ -475,14 +483,6 @@ namespace BurnOutSharp
|
||||
AppendToDictionary(protections, subProtections);
|
||||
}
|
||||
|
||||
// MSI
|
||||
if (fileName != null && scannable is MSI)
|
||||
{
|
||||
var subProtections = scannable.Scan(this, fileName);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
AppendToDictionary(protections, subProtections);
|
||||
}
|
||||
|
||||
// MoPaQ archive
|
||||
if (fileName != null && scannable is MPQ)
|
||||
{
|
||||
|
||||
@@ -43,6 +43,13 @@ namespace BurnOutSharp.Tools
|
||||
|
||||
#endregion
|
||||
|
||||
#region CFB
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
#endregion
|
||||
|
||||
#region CIA
|
||||
|
||||
// No magic checks for CIA
|
||||
@@ -150,13 +157,6 @@ namespace BurnOutSharp.Tools
|
||||
|
||||
#endregion
|
||||
|
||||
#region MSI
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }))
|
||||
return SupportedFileType.MSI;
|
||||
|
||||
#endregion
|
||||
|
||||
#region N3DS
|
||||
|
||||
// No magic checks for N3DS
|
||||
@@ -365,6 +365,30 @@ namespace BurnOutSharp.Tools
|
||||
|
||||
#endregion
|
||||
|
||||
#region CFB
|
||||
|
||||
// Installer package
|
||||
if (extension.Equals("msi", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
// Merge module
|
||||
else if (extension.Equals("msm", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
// Patch Package
|
||||
else if (extension.Equals("msp", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
// Transform
|
||||
else if (extension.Equals("mst", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
// Patch Creation Properties
|
||||
else if (extension.Equals("pcp", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
#endregion
|
||||
|
||||
#region CIA
|
||||
|
||||
if (extension.Equals("cia", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -433,13 +457,6 @@ namespace BurnOutSharp.Tools
|
||||
|
||||
#endregion
|
||||
|
||||
#region MSI
|
||||
|
||||
if (extension.Equals("msi", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.MSI;
|
||||
|
||||
#endregion
|
||||
|
||||
#region N3DS
|
||||
|
||||
// 3DS cart image
|
||||
@@ -717,6 +734,7 @@ namespace BurnOutSharp.Tools
|
||||
case SupportedFileType.BFPK: return new FileType.BFPK();
|
||||
case SupportedFileType.BSP: return new FileType.BSP();
|
||||
case SupportedFileType.BZip2: return new FileType.BZip2();
|
||||
case SupportedFileType.CFB: return new FileType.CFB();
|
||||
//case SupportedFileType.CIA: return new FileType.CIA();
|
||||
case SupportedFileType.Executable: return new FileType.Executable();
|
||||
case SupportedFileType.GCF: return new FileType.GCF();
|
||||
@@ -728,7 +746,6 @@ namespace BurnOutSharp.Tools
|
||||
case SupportedFileType.MicrosoftCAB: return new FileType.MicrosoftCAB();
|
||||
case SupportedFileType.MicrosoftLZ: return new FileType.MicrosoftLZ();
|
||||
case SupportedFileType.MPQ: return new FileType.MPQ();
|
||||
case SupportedFileType.MSI: return new FileType.MSI();
|
||||
//case SupportedFileType.N3DS: return new FileType.N3DS();
|
||||
//case SupportedFileType.NCF: return new FileType.NCF();
|
||||
//case SupportedFileType.Nitro: return new FileType.Nitro();
|
||||
|
||||
@@ -156,7 +156,7 @@ Below is a list of container formats that are supported in some way:
|
||||
| 7-zip archive | No | Yes | Yes | Via `SharpCompress` |
|
||||
| BFPK custom archive format | Yes | Yes | Yes | |
|
||||
| bzip2 archive | No | Yes | Yes | Via `SharpCompress` |
|
||||
| Compound File Binary (CFB) | Yes | Yes* | No | Basis of MSI, only CFB common pieces printable |
|
||||
| Compound File Binary (CFB) | Yes* | Yes | Yes | Via `OpenMcdf`, only CFB common pieces printable |
|
||||
| gzip archive | No | Yes | Yes | Via `SharpCompress` |
|
||||
| Half-Life Game Cache File (GCF) | Yes | Yes | Yes | |
|
||||
| Half-Life Level (BSP) | Yes | Yes | Yes | |
|
||||
@@ -171,7 +171,6 @@ Below is a list of container formats that are supported in some way:
|
||||
| Microsoft cabinet file | Yes | Yes | Yes | |
|
||||
| Microsoft LZ-compressed files | No | Yes | Yes | |
|
||||
| MoPaQ game data archive (MPQ) | No | Yes | Yes | Via `StormLibSharp` |
|
||||
| Microsoft installation package (MSI) | No | Yes | Yes | Via `OpenMcdf` |
|
||||
| MS-DOS Executable | Yes | Yes | No | Incomplete |
|
||||
| New Exectuable | Yes | Yes | No | Incomplete |
|
||||
| Nintendo 3DS cart image | Yes | Yes | No | |
|
||||
|
||||
@@ -189,6 +189,58 @@ namespace Test
|
||||
}
|
||||
}
|
||||
|
||||
// CFB
|
||||
else if (ft == SupportedFileType.CFB)
|
||||
{
|
||||
// Build the installer information
|
||||
Console.WriteLine("Extracting CFB contents");
|
||||
Console.WriteLine();
|
||||
|
||||
// If the CFB file itself fails
|
||||
try
|
||||
{
|
||||
using (CompoundFile cf = new CompoundFile(stream, CFSUpdateMode.ReadOnly, CFSConfiguration.Default))
|
||||
{
|
||||
cf.RootStorage.VisitEntries((e) =>
|
||||
{
|
||||
if (!e.IsStream)
|
||||
return;
|
||||
|
||||
var str = cf.RootStorage.GetStream(e.Name);
|
||||
if (str == null)
|
||||
return;
|
||||
|
||||
byte[] strData = str.GetData();
|
||||
if (strData == null)
|
||||
return;
|
||||
|
||||
string decoded = BurnOutSharp.FileType.CFB.DecodeStreamName(e.Name).TrimEnd('\0');
|
||||
byte[] nameBytes = Encoding.UTF8.GetBytes(e.Name);
|
||||
|
||||
// UTF-8 encoding of 0x4840.
|
||||
if (nameBytes[0] == 0xe4 && nameBytes[1] == 0xa1 && nameBytes[2] == 0x80)
|
||||
decoded = decoded.Substring(3);
|
||||
|
||||
foreach (char c in Path.GetInvalidFileNameChars())
|
||||
{
|
||||
decoded = decoded.Replace(c, '_');
|
||||
}
|
||||
|
||||
string filename = Path.Combine(outputDirectory, decoded);
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
fs.Write(strData, 0, strData.Length);
|
||||
}
|
||||
}, recursive: true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Something went wrong extracting CFB: {ex}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
// GCF
|
||||
else if (ft == SupportedFileType.GCF)
|
||||
{
|
||||
@@ -458,58 +510,6 @@ namespace Test
|
||||
}
|
||||
#endif
|
||||
|
||||
// MSI
|
||||
else if (ft == SupportedFileType.MSI)
|
||||
{
|
||||
// Build the installer information
|
||||
Console.WriteLine("Extracting MSI contents");
|
||||
Console.WriteLine();
|
||||
|
||||
// If the MSI file itself fails
|
||||
try
|
||||
{
|
||||
using (CompoundFile msi = new CompoundFile(stream, CFSUpdateMode.ReadOnly, CFSConfiguration.Default))
|
||||
{
|
||||
msi.RootStorage.VisitEntries((e) =>
|
||||
{
|
||||
if (!e.IsStream)
|
||||
return;
|
||||
|
||||
var str = msi.RootStorage.GetStream(e.Name);
|
||||
if (str == null)
|
||||
return;
|
||||
|
||||
byte[] strData = str.GetData();
|
||||
if (strData == null)
|
||||
return;
|
||||
|
||||
string decoded = BurnOutSharp.FileType.MSI.DecodeStreamName(e.Name).TrimEnd('\0');
|
||||
byte[] nameBytes = Encoding.UTF8.GetBytes(e.Name);
|
||||
|
||||
// UTF-8 encoding of 0x4840.
|
||||
if (nameBytes[0] == 0xe4 && nameBytes[1] == 0xa1 && nameBytes[2] == 0x80)
|
||||
decoded = decoded.Substring(3);
|
||||
|
||||
foreach (char c in Path.GetInvalidFileNameChars())
|
||||
{
|
||||
decoded = decoded.Replace(c, '_');
|
||||
}
|
||||
|
||||
string filename = Path.Combine(outputDirectory, decoded);
|
||||
using (Stream fs = File.OpenWrite(filename))
|
||||
{
|
||||
fs.Write(strData, 0, strData.Length);
|
||||
}
|
||||
}, recursive: true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Something went wrong extracting MSI: {ex}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
// PAK
|
||||
else if (ft == SupportedFileType.PAK)
|
||||
{
|
||||
|
||||
@@ -174,6 +174,25 @@ namespace Test
|
||||
bsp.Print();
|
||||
}
|
||||
|
||||
// CFB
|
||||
else if (ft == SupportedFileType.CFB)
|
||||
{
|
||||
// Build the CFB information
|
||||
Console.WriteLine("Creating Compact File Binary deserializer");
|
||||
Console.WriteLine();
|
||||
|
||||
var cfb = CFB.Create(stream);
|
||||
if (cfb == null)
|
||||
{
|
||||
Console.WriteLine("Something went wrong parsing Compact File Binary");
|
||||
Console.WriteLine();
|
||||
return;
|
||||
}
|
||||
|
||||
// Print the CFB to screen
|
||||
cfb.Print();
|
||||
}
|
||||
|
||||
// CIA
|
||||
else if (ft == SupportedFileType.CIA)
|
||||
{
|
||||
@@ -257,25 +276,6 @@ namespace Test
|
||||
cabinet.Print();
|
||||
}
|
||||
|
||||
// MSI -- TODO: Technically CFB
|
||||
else if (ft == SupportedFileType.MSI)
|
||||
{
|
||||
// Build the CFB information
|
||||
Console.WriteLine("Creating Compact File Binary deserializer");
|
||||
Console.WriteLine();
|
||||
|
||||
var cfb = CFB.Create(stream);
|
||||
if (cfb == null)
|
||||
{
|
||||
Console.WriteLine("Something went wrong parsing Compact File Binary");
|
||||
Console.WriteLine();
|
||||
return;
|
||||
}
|
||||
|
||||
// Print the CFB to screen
|
||||
cfb.Print();
|
||||
}
|
||||
|
||||
// N3DS
|
||||
else if (ft == SupportedFileType.N3DS)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user