Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You need to get the MethodInfo. Call GetMethodBody() to get the method body structure and then call GetILAsByteArray on that. The convert that byte array into a stream of comprehensible IL. </p> <p>Roughly speaking </p> <pre><code>public static List&lt;Instruction&gt; ReadIL(MethodInfo method) { MethodBody body = method.GetMethodBody(); if (body == null) return null; var instructions = new List&lt;Instruction&gt;(); int offset = 0; byte[] il = body.GetILAsByteArray(); while (offset &lt; il.Length) { int startOffset = offset; byte opCodeByte = il[offset]; short opCodeValue = opCodeByte; // If it's an extended opcode then grab the second byte. The 0xFE // prefix codes aren't marked as prefix operators though. if (OpCodeList[opCodeValue].OpCodeType == OpCodeType.Prefix || opCodeValue == 0xFE) { opCodeValue = (short) ((opCodeValue &lt;&lt; 8) + il[offset + 1]); offset += 1; } // Move to the first byte of the argument. offset += 1; OpCode code = OpCodeList[opCodeValue]; Int64? argument = null; if (code.ArgumentSize() &gt; 0) { Int64 arg = 0; Debug.Assert(code.ArgumentSize() &lt;= 8); for (int i = 0; i &lt; code.ArgumentSize(); ++i) { Int64 v = il[offset + i]; arg += v &lt;&lt; (i*8); } argument = arg; offset += code.ArgumentSize(); } var instruction = new Instruction(startOffset, code, argument); instructions.Add(instruction); } return instructions; } </code></pre> <p>where OpCodeList is constructed via</p> <pre><code>OpCodeList = new Dictionary&lt;short, OpCode&gt;(); foreach (var opCode in typeof (OpCodes).GetFields() .Where(f =&gt; f.FieldType == typeof (OpCode)) .Select(f =&gt; (OpCode) f.GetValue(null))) { OpCodeList.Add(opCode.Value, opCode); } </code></pre> <p>You can then work out which instructions are IL property calls or member variable look ups or whatever you require and resolve then via GetType().Module.ResolveField.</p> <p>(Caveat code above more or less work but was ripped from a bigger project I did so maybe missing minor details).</p> <p><strong>Edit:</strong> Argument size is an extension method on OpCode that just uses a look up table to do find the appropriate value</p> <pre><code>public static int ArgumentSize(this OpCode opCode) { Dictionary&lt;OperandType, int&gt; operandSizes = new Dictionary&lt;OperandType, int&gt;() { {OperandType.InlineBrTarget, 4}, {OperandType.InlineField, 4}, {OperandType.InlineI, 4}, // etc., etc. }; return operandSizes[opCode.OperandType]; } </code></pre> <p>You'll find sizes in <a href="http://www.ecma-international.org/publications/standards/Ecma-335.htm" rel="nofollow noreferrer">ECMA 335</a> which you'll also need to look at for the OpCodes to find which OpCodes you to search for to find the calls you are looking for.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload