|
Range ReadListRange (uint current_index, Table current, Table target) |
|
{ |
|
var list = new Range (); |
|
|
|
var start = ReadTableIndex (target); |
|
if (start == 0) |
|
return list; |
|
|
|
uint next_index; |
|
var current_table = image.TableHeap [current]; |
|
|
|
if (current_index == current_table.Length) |
|
next_index = image.TableHeap [target].Length + 1; |
|
else { |
|
var position = this.position; |
|
this.position += (int) (current_table.RowSize - image.GetTableIndexSize (target)); |
|
next_index = ReadTableIndex (target); |
|
this.position = position; |
|
} |
|
|
|
list.Start = start; |
|
list.Length = next_index - start; |
|
|
|
return list; |
|
} |
(Sorry but I'm unable to provide a sample dll.)
We have a big dll which exactly has 65535 parameters in metadata table.

When processing it using cecil, it throw exception like this:
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
at Mono.Collections.Generic.Collection`1[T].get_Item (System.Int32 index)
at Mono.Cecil.MetadataReader.ReadParameter (System.UInt32 param_rid, Mono.Cecil.MethodDefinition method)
at Mono.Cecil.MetadataReader.ReadParameters (Mono.Cecil.MethodDefinition method, Mono.Cecil.Range param_range)
at Mono.Cecil.MetadataReader.ReadMethod (System.UInt32 method_rid, Mono.Collections.Generic.Collection`1[T] methods)
at Mono.Cecil.MetadataReader.ReadMethods (Mono.Cecil.TypeDefinition type)
at Mono.Cecil.TypeDefinition+<>c.<get_Methods>b__43_0 (Mono.Cecil.TypeDefinition type, Mono.Cecil.MetadataReader reader)
at Mono.Cecil.ModuleDefinition.Read[TItem,TRet] (TRet& variable, TItem item, System.Func`3[T1,T2,TResult] read)
at Mono.Cecil.TypeDefinition.get_Methods ()
After some debugging I managed to locate the problem:
|
next_index = ReadTableIndex (target); |
When it's trying to read the 65535th (the last) param (it is used in a compiler-generated anonymous method), and image.GetTableIndexSize returns 2 (entry < 65536), ReadTableIndex returns 0, next_index = 0.
|
list.Length = next_index - start; |
list.Length = next_index - start = 0u - 65535u = 4294901761 💥

On the other hand, dnlib already handled this problem, so it still works for our dll:
https://github.com/0xd4d/dnlib/blob/97e07a8f1ea0ccbf31231dad0f7cb093805b8eee/src/DotNet/MD/CompressedMetadata.cs#L143-L157
The magic happens here:

cecil/Mono.Cecil/AssemblyReader.cs
Lines 979 to 1003 in ba9c6c7
(Sorry but I'm unable to provide a sample dll.)
We have a big dll which exactly has 65535 parameters in metadata table.

When processing it using cecil, it throw exception like this:
After some debugging I managed to locate the problem:
cecil/Mono.Cecil/AssemblyReader.cs
Line 995 in ba9c6c7
When it's trying to read the 65535th (the last) param (it is used in a compiler-generated anonymous method), and
image.GetTableIndexSizereturns 2 (entry < 65536),ReadTableIndexreturns 0,next_index = 0.cecil/Mono.Cecil/AssemblyReader.cs
Line 1000 in ba9c6c7
list.Length = next_index - start = 0u - 65535u = 4294901761💥On the other hand, dnlib already handled this problem, so it still works for our dll:
https://github.com/0xd4d/dnlib/blob/97e07a8f1ea0ccbf31231dad0f7cb093805b8eee/src/DotNet/MD/CompressedMetadata.cs#L143-L157
The magic happens here:
