diff --git a/BurnOutSharp.Wrappers/PortableExecutable.cs b/BurnOutSharp.Wrappers/PortableExecutable.cs
index a6146309..b76305e0 100644
--- a/BurnOutSharp.Wrappers/PortableExecutable.cs
+++ b/BurnOutSharp.Wrappers/PortableExecutable.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Net;
using System.Text;
using System.Xml;
using static BurnOutSharp.Builder.Extensions;
@@ -613,7 +614,7 @@ namespace BurnOutSharp.Wrappers
/// "Build signature"
///
public string BuildSignature => GetVersionInfoString("BuildSignature");
-
+
///
/// Additional information that should be displayed for diagnostic purposes.
///
@@ -796,6 +797,16 @@ namespace BurnOutSharp.Wrappers
///
private List[] _sectionStringData = null;
+ ///
+ /// Cached raw table data
+ ///
+ private byte[][] _tableData = null;
+
+ ///
+ /// Cached found string data in tables
+ ///
+ private List[] _tableStringData = null;
+
///
/// Cached resource data
///
@@ -3302,5 +3313,219 @@ namespace BurnOutSharp.Wrappers
}
#endregion
+
+ #region Tables
+
+ ///
+ /// Get the table data based on index, if possible
+ ///
+ /// Index of the table to check for
+ /// Table data on success, null on error
+ public byte[] GetTableData(int index)
+ {
+ // If the table doesn't exist
+ if (index < 0 || index > 16)
+ return null;
+
+ // Get the virtual address and size from the entries
+ uint virtualAddress = 0, size = 0;
+ switch (index)
+ {
+ case 1:
+ virtualAddress = OH_ExportTable.VirtualAddress;
+ size = OH_ExportTable.Size;
+ break;
+ case 2:
+ virtualAddress = OH_ImportTable.VirtualAddress;
+ size = OH_ImportTable.Size;
+ break;
+ case 3:
+ virtualAddress = OH_ResourceTable.VirtualAddress;
+ size = OH_ResourceTable.Size;
+ break;
+ case 4:
+ virtualAddress = OH_ExceptionTable.VirtualAddress;
+ size = OH_ExceptionTable.Size;
+ break;
+ case 5:
+ virtualAddress = OH_CertificateTable.VirtualAddress;
+ size = OH_CertificateTable.Size;
+ break;
+ case 6:
+ virtualAddress = OH_BaseRelocationTable.VirtualAddress;
+ size = OH_BaseRelocationTable.Size;
+ break;
+ case 7:
+ virtualAddress = OH_Debug.VirtualAddress;
+ size = OH_Debug.Size;
+ break;
+ case 8: // Architecture Table
+ virtualAddress = 0;
+ size = 0;
+ break;
+ case 9:
+ virtualAddress = OH_GlobalPtr.VirtualAddress;
+ size = OH_GlobalPtr.Size;
+ break;
+ case 10:
+ virtualAddress = OH_ThreadLocalStorageTable.VirtualAddress;
+ size = OH_ThreadLocalStorageTable.Size;
+ break;
+ case 11:
+ virtualAddress = OH_LoadConfigTable.VirtualAddress;
+ size = OH_LoadConfigTable.Size;
+ break;
+ case 12:
+ virtualAddress = OH_BoundImport.VirtualAddress;
+ size = OH_BoundImport.Size;
+ break;
+ case 13:
+ virtualAddress = OH_ImportAddressTable.VirtualAddress;
+ size = OH_ImportAddressTable.Size;
+ break;
+ case 14:
+ virtualAddress = OH_DelayImportDescriptor.VirtualAddress;
+ size = OH_DelayImportDescriptor.Size;
+ break;
+ case 15:
+ virtualAddress = OH_CLRRuntimeHeader.VirtualAddress;
+ size = OH_CLRRuntimeHeader.Size;
+ break;
+ case 16: // Reserved
+ virtualAddress = 0;
+ size = 0;
+ break;
+ }
+
+ // Get the physical address from the virtual one
+ uint address = virtualAddress.ConvertVirtualAddress(SectionTable);
+ if (address == 0 || size == 0)
+ return null;
+
+ lock(_sourceDataLock)
+ {
+ // Create the table data array if we have to
+ if (_tableData == null)
+ _tableData = new byte[16][];
+
+ // If we already have cached data, just use that immediately
+ if (_tableData[index] != null)
+ return _tableData[index];
+
+ // Populate the raw table data based on the source
+ byte[] tableData = ReadFromDataSource((int)address, (int)size);
+
+ // Cache and return the table data, even if null
+ _tableData[index] = tableData;
+ return tableData;
+ }
+ }
+
+ ///
+ /// Get the table strings based on index, if possible
+ ///
+ /// Index of the table to check for
+ /// Table strings on success, null on error
+ public List GetTableStrings(int index)
+ {
+ // If the table doesn't exist
+ if (index < 0 || index > 16)
+ return null;
+
+ // Get the virtual address and size from the entries
+ uint virtualAddress = 0, size = 0;
+ switch (index)
+ {
+ case 1:
+ virtualAddress = OH_ExportTable.VirtualAddress;
+ size = OH_ExportTable.Size;
+ break;
+ case 2:
+ virtualAddress = OH_ImportTable.VirtualAddress;
+ size = OH_ImportTable.Size;
+ break;
+ case 3:
+ virtualAddress = OH_ResourceTable.VirtualAddress;
+ size = OH_ResourceTable.Size;
+ break;
+ case 4:
+ virtualAddress = OH_ExceptionTable.VirtualAddress;
+ size = OH_ExceptionTable.Size;
+ break;
+ case 5:
+ virtualAddress = OH_CertificateTable.VirtualAddress;
+ size = OH_CertificateTable.Size;
+ break;
+ case 6:
+ virtualAddress = OH_BaseRelocationTable.VirtualAddress;
+ size = OH_BaseRelocationTable.Size;
+ break;
+ case 7:
+ virtualAddress = OH_Debug.VirtualAddress;
+ size = OH_Debug.Size;
+ break;
+ case 8: // Architecture Table
+ virtualAddress = 0;
+ size = 0;
+ break;
+ case 9:
+ virtualAddress = OH_GlobalPtr.VirtualAddress;
+ size = OH_GlobalPtr.Size;
+ break;
+ case 10:
+ virtualAddress = OH_ThreadLocalStorageTable.VirtualAddress;
+ size = OH_ThreadLocalStorageTable.Size;
+ break;
+ case 11:
+ virtualAddress = OH_LoadConfigTable.VirtualAddress;
+ size = OH_LoadConfigTable.Size;
+ break;
+ case 12:
+ virtualAddress = OH_BoundImport.VirtualAddress;
+ size = OH_BoundImport.Size;
+ break;
+ case 13:
+ virtualAddress = OH_ImportAddressTable.VirtualAddress;
+ size = OH_ImportAddressTable.Size;
+ break;
+ case 14:
+ virtualAddress = OH_DelayImportDescriptor.VirtualAddress;
+ size = OH_DelayImportDescriptor.Size;
+ break;
+ case 15:
+ virtualAddress = OH_CLRRuntimeHeader.VirtualAddress;
+ size = OH_CLRRuntimeHeader.Size;
+ break;
+ case 16: // Reserved
+ virtualAddress = 0;
+ size = 0;
+ break;
+ }
+
+ // Get the physical address from the virtual one
+ uint address = virtualAddress.ConvertVirtualAddress(SectionTable);
+ if (address == 0 || size == 0)
+ return null;
+
+ lock (_sourceDataLock)
+ {
+ // Create the table string array if we have to
+ if (_tableStringData == null)
+ _tableStringData = new List[16];
+
+ // If we already have cached data, just use that immediately
+ if (_tableStringData[index] != null)
+ return _tableStringData[index];
+
+ // Populate the table string data based on the source
+ List tableStringData = ReadStringsFromDataSource((int)address, (int)size);
+
+ // Cache and return the table string data, even if null
+ _tableStringData[index] = tableStringData;
+ return tableStringData;
+ }
+ }
+
+ #endregion
}
}
\ No newline at end of file