Open UlyssesWu opened 1 year ago
That's a good catch, thank you :)
The magic actually happens here in dnlib
:
uint endRid = !hasNext || (nextListRid == 0 && tableSourceRid + 1 == tableSource.Rows && tableDest.Rows == 0xFFFF) ? lastRid : nextListRid;
uint endRid = !hasNext || (nextListRid == 0 && tableSourceRid + 1 == tableSource.Rows && tableDest.Rows == 0xFFFF) ? lastRid : nextListRid;
Thanks for pointing out. In my situation, endRid
was set to 0 at this line. Then it was set to 65535
in L153, which I thought was the key to keep endRid - startRid
correct in L156.
https://github.com/jbevain/cecil/blob/ba9c6c79f5b82c68517cb005fb1174cea7805a64/Mono.Cecil/AssemblyReader.cs#L979-L1003
(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:
https://github.com/jbevain/cecil/blob/ba9c6c79f5b82c68517cb005fb1174cea7805a64/Mono.Cecil/AssemblyReader.cs#L995
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
.https://github.com/jbevain/cecil/blob/ba9c6c79f5b82c68517cb005fb1174cea7805a64/Mono.Cecil/AssemblyReader.cs#L1000
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: