the last byte of API/library call instructions is always
It's because calls needs to have method (ref) as a parameter and methods are defined in the table that has an id of
Having bytes of the call like this
280600000A let's go one by one.
0x28 - is the value for opcode 'call' and it takes one operand.
- the rest of the opcode is the metadata token so basically the information which method should be called
0x0A is at the end? It should be read as a little-endian so the value should be
0x0A000006. But what are the bytes?
When CIL code uses metadata it does so through a metadata token. This is a 32-bit value where the top 8 bits identify the appropriate metadata table, and the remaining 24 bits give the index of the metadata in the table.
So the first value is the table id - and as I've mentioned the id of member's ref table is value
0x0A. And the rest is an index in the table (in our case
More about the tables? Those are basically part of .NET metadata information, that can be seen when you open one in i.e. dnSpy
As one can see
0x0A is assigned to the
MemberRef (containing both methods and fields references)
what about operands of ldstr instructions?
In this instance, the instruction has the following structure
0x70 indicates different stream - namely User defined strings or
#US. The rest (again interpreted as a little-ending 32-bit val) is the offset (in bytes) in
Generally dnSpy is a great tool to verifying those values as one can metadata tables.
The linked article (and the whole series is a great resource) it does explain (I think) the structure but maybe indirectly - just find the information about metadata token.
We can induce from it the whole structure of a metadata token.