mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-04-26 08:10:32 +00:00
Fix resource parsing, fix MS-CAB SFX
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using BurnOutSharp.Tools;
|
||||
@@ -37,7 +35,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
|
||||
while ((r.Length = stream.ReadUInt16()) == 0x0000);
|
||||
|
||||
r.Length = stream.ReadUInt16();
|
||||
r.ValueLength = stream.ReadUInt16();
|
||||
r.Type = stream.ReadUInt16();
|
||||
r.Key = stream.ReadString(Encoding.Unicode);
|
||||
@@ -51,18 +48,9 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
|
||||
while ((r.Length = content.ReadUInt16(ref offset)) == 0x0000);
|
||||
|
||||
offset += 2;
|
||||
r.ValueLength = content.ReadUInt16(ref offset);
|
||||
r.Type = content.ReadUInt16(ref offset);
|
||||
|
||||
List<char> keyChars = new List<char>();
|
||||
while (BitConverter.ToUInt16(content, offset) != 0x0000)
|
||||
{
|
||||
keyChars.Add(Encoding.Unicode.GetChars(content, offset, 2)[0]); offset += 2;
|
||||
}
|
||||
offset += 2;
|
||||
|
||||
r.Key = new string(keyChars.ToArray());
|
||||
r.Key = content.ReadString(ref offset, Encoding.Unicode);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -10,18 +10,21 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
/// </summary>
|
||||
public StringTable Children;
|
||||
|
||||
public StringFileInfo(Resource resource)
|
||||
{
|
||||
this.Length = resource?.Length ?? default;
|
||||
this.ValueLength = resource?.ValueLength ?? default;
|
||||
this.Type = resource?.Type ?? default;
|
||||
this.Key = resource?.Key ?? default;
|
||||
}
|
||||
|
||||
public static new StringFileInfo Deserialize(Stream stream)
|
||||
{
|
||||
StringFileInfo sfi = new StringFileInfo();
|
||||
|
||||
Resource resource = Resource.Deserialize(stream);
|
||||
if (resource.Key != "StringFileInfo")
|
||||
return null;
|
||||
|
||||
sfi.Length = resource.Length;
|
||||
sfi.ValueLength = resource.ValueLength;
|
||||
sfi.Type = resource.Type;
|
||||
sfi.Key = resource.Key;
|
||||
StringFileInfo sfi = new StringFileInfo(resource);
|
||||
sfi.Children = StringTable.Deserialize(stream);
|
||||
|
||||
return sfi;
|
||||
@@ -29,16 +32,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
|
||||
public static new StringFileInfo Deserialize(byte[] content, ref int offset)
|
||||
{
|
||||
StringFileInfo sfi = new StringFileInfo();
|
||||
|
||||
Resource resource = Resource.Deserialize(content, ref offset);
|
||||
if (resource.Key != "StringFileInfo")
|
||||
return null;
|
||||
|
||||
sfi.Length = resource.Length;
|
||||
sfi.ValueLength = resource.ValueLength;
|
||||
sfi.Type = resource.Type;
|
||||
sfi.Key = resource.Key;
|
||||
StringFileInfo sfi = new StringFileInfo(resource);
|
||||
sfi.Children = StringTable.Deserialize(content, ref offset);
|
||||
|
||||
return sfi;
|
||||
|
||||
@@ -11,16 +11,18 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
/// </summary>
|
||||
public string Value;
|
||||
|
||||
public StringStruct(Resource resource)
|
||||
{
|
||||
this.Length = resource?.Length ?? default;
|
||||
this.ValueLength = resource?.ValueLength ?? default;
|
||||
this.Type = resource?.Type ?? default;
|
||||
this.Key = resource?.Key ?? default;
|
||||
}
|
||||
|
||||
public static new StringStruct Deserialize(Stream stream)
|
||||
{
|
||||
StringStruct s = new StringStruct();
|
||||
|
||||
Resource resource = Resource.Deserialize(stream);
|
||||
|
||||
s.Length = resource.Length;
|
||||
s.ValueLength = resource.ValueLength;
|
||||
s.Type = resource.Type;
|
||||
s.Key = resource.Key;
|
||||
StringStruct s = new StringStruct(resource);
|
||||
stream.Seek(stream.Position % 4 == 0 ? 0 : 4 - (stream.Position % 4), SeekOrigin.Current);
|
||||
s.Value = new string(stream.ReadChars(s.ValueLength));
|
||||
|
||||
@@ -29,14 +31,8 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
|
||||
public static new StringStruct Deserialize(byte[] content, ref int offset)
|
||||
{
|
||||
StringStruct s = new StringStruct();
|
||||
|
||||
Resource resource = Resource.Deserialize(content, ref offset);
|
||||
|
||||
s.Length = resource.Length;
|
||||
s.ValueLength = resource.ValueLength;
|
||||
s.Type = resource.Type;
|
||||
s.Key = resource.Key;
|
||||
StringStruct s = new StringStruct(resource);
|
||||
offset += offset % 4 == 0 ? 0 : 4 - (offset % 4);
|
||||
s.Value = Encoding.Unicode.GetString(content, offset, s.ValueLength * 2); offset += s.ValueLength * 2;
|
||||
|
||||
|
||||
@@ -10,19 +10,22 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
/// </summary>
|
||||
public StringStruct[] Children;
|
||||
|
||||
public StringTable(Resource resource)
|
||||
{
|
||||
this.Length = resource?.Length ?? default;
|
||||
this.ValueLength = resource?.ValueLength ?? default;
|
||||
this.Type = resource?.Type ?? default;
|
||||
this.Key = resource?.Key ?? default;
|
||||
}
|
||||
|
||||
public static new StringTable Deserialize(Stream stream)
|
||||
{
|
||||
long originalPosition = stream.Position;
|
||||
StringTable st = new StringTable();
|
||||
|
||||
Resource resource = Resource.Deserialize(stream);
|
||||
if (resource.Key.Length != 8)
|
||||
return null;
|
||||
|
||||
st.Length = resource.Length;
|
||||
st.ValueLength = resource.ValueLength;
|
||||
st.Type = resource.Type;
|
||||
st.Key = resource.Key;
|
||||
StringTable st = new StringTable(resource);
|
||||
|
||||
var tempValue = new List<StringStruct>();
|
||||
while (stream.Position - originalPosition < st.Length)
|
||||
@@ -38,16 +41,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
public static new StringTable Deserialize(byte[] content, ref int offset)
|
||||
{
|
||||
int originalPosition = offset;
|
||||
StringTable st = new StringTable();
|
||||
|
||||
Resource resource = Resource.Deserialize(content, ref offset);
|
||||
if (resource.Key.Length != 8)
|
||||
return null;
|
||||
|
||||
st.Length = resource.Length;
|
||||
st.ValueLength = resource.ValueLength;
|
||||
st.Type = resource.Type;
|
||||
st.Key = resource.Key;
|
||||
StringTable st = new StringTable(resource);
|
||||
|
||||
var tempValue = new List<StringStruct>();
|
||||
while (offset - originalPosition < st.Length)
|
||||
|
||||
@@ -16,19 +16,22 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
/// </summary>
|
||||
public LanguageCodePage[] Value;
|
||||
|
||||
public Var(Resource resource)
|
||||
{
|
||||
this.Length = resource?.Length ?? default;
|
||||
this.ValueLength = resource?.ValueLength ?? default;
|
||||
this.Type = resource?.Type ?? default;
|
||||
this.Key = resource?.Key ?? default;
|
||||
}
|
||||
|
||||
public static new Var Deserialize(Stream stream)
|
||||
{
|
||||
long originalPosition = stream.Position;
|
||||
Var v = new Var();
|
||||
|
||||
Resource resource = Resource.Deserialize(stream);
|
||||
if (resource.Key != "Translation")
|
||||
return null;
|
||||
|
||||
v.Length = resource.Length;
|
||||
v.ValueLength = resource.ValueLength;
|
||||
v.Type = resource.Type;
|
||||
v.Key = resource.Key;
|
||||
Var v = new Var(resource);
|
||||
|
||||
var tempValue = new List<LanguageCodePage>();
|
||||
while (stream.Position - originalPosition < v.Length)
|
||||
@@ -44,16 +47,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
public static new Var Deserialize(byte[] content, ref int offset)
|
||||
{
|
||||
int originalPosition = offset;
|
||||
Var v = new Var();
|
||||
|
||||
Resource resource = Resource.Deserialize(content, ref offset);
|
||||
if (resource.Key != "Translation")
|
||||
return null;
|
||||
|
||||
v.Length = resource.Length;
|
||||
v.ValueLength = resource.ValueLength;
|
||||
v.Type = resource.Type;
|
||||
v.Key = resource.Key;
|
||||
Var v = new Var(resource);
|
||||
|
||||
var tempValue = new List<LanguageCodePage>();
|
||||
while (offset - originalPosition < v.Length)
|
||||
|
||||
@@ -9,18 +9,21 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
/// </summary>
|
||||
public Var Children;
|
||||
|
||||
public VarFileInfo(Resource resource)
|
||||
{
|
||||
this.Length = resource?.Length ?? default;
|
||||
this.ValueLength = resource?.ValueLength ?? default;
|
||||
this.Type = resource?.Type ?? default;
|
||||
this.Key = resource?.Key ?? default;
|
||||
}
|
||||
|
||||
public static new VarFileInfo Deserialize(Stream stream)
|
||||
{
|
||||
VarFileInfo vfi = new VarFileInfo();
|
||||
|
||||
Resource resource = Resource.Deserialize(stream);
|
||||
if (resource.Key != "VarFileInfo")
|
||||
return null;
|
||||
|
||||
vfi.Length = resource.Length;
|
||||
vfi.ValueLength = resource.ValueLength;
|
||||
vfi.Type = resource.Type;
|
||||
vfi.Key = resource.Key;
|
||||
VarFileInfo vfi = new VarFileInfo(resource);
|
||||
vfi.Children = Var.Deserialize(stream);
|
||||
|
||||
return vfi;
|
||||
@@ -28,16 +31,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
|
||||
public static new VarFileInfo Deserialize(byte[] content, ref int offset)
|
||||
{
|
||||
VarFileInfo vfi = new VarFileInfo();
|
||||
|
||||
Resource resource = Resource.Deserialize(content, ref offset);
|
||||
if (resource.Key != "VarFileInfo")
|
||||
return null;
|
||||
|
||||
vfi.Length = resource.Length;
|
||||
vfi.ValueLength = resource.ValueLength;
|
||||
vfi.Type = resource.Type;
|
||||
vfi.Key = resource.Key;
|
||||
VarFileInfo vfi = new VarFileInfo(resource);
|
||||
vfi.Children = Var.Deserialize(content, ref offset);
|
||||
|
||||
return vfi;
|
||||
|
||||
@@ -23,19 +23,22 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
/// </summary>
|
||||
public VarFileInfo ChildrenVarFileInfo;
|
||||
|
||||
public VersionInfo(Resource resource)
|
||||
{
|
||||
this.Length = resource?.Length ?? default;
|
||||
this.ValueLength = resource?.ValueLength ?? default;
|
||||
this.Type = resource?.Type ?? default;
|
||||
this.Key = resource?.Key ?? default;
|
||||
}
|
||||
|
||||
public static new VersionInfo Deserialize(Stream stream)
|
||||
{
|
||||
long originalPosition = stream.Position;
|
||||
|
||||
VersionInfo vi = new VersionInfo();
|
||||
Resource resource = Resource.Deserialize(stream);
|
||||
if (resource.Key != "VS_VERSION_INFO")
|
||||
return null;
|
||||
|
||||
vi.Length = resource.Length;
|
||||
vi.ValueLength = resource.ValueLength;
|
||||
vi.Type = resource.Type;
|
||||
vi.Key = resource.Key;
|
||||
|
||||
VersionInfo vi = new VersionInfo(resource);
|
||||
|
||||
if (vi.ValueLength > 0)
|
||||
vi.Value = FixedFileInfo.Deserialize(stream);
|
||||
@@ -78,16 +81,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Resources
|
||||
public static new VersionInfo Deserialize(byte[] content, ref int offset)
|
||||
{
|
||||
int originalOffset = offset;
|
||||
|
||||
VersionInfo vi = new VersionInfo();
|
||||
Resource resource = Resource.Deserialize(content, ref offset);
|
||||
if (resource.Key != "VS_VERSION_INFO")
|
||||
return null;
|
||||
|
||||
vi.Length = resource.Length;
|
||||
vi.ValueLength = resource.ValueLength;
|
||||
vi.Type = resource.Type;
|
||||
vi.Key = resource.Key;
|
||||
VersionInfo vi = new VersionInfo(resource);
|
||||
|
||||
if (vi.ValueLength > 0)
|
||||
vi.Value = FixedFileInfo.Deserialize(content, ref offset);
|
||||
|
||||
@@ -24,11 +24,11 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
string name = Utilities.GetInternalName(pex);
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.Equals("Wextract", StringComparison.OrdinalIgnoreCase))
|
||||
return $"Microsoft CAB SFX v{Utilities.GetFileVersion(pex)}".TrimEnd('v');
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
|
||||
name = Utilities.GetOriginalFileName(pex);
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.Equals("WEXTRACT.EXE", StringComparison.OrdinalIgnoreCase))
|
||||
return $"Microsoft CAB SFX v{Utilities.GetFileVersion(pex)}".TrimEnd('v');
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
|
||||
// Get the .data section, if it exists
|
||||
if (pex.DataSectionRaw != null)
|
||||
@@ -45,7 +45,7 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return $"Microsoft CAB SFX v{Utilities.GetFileVersion(pex)}".TrimEnd('v');
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
}
|
||||
|
||||
// Get the .text section, if it exists
|
||||
@@ -61,7 +61,7 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.TextSectionRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return $"Microsoft CAB SFX v{Utilities.GetFileVersion(pex)}".TrimEnd('v');
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -84,5 +84,18 @@ namespace BurnOutSharp.PackerType
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
string version = Utilities.GetFileVersion(pex);
|
||||
if (!string.IsNullOrWhiteSpace(version))
|
||||
return $"v{version}";
|
||||
|
||||
version = Utilities.GetManifestVersion(pex);
|
||||
if (!string.IsNullOrWhiteSpace(version))
|
||||
return $"v{version}";
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,21 +126,17 @@ namespace BurnOutSharp.Tools
|
||||
/// </summary>
|
||||
public static string ReadString(this byte[] content, ref int offset, Encoding encoding)
|
||||
{
|
||||
// TODO: Fix the code below to make it work with byte arrays and not streams
|
||||
return null;
|
||||
byte[] nullTerminator = encoding.GetBytes(new char[] { '\0' });
|
||||
int charWidth = nullTerminator.Length;
|
||||
|
||||
// byte[] nullTerminator = encoding.GetBytes(new char[] { '\0' });
|
||||
// int charWidth = nullTerminator.Length;
|
||||
List<char> keyChars = new List<char>();
|
||||
while (BitConverter.ToUInt16(content, offset) != 0x0000)
|
||||
{
|
||||
keyChars.Add(encoding.GetChars(content, offset, charWidth)[0]); offset += charWidth;
|
||||
}
|
||||
offset += 2;
|
||||
|
||||
// List<byte> tempBuffer = new List<byte>();
|
||||
|
||||
// byte[] buffer = new byte[charWidth];
|
||||
// while (stream.Read(buffer, 0, charWidth) != 0 && buffer.SequenceEqual(nullTerminator))
|
||||
// {
|
||||
// tempBuffer.AddRange(buffer);
|
||||
// }
|
||||
|
||||
// return encoding.GetString(tempBuffer.ToArray());
|
||||
return new string(keyChars.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user