Skip to content

Commit

Permalink
Add support for #JTD stream for EnC metadata in Hex editor
Browse files Browse the repository at this point in the history
  • Loading branch information
ElektroKill committed Jul 5, 2023
1 parent 19a3d84 commit dd65443
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 12 deletions.
7 changes: 6 additions & 1 deletion dnSpy/dnSpy.Contracts.DnSpy/Hex/Files/DotNet/DotNetHeap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected DotNetHeap(HexBufferSpan span, DotNetHeapKind heapKind) {
public abstract DotNetMetadataHeaders Metadata { get; }

/// <summary>
/// Gets a structure or null
/// Gets a structure or null
/// </summary>
/// <param name="position">Position</param>
/// <returns></returns>
Expand Down Expand Up @@ -137,6 +137,11 @@ public abstract class TablesHeap : DotNetHeap {
/// </summary>
public abstract ulong SortedMask { get; }

/// <summary>
/// All columns that can be 2 or 4 bytes are forced to be 4 bytes.
/// </summary>
public abstract bool ForceAllBigColumns { get; }

/// <summary>
/// Constructor
/// </summary>
Expand Down
9 changes: 8 additions & 1 deletion dnSpy/dnSpy/Hex/Files/DotNet/DotNetHeapsReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ DotNetHeap[] CreateENCHeaps() {
USHeap? usHeap = null;
BlobHeap? blobHeap = null;
GUIDHeap? guidHeap = null;
TablesHeap? tablesHeap = null;
TablesHeapImpl? tablesHeap = null;
bool forceAllBig = false;
foreach (var ssh in storageStreamHeaders) {
var span = new HexBufferSpan(file.Buffer, ssh.DataSpan);

Expand Down Expand Up @@ -166,6 +167,11 @@ DotNetHeap[] CreateENCHeaps() {
}
break;

case "#JTD":
forceAllBig = true;
list.Add(new UnknownHeapImpl(span));
continue;

case "#~": // Only if #Schema is used
case "#-":
if (tablesHeap is null && span.Length >= TablesHeapImpl.MinimumSize) {
Expand All @@ -177,6 +183,7 @@ DotNetHeap[] CreateENCHeaps() {
}
list.Add(new UnknownHeapImpl(span));
}
tablesHeap?.SetForceAllBigColumns(forceAllBig);
return list.ToArray();
}

Expand Down
21 changes: 12 additions & 9 deletions dnSpy/dnSpy/Hex/Files/DotNet/DotNetTableSizes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ sealed class DotNetTableSizes {
bool bigStrings;
bool bigGuid;
bool bigBlob;
bool forceAllBig;
uint[]? rowCounts;
TableInfo[]? tableInfos;

Expand All @@ -41,11 +42,13 @@ sealed class DotNetTableSizes {
/// <param name="bigGuid"><c>true</c> if #GUID size >= 0x10000</param>
/// <param name="bigBlob"><c>true</c> if #Blob size >= 0x10000</param>
/// <param name="rowCounts">Count of rows in each table</param>
public void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, uint[] rowCounts) {
/// <param name="forceAllBig">Force all columns to 4 bytes instead of 2 or 4 bytes</param>
public void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, uint[] rowCounts, bool forceAllBig) {
Debug2.Assert(tableInfos is not null);
this.bigStrings = bigStrings;
this.bigGuid = bigGuid;
this.bigBlob = bigBlob;
this.bigStrings = bigStrings || forceAllBig;
this.bigGuid = bigGuid || forceAllBig;
this.bigBlob = bigBlob || forceAllBig;
this.forceAllBig = forceAllBig;
this.rowCounts = rowCounts;
for (int i = 0; i < tableInfos.Length; i++) {
var tableInfo = tableInfos[i];
Expand All @@ -67,7 +70,7 @@ int GetSize(ColumnSize columnSize) {
if (ColumnSize.Module <= columnSize && columnSize <= ColumnSize.CustomDebugInformation) {
int table = (int)(columnSize - ColumnSize.Module);
uint count = table >= rowCounts.Length ? 0 : rowCounts[table];
return count > 0xFFFF ? 4 : 2;
return forceAllBig || count > 0xFFFF ? 4 : 2;
}
else if (ColumnSize.TypeDefOrRef <= columnSize && columnSize <= ColumnSize.HasCustomDebugInformation) {
CodedToken info;
Expand Down Expand Up @@ -97,7 +100,7 @@ int GetSize(ColumnSize columnSize) {
}
// Can't overflow since maxRows <= 0x00FFFFFF and info.Bits < 8
uint finalRows = maxRows << info.Bits;
return finalRows > 0xFFFF ? 4 : 2;
return forceAllBig || finalRows > 0xFFFF ? 4 : 2;
}
else {
switch (columnSize) {
Expand All @@ -106,9 +109,9 @@ int GetSize(ColumnSize columnSize) {
case ColumnSize.UInt16: return 2;
case ColumnSize.Int32: return 4;
case ColumnSize.UInt32: return 4;
case ColumnSize.Strings:return bigStrings ? 4 : 2;
case ColumnSize.GUID: return bigGuid ? 4 : 2;
case ColumnSize.Blob: return bigBlob ? 4 : 2;
case ColumnSize.Strings:return forceAllBig || bigStrings ? 4 : 2;
case ColumnSize.GUID: return forceAllBig || bigGuid ? 4 : 2;
case ColumnSize.Blob: return forceAllBig || bigBlob ? 4 : 2;
}
}
throw new InvalidOperationException($"Invalid ColumnSize: {columnSize}");
Expand Down
7 changes: 6 additions & 1 deletion dnSpy/dnSpy/Hex/Files/DotNet/TablesHeapImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ public override ulong SortedMask {
}
}

public override bool ForceAllBigColumns => forceAllBigColumns;

internal void SetForceAllBigColumns(bool value) => forceAllBigColumns = value;

bool initialized;
HexSpan headerSpan;
HexSpan tablesSpan;
Expand All @@ -114,6 +118,7 @@ public override ulong SortedMask {
byte log2Rid;
ulong validMask;
ulong sortedMask;
bool forceAllBigColumns;
uint extraData;
MDTable[]? mdTables;
ReadOnlyCollection<MDTable>? mdTablesReadOnly;
Expand Down Expand Up @@ -177,7 +182,7 @@ void Initialize() {

headerSpan = HexSpan.FromBounds(Span.Span.Start, pos);

dnTableSizes.InitializeSizes((flags & MDStreamFlags.BigStrings) != 0, (flags & MDStreamFlags.BigGUID) != 0, (flags & MDStreamFlags.BigBlob) != 0, sizes);
dnTableSizes.InitializeSizes((flags & MDStreamFlags.BigStrings) != 0, (flags & MDStreamFlags.BigGUID) != 0, (flags & MDStreamFlags.BigBlob) != 0, sizes, forceAllBigColumns);
mdTables = new MDTable[tableInfos.Length];
mdTablesReadOnly = new ReadOnlyCollection<MDTable>(mdTables);
tableRecordDataFactories = new TableRecordDataFactory[tableInfos.Length];
Expand Down

0 comments on commit dd65443

Please sign in to comment.