mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-04-24 23:30:07 +00:00
Lock section names, scan for hidden resources
This commit is contained in:
@@ -300,7 +300,7 @@ namespace BurnOutSharp.Builders
|
||||
|
||||
// Try to parse the resource directory table
|
||||
data.Seek(resourceTableAddress, SeekOrigin.Begin);
|
||||
var resourceDirectoryTable = ParseResourceDirectoryTable(data, data.Position, executable.SectionTable);
|
||||
var resourceDirectoryTable = ParseResourceDirectoryTable(data, data.Position, executable.SectionTable, optionalHeader.ResourceTable.Size, true);
|
||||
if (resourceDirectoryTable == null)
|
||||
return null;
|
||||
|
||||
@@ -1195,8 +1195,10 @@ namespace BurnOutSharp.Builders
|
||||
/// <param name="data">Stream to parse</param>
|
||||
/// <param name="initialOffset">Initial offset to use in address comparisons</param>
|
||||
/// <param name="sections">Section table to use for virtual address translation</param>
|
||||
/// <param name="size">Indicates the size of the section, only used for top-level</param>
|
||||
/// <param name="topLevel">Indicates if this is the top level or not</param>
|
||||
/// <returns>Filled resource directory table on success, null on error</returns>
|
||||
private static ResourceDirectoryTable ParseResourceDirectoryTable(Stream data, long initialOffset, SectionHeader[] sections)
|
||||
private static ResourceDirectoryTable ParseResourceDirectoryTable(Stream data, long initialOffset, SectionHeader[] sections, uint size = 0, bool topLevel = false)
|
||||
{
|
||||
// TODO: Use marshalling here instead of building
|
||||
var resourceDirectoryTable = new ResourceDirectoryTable();
|
||||
@@ -1287,6 +1289,34 @@ namespace BurnOutSharp.Builders
|
||||
}
|
||||
}
|
||||
|
||||
// If we are not at the top level
|
||||
if (!topLevel)
|
||||
return resourceDirectoryTable;
|
||||
|
||||
// Align to the 1024-byte boundary
|
||||
while (data.Position - initialOffset < size && data.Position % 1024 != 0)
|
||||
_ = data.ReadByteValue();
|
||||
|
||||
// If we have not used up the full size, parse the remaining chunk as a single resource
|
||||
if (data.Position - initialOffset < size)
|
||||
{
|
||||
Array.Resize(ref resourceDirectoryTable.Entries, totalEntryCount + 1);
|
||||
int length = (int)(data.Position - initialOffset);
|
||||
|
||||
resourceDirectoryTable.Entries[totalEntryCount] = new ResourceDirectoryEntry
|
||||
{
|
||||
Name = new ResourceDirectoryString { UnicodeString = Encoding.ASCII.GetBytes("HIDDEN RESOURCE") },
|
||||
IntegerID = uint.MaxValue,
|
||||
DataEntryOffset = (uint)data.Position,
|
||||
DataEntry = new ResourceDataEntry
|
||||
{
|
||||
Size = (uint)length,
|
||||
Data = data.ReadBytes(length),
|
||||
Codepage = (uint)Encoding.Unicode.CodePage,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return resourceDirectoryTable;
|
||||
}
|
||||
|
||||
|
||||
@@ -563,23 +563,26 @@ namespace BurnOutSharp.Wrappers
|
||||
{
|
||||
get
|
||||
{
|
||||
// Use the cached data if possible
|
||||
if (_sectionNames != null)
|
||||
return _sectionNames;
|
||||
|
||||
// Otherwise, build and return the cached array
|
||||
_sectionNames = new string[_executable.SectionTable.Length];
|
||||
for (int i = 0; i < _sectionNames.Length; i++)
|
||||
lock (_sourceDataLock)
|
||||
{
|
||||
var section = _executable.SectionTable[i];
|
||||
// Use the cached data if possible
|
||||
if (_sectionNames != null)
|
||||
return _sectionNames;
|
||||
|
||||
// TODO: Handle long section names with leading `/`
|
||||
byte[] sectionNameBytes = section.Name;
|
||||
string sectionNameString = Encoding.UTF8.GetString(sectionNameBytes).TrimEnd('\0');
|
||||
_sectionNames[i] = sectionNameString;
|
||||
// Otherwise, build and return the cached array
|
||||
_sectionNames = new string[_executable.SectionTable.Length];
|
||||
for (int i = 0; i < _sectionNames.Length; i++)
|
||||
{
|
||||
var section = _executable.SectionTable[i];
|
||||
|
||||
// TODO: Handle long section names with leading `/`
|
||||
byte[] sectionNameBytes = section.Name;
|
||||
string sectionNameString = Encoding.UTF8.GetString(sectionNameBytes).TrimEnd('\0');
|
||||
_sectionNames[i] = sectionNameString;
|
||||
}
|
||||
|
||||
return _sectionNames;
|
||||
}
|
||||
|
||||
return _sectionNames;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3117,7 +3120,7 @@ namespace BurnOutSharp.Wrappers
|
||||
/// </summary>
|
||||
private void ParseResourceDirectoryTable(Models.PortableExecutable.ResourceDirectoryTable table, List<object> types)
|
||||
{
|
||||
int totalEntries = table.NumberOfNameEntries + table.NumberOfIDEntries;
|
||||
int totalEntries = table?.Entries?.Length ?? 0;
|
||||
for (int i = 0; i < totalEntries; i++)
|
||||
{
|
||||
var entry = table.Entries[i];
|
||||
|
||||
Reference in New Issue
Block a user