Starting Address: 0x290
iOffset: 0x6C
iSize: 0x104
rcName: #~
Starting Address: 0x29C
iOffset: 0x170
iSize: 0x100
rcName: #Strings
Starting Address: 0x2B0
iOffset: 0x270
iSize: 0x1C
rcName: #US
Starting Address: 0x2BC
iOffset: 0x28C
iSize: 0x10
rcName: #GUID
Starting Address: 0x2CC
iOffset: 0x29C
iSize: 0x50
rcName: #Blob
for the HelloWorld_CSC_2.0.exe file I tested it with. The first stream on the list is named #~ which means it is going to be fun to deal with because it is a compressed metadata stream. The .NET IL Assembler book has a nifty drawing showing all 5 of the streams above:
![]() |
Size
|
Field
|
Description
|
4 bytes
|
Reserved
|
Reserved; set to 0.
|
1 byte
|
Major
|
Major version of the
table schema (1 for v1.0 and v1.1; 2 for v2.0 or later).
|
1 byte
|
Minor
|
Minor version of the
table schema (0 for all versions).
|
1 byte
|
Heaps
|
Binary flags indicate
the offset sizes to be used within the heaps
.• 4-byte unsigned integer offset is indicated by 0x01 for a string heap, 0x02 for a GUID heap, and 0x04 for a blob heap .• If a flag is not set, the respective heap offset is a 2-byte unsigned integer .• A #- stream can also have special flags set: flag 0x20, indicating that the stream contains only changes made during an edit-and-continue session, and flag 0x80, indicating that the metadata might contain items marked as deleted. |
1 byte
|
Rid
|
Bit width of the
maximal record index to all tables of the metadata; calculated at run time
(during the metadata stream initialization).
|
8 bytes
|
MaskValid
|
Bit vector of present
tables, each bit representing one table (1 if present).
|
8 bytes
|
Sorted
|
Bit vector of sorted
tables, each bit representing a respective table (1 if sorted).
|
So, here is the code:
But there is a catch. The bits in the MaskValid represent tables, and this is followed by a bunch of 4 byte unsigned integers for each '1' representing the number of records in the table. I will work on that part next, this is good enough for now.
Keep compiling!