diff --git a/BurnOutSharp.Wrappers/PortableExecutable.cs b/BurnOutSharp.Wrappers/PortableExecutable.cs index b76305e0..f104e90f 100644 --- a/BurnOutSharp.Wrappers/PortableExecutable.cs +++ b/BurnOutSharp.Wrappers/PortableExecutable.cs @@ -577,6 +577,31 @@ namespace BurnOutSharp.Wrappers } } + /// + /// Dictionary of debug data + /// + public Dictionary DebugData + { + get + { + lock (_sourceDataLock) + { + // Use the cached data if possible + if (_debugData != null && _debugData.Count != 0) + return _debugData; + + // If we have no resource table, just return + if (DebugTable?.DebugDirectoryTable == null + || DebugTable.DebugDirectoryTable.Length == 0) + return null; + + // Otherwise, build and return the cached dictionary + ParseDebugTable(); + return _debugData; + } + } + } + /// /// Dictionary of resource data /// @@ -592,12 +617,12 @@ namespace BurnOutSharp.Wrappers // If we have no resource table, just return if (OH_ResourceTable == null - || _executable.OptionalHeader.ResourceTable.VirtualAddress == 0 - || _executable.ResourceDirectoryTable == null) + || OH_ResourceTable.VirtualAddress == 0 + || ResourceDirectoryTable == null) return null; // Otherwise, build and return the cached dictionary - ParseResourceDirectoryTable(_executable.ResourceDirectoryTable, types: new List()); + ParseResourceDirectoryTable(ResourceDirectoryTable, types: new List()); return _resourceData; } } @@ -807,6 +832,11 @@ namespace BurnOutSharp.Wrappers /// private List[] _tableStringData = null; + /// + /// Cached debug data + /// + private readonly Dictionary _debugData = new Dictionary(); + /// /// Cached resource data /// @@ -2773,6 +2803,75 @@ namespace BurnOutSharp.Wrappers #endregion + #region Debug Data + + /// + /// Find unparsed debug data by string value + /// + /// String value to check for + /// Enumerable of matching debug data + public IEnumerable FindDebugTableByValue(string value) + { + // Ensure that we have the resource data cached + if (DebugData == null) + return Enumerable.Empty(); + + return DebugData.Select(r => r.Value) + .Where(b => b != null) + .Where(b => + { + try + { + string arrayAsASCII = Encoding.ASCII.GetString(b); + if (arrayAsASCII.Contains(value)) + return true; + } + catch { } + + try + { + string arrayAsUTF8 = Encoding.UTF8.GetString(b); + if (arrayAsUTF8.Contains(value)) + return true; + } + catch { } + + try + { + string arrayAsUnicode = Encoding.Unicode.GetString(b); + if (arrayAsUnicode.Contains(value)) + return true; + } + catch { } + + return false; + }); + } + + #endregion + + #region Debug Parsing + + /// + /// Parse the debug directory table information + /// + private void ParseDebugTable() + { + // Loop through all debug table entries + for (int i = 0; i < DebugTable.DebugDirectoryTable.Length; i++) + { + var entry = DebugTable.DebugDirectoryTable[i]; + + uint address = entry.PointerToRawData; + uint size = entry.SizeOfData; + + byte[] entryData = ReadFromDataSource((int)address, (int)size); + _debugData[i] = entryData; + } + } + + #endregion + #region Resource Data ///