Clean up PE string table parsing

This commit is contained in:
Matt Nadareski
2022-11-09 14:27:32 -08:00
parent 4fcb719613
commit 6b14321505
2 changed files with 54 additions and 15 deletions

View File

@@ -418,6 +418,47 @@ namespace BurnOutSharp.Builder
return table;
}
/// <summary>
/// Read resource data as a string table resource
/// </summary>
/// <param name="data">Resource data entry to parse into a string table resource</param>
/// <returns>A filled string table resource on success, null on error</returns>
public static Dictionary<int, string> AsStringTable(this Models.PortableExecutable.ResourceDataEntry entry)
{
// If we have an invalid entry, just skip
if (entry?.Data == null)
return null;
// Initialize the iterators
int offset = 0, stringIndex = 0;
// Create the output table
var stringTable = new Dictionary<int, string>();
// Create the string encoding
Encoding stringEncoding = (entry.Codepage != 0 ? Encoding.GetEncoding((int)entry.Codepage) : Encoding.Unicode);
// Loop through and add
while (offset < entry.Data.Length)
{
ushort stringLength = entry.Data.ReadUInt16(ref offset);
if (stringLength == 0)
{
stringTable[stringIndex++] = "[EMPTY]";
}
else
{
string fullEncodedString = stringEncoding.GetString(entry.Data, offset, entry.Data.Length - offset);
string stringValue = fullEncodedString.Substring(0, stringLength);
offset += stringEncoding.GetByteCount(stringValue);
stringValue = stringValue.Replace("\n", "\\n").Replace("\r", "\\r");
stringTable[stringIndex++] = stringValue;
}
}
return stringTable;
}
#endregion
}
}

View File

@@ -880,22 +880,16 @@ namespace ExecutableTest
Console.WriteLine($"{padding}Dialog box found, not parsed yet");
break;
case BurnOutSharp.Models.PortableExecutable.ResourceType.RT_STRING:
int stringIndex = 0;
Encoding stringEncoding = (entry.Codepage != 0 ? Encoding.GetEncoding((int)entry.Codepage) : Encoding.Unicode);
while (offset < entry.Data.Length)
var stringTable = entry.AsStringTable();
if (stringTable == null)
{
ushort stringLength = entry.Data.ReadUInt16(ref offset);
if (stringLength == 0)
Console.WriteLine($"{padding}String table resource found, but malformed");
}
else
{
foreach ((int index, string stringValue) in stringTable)
{
Console.WriteLine($"{padding}String entry {stringIndex++} ({stringLength}): [EMPTY]");
}
else
{
string fullEncodedString = stringEncoding.GetString(entry.Data, offset, entry.Data.Length - offset);
string stringValue = fullEncodedString.Substring(0, stringLength);
offset += stringEncoding.GetByteCount(stringValue);
stringValue = stringValue.Replace("\n", "\\n").Replace("\r", "\\r");
Console.WriteLine($"{padding}String entry {stringIndex++} ({stringLength}): {stringValue}");
Console.WriteLine($"{padding}String entry {index}: {stringValue}");
}
}
break;
@@ -907,7 +901,11 @@ namespace ExecutableTest
break;
case BurnOutSharp.Models.PortableExecutable.ResourceType.RT_ACCELERATOR:
var acceleratorTable = entry.Data.AsAcceleratorTableResource(ref offset);
if (acceleratorTable != null)
if (acceleratorTable == null)
{
Console.WriteLine($"{padding}Accelerator table resource found, but malformed");
}
else
{
for (int i = 0; i < acceleratorTable.Length; i++)
{