/// <summary>Returns the signature blob identified by a metadata token.</summary> /// <returns>An array of bytes representing the signature blob.</returns> /// <param name="metadataToken">A metadata token that identifies a signature in the module.</param> /// <exception cref="T:System.ArgumentException"> /// <paramref name="metadataToken" /> is not a valid MemberRef, MethodDef, TypeSpec, signature, or FieldDef token in the scope of the current module.</exception> /// <exception cref="T:System.ArgumentOutOfRangeException"> /// <paramref name="metadataToken" /> is not a valid token in the scope of the current module.</exception> public byte[] ResolveSignature(int metadataToken) { ResolveTokenError error; byte[] array = Module.ResolveSignature(this._impl, metadataToken, out error); if (array == null) { throw this.resolve_token_exception(metadataToken, error, "signature"); } return(array); }
/// <summary> /// Constructs the array of ILInstructions according to the IL byte code. /// </summary> /// <param name="module"></param> private void ConstructInstructions(Module module) { byte[] il = this.il; int position = 0; instructions = new List<ILInstruction>(); while (position < il.Length) { ILInstruction instruction = new ILInstruction(); // get the operation code of the current instruction OpCode code = OpCodes.Nop; ushort value = il[position++]; if (value != 0xfe) { code = Globals.singleByteOpCodes[(int)value]; } else { value = il[position++]; code = Globals.multiByteOpCodes[(int)value]; value = (ushort)(value | 0xfe00); } instruction.Code = code; instruction.Offset = position - 1; int metadataToken = 0; // get the operand of the current operation switch (code.OperandType) { case OperandType.InlineBrTarget: metadataToken = ReadInt32(il, ref position); metadataToken += position; instruction.Operand = metadataToken; break; // patched from comments on CP -hwd case OperandType.InlineField: metadataToken = ReadInt32(il, ref position); if (mi is ConstructorInfo) { instruction.Operand = module.ResolveField(metadataToken, mi.DeclaringType.GetGenericArguments(), null); } else { instruction.Operand = module.ResolveField(metadataToken, mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments()); } break; // patched from comments on CP -hwd case OperandType.InlineMethod: metadataToken = ReadInt32(il, ref position); try { if (mi is ConstructorInfo) { instruction.Operand = module.ResolveMethod(metadataToken, mi.DeclaringType.GetGenericArguments(), null); } else { instruction.Operand = module.ResolveMethod(metadataToken, mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments()); } } catch { if (mi is ConstructorInfo) { instruction.Operand = module.ResolveMember(metadataToken, mi.DeclaringType.GetGenericArguments(), null); } else { instruction.Operand = module.ResolveMember(metadataToken, mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments()); } } break; case OperandType.InlineSig: metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveSignature(metadataToken); break; // patched from comments on CP -hwd case OperandType.InlineTok: metadataToken = ReadInt32(il, ref position); //try //{ if (mi is ConstructorInfo) { instruction.Operand = module.ResolveType(metadataToken, mi.DeclaringType.GetGenericArguments(), null); } else { instruction.Operand = module.ResolveType(metadataToken, mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments()); } //} //catch //{ // int i = 1; //} break; // patched from comments on CP -hwd case OperandType.InlineType: metadataToken = ReadInt32(il, ref position); if (this.mi is MethodInfo) { instruction.Operand = module.ResolveType(metadataToken, this.mi.DeclaringType.GetGenericArguments(), this.mi.GetGenericArguments()); } else if (mi is ConstructorInfo) { instruction.Operand = module.ResolveType(metadataToken, this.mi.DeclaringType.GetGenericArguments(), null); } else { instruction.Operand = module.ResolveType(metadataToken); } break; case OperandType.InlineI: { instruction.Operand = ReadInt32(il, ref position); break; } case OperandType.InlineI8: { instruction.Operand = ReadInt64(il, ref position); break; } case OperandType.InlineNone: { instruction.Operand = null; break; } case OperandType.InlineR: { instruction.Operand = ReadDouble(il, ref position); break; } case OperandType.InlineString: { metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveString(metadataToken); break; } case OperandType.InlineSwitch: { int count = ReadInt32(il, ref position); int[] casesAddresses = new int[count]; for (int i = 0; i < count; i++) { casesAddresses[i] = ReadInt32(il, ref position); } int[] cases = new int[count]; for (int i = 0; i < count; i++) { cases[i] = position + casesAddresses[i]; } break; } case OperandType.InlineVar: { instruction.Operand = ReadUInt16(il, ref position); break; } case OperandType.ShortInlineBrTarget: { instruction.Operand = ReadSByte(il, ref position) + position; break; } case OperandType.ShortInlineI: { instruction.Operand = ReadSByte(il, ref position); break; } case OperandType.ShortInlineR: { instruction.Operand = ReadSingle(il, ref position); break; } case OperandType.ShortInlineVar: { instruction.Operand = ReadByte(il, ref position); break; } default: { throw new Exception("Unknown operand type."); } } instructions.Add(instruction); } }
/// <summary> /// Constructs the array of ILInstructions according to the IL byte code. /// </summary> /// <param name="module"></param> private void ConstructInstructions(Module module) { byte[] il = this.il; int position = 0; instructions = new List<ILInstruction>(); while (position < il.Length) { ILInstruction instruction = new ILInstruction(); // get the operation code of the current instruction OpCode code = OpCodes.Nop; ushort value = il[position++]; if (value != 0xfe) { code = Globals.singleByteOpCodes[(int)value]; } else { value = il[position++]; code = Globals.multiByteOpCodes[(int)value]; value = (ushort)(value | 0xfe00); } instruction.Code = code; instruction.Offset = position - 1; int metadataToken = 0; // get the operand of the current operation switch (code.OperandType) { case OperandType.InlineBrTarget: metadataToken = ReadInt32(il, ref position); metadataToken += position; instruction.Operand = metadataToken; break; case OperandType.InlineField: metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveField(metadataToken); break; case OperandType.InlineMethod: metadataToken = ReadInt32(il, ref position); try { instruction.Operand = module.ResolveMethod(metadataToken); } catch { try { instruction.Operand = module.ResolveMember(metadataToken); } catch (Exception) { //Try generic method try { instruction.Operand = module.ResolveMethod(metadataToken, mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments()); } catch (Exception) { //Try generic member try { instruction.Operand = module.ResolveMember(metadataToken, mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments()); } catch (Exception) { throw; } } } } break; case OperandType.InlineSig: metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveSignature(metadataToken); break; case OperandType.InlineTok: metadataToken = ReadInt32(il, ref position); try { instruction.Operand = module.ResolveType(metadataToken); } catch { } // SSS : see what to do here break; case OperandType.InlineType: metadataToken = ReadInt32(il, ref position); // now we call the ResolveType always using the generic attributes type in order // to support decompilation of generic methods and classes // thanks to the guys from code project who commented on this missing feature try { instruction.Operand = module.ResolveType(metadataToken); } catch (Exception) { instruction.Operand = module.ResolveType(metadataToken, this.mi.DeclaringType.GetGenericArguments(), this.mi.GetGenericArguments()); } break; case OperandType.InlineI: { instruction.Operand = ReadInt32(il, ref position); break; } case OperandType.InlineI8: { instruction.Operand = ReadInt64(il, ref position); break; } case OperandType.InlineNone: { instruction.Operand = null; break; } case OperandType.InlineR: { instruction.Operand = ReadDouble(il, ref position); break; } case OperandType.InlineString: { metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveString(metadataToken); break; } case OperandType.InlineSwitch: { int count = ReadInt32(il, ref position); int[] casesAddresses = new int[count]; for (int i = 0; i < count; i++) { casesAddresses[i] = ReadInt32(il, ref position); } int[] cases = new int[count]; for (int i = 0; i < count; i++) { cases[i] = position + casesAddresses[i]; } break; } case OperandType.InlineVar: { instruction.Operand = ReadUInt16(il, ref position); break; } case OperandType.ShortInlineBrTarget: { instruction.Operand = ReadSByte(il, ref position) + position; break; } case OperandType.ShortInlineI: { instruction.Operand = ReadSByte(il, ref position); break; } case OperandType.ShortInlineR: { instruction.Operand = ReadSingle(il, ref position); break; } case OperandType.ShortInlineVar: { instruction.Operand = ReadByte(il, ref position); break; } default: { throw new Exception("Unknown operand type."); } } instructions.Add(instruction); } }
private static int _ReadOperand(MethodBase This, OpCode code, int position, byte[] il, Module module, ILInstruction instruction) { int metadataToken; switch (code.OperandType) { case OperandType.InlineBrTarget: { metadataToken = ReadInt32(il, ref position); metadataToken += position; instruction.Operand = metadataToken; break; } case OperandType.InlineField: { metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveField(metadataToken); break; } case OperandType.InlineMethod: { metadataToken = ReadInt32(il, ref position); try { instruction.Operand = module.ResolveMethod(metadataToken); } catch { instruction.Operand = module.ResolveMember(metadataToken); } break; } case OperandType.InlineSig: { metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveSignature(metadataToken); break; } case OperandType.InlineTok: { metadataToken = ReadInt32(il, ref position); try { instruction.Operand = module.ResolveType(metadataToken); } catch { } // SSS : see what to do here break; } case OperandType.InlineType: { metadataToken = ReadInt32(il, ref position); // now we call the ResolveType always using the generic attributes type in order // to support decompilation of generic methods and classes // thanks to the guys from code project who commented on this missing feature instruction.Operand = module.ResolveType(metadataToken, This.DeclaringType.GetGenericArguments(), This.GetGenericArguments()); break; } case OperandType.InlineI: { instruction.Operand = ReadInt32(il, ref position); break; } case OperandType.InlineI8: { instruction.Operand = ReadInt64(il, ref position); break; } case OperandType.InlineNone: { instruction.Operand = null; break; } case OperandType.InlineR: { instruction.Operand = ReadDouble(il, ref position); break; } case OperandType.InlineString: { metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveString(metadataToken); break; } case OperandType.InlineSwitch: { var count = ReadInt32(il, ref position); var casesAddresses = new int[count]; for (var i = 0; i < count; i++) { casesAddresses[i] = ReadInt32(il, ref position); } var cases = new int[count]; for (var i = 0; i < count; i++) { cases[i] = position + casesAddresses[i]; } break; } case OperandType.InlineVar: { instruction.Operand = ReadUInt16(il, ref position); break; } case OperandType.ShortInlineBrTarget: { instruction.Operand = ReadSByte(il, ref position) + position; break; } case OperandType.ShortInlineI: { if (instruction.Code == OpCodes.Ldc_I4_S) { instruction.Operand = ReadSByte(il, ref position); } else { instruction.Operand = ReadByte(il, ref position); } break; } case OperandType.ShortInlineR: { instruction.Operand = ReadSingle(il, ref position); break; } case OperandType.ShortInlineVar: { instruction.Operand = ReadByte(il, ref position); break; } default: { throw new Exception("Unknown operand type."); } } return(position); }
private void ConstructInstructions(Module module) { byte[] localIlbytes = this.il; int position = 0; while (position < localIlbytes.Length) { var instruction = new ILInstruction(); // get the operation code of the current instruction OpCode code; ushort value = localIlbytes[position++]; if (GlobalIntermediateLanguageConstants.SingleByteOpCodes.Count == 0) { throw new InvalidOperationException( "Attempt to use Method Body Reader before Global Intermediate Language Constants has been initialised. Global Intermediate Language Constants. Load Op Codes must be called once."); } if (value != 0xfe) { code = GlobalIntermediateLanguageConstants.SingleByteOpCodes[value]; } else { value = localIlbytes[position++]; code = GlobalIntermediateLanguageConstants.MultiByteOpCodes[value]; } instruction.Code = code; instruction.Offset = position - 1; int metadataToken; // get the operand of the current operation switch (code.OperandType) { case OperandType.InlineBrTarget: metadataToken = ReadInt32(ref position); metadataToken += position; instruction.Operand = metadataToken; break; case OperandType.InlineField: // TODO All these try catch blocks need to go try { metadataToken = ReadInt32(ref position); instruction.Operand = module.ResolveField(metadataToken); } catch { instruction.Operand = new object(); } break; case OperandType.InlineMethod: metadataToken = ReadInt32(ref position); try { instruction.Operand = module.ResolveMethod(metadataToken); } catch { instruction.Operand = new object(); } break; case OperandType.InlineSig: metadataToken = ReadInt32(ref position); instruction.Operand = module.ResolveSignature(metadataToken); break; case OperandType.InlineTok: metadataToken = ReadInt32(ref position); try { instruction.Operand = module.ResolveType(metadataToken); } catch { } // TODO : see what to do here break; case OperandType.InlineType: metadataToken = ReadInt32(ref position); // now we call the ResolveType always using the generic attributes type in order // to support decompilation of generic methods and classes // thanks to the guys from code project who commented on this missing feature Type[] declaringTypeGenericArgs = this.mi.DeclaringType.GetGenericArguments(); Type[] genericArgs = null; if (this.mi.IsGenericMethod) { genericArgs = this.mi.GetGenericArguments(); } instruction.Operand = module.ResolveType(metadataToken, declaringTypeGenericArgs, genericArgs); break; case OperandType.InlineI: { instruction.Operand = ReadInt32(ref position); break; } case OperandType.InlineI8: { instruction.Operand = ReadInt64(ref position); break; } case OperandType.InlineNone: { instruction.Operand = null; break; } case OperandType.InlineR: { instruction.Operand = ReadDouble(ref position); break; } case OperandType.InlineString: { metadataToken = ReadInt32(ref position); instruction.Operand = module.ResolveString(metadataToken); break; } case OperandType.InlineSwitch: { int count = ReadInt32(ref position); var casesAddresses = new int[count]; for (int i = 0; i < count; i++) { casesAddresses[i] = ReadInt32(ref position); } var cases = new int[count]; for (int i = 0; i < count; i++) { cases[i] = position + casesAddresses[i]; } break; } case OperandType.InlineVar: { instruction.Operand = ReadUInt16(ref position); break; } case OperandType.ShortInlineBrTarget: { instruction.Operand = ReadSByte(ref position) + position; break; } case OperandType.ShortInlineI: { instruction.Operand = ReadSByte(ref position); break; } case OperandType.ShortInlineR: { instruction.Operand = ReadSingle(ref position); break; } case OperandType.ShortInlineVar: { instruction.Operand = ReadByte(ref position); break; } default: { throw new NotSupportedException("Unknown operand type."); } } this.instructions.Add(instruction); } }
public string ToString( Module module ) { OpCode opCode = OpCode; string operandStr = ""; int operandStart = _startIndex + opCode.Size; switch (opCode.OperandType) { case OperandType.InlineBrTarget: break; case OperandType.InlineField: operandStr = module.ResolveField(_il.GetInt32(operandStart)).Name; break; case OperandType.InlineI: operandStr = _il.GetInt32(operandStart).ToString(); break; case OperandType.InlineI8: operandStr = _il.GetInt64(operandStart).ToString(); break; case OperandType.InlineMethod: operandStr = module.ResolveMethod(_il.GetInt32(operandStart)).Name; break; case OperandType.InlineNone: break; case OperandType.InlineR: operandStr = _il.GetDouble(operandStart).ToString(); break; case OperandType.InlineSig: operandStr = string.Join("", module.ResolveSignature(_il.GetInt32(operandStart)) .Select(b => b.ToString("X2"))); break; case OperandType.InlineString: operandStr = "\"" + module.ResolveString(_il.GetInt32(operandStart)) + "\""; break; case OperandType.InlineSwitch: break; case OperandType.InlineTok: operandStr = module.ResolveType(_il.GetInt32(operandStart)).Name; break; case OperandType.InlineType: operandStr = module.ResolveType(_il.GetInt32(operandStart)).Name; break; case OperandType.InlineVar: operandStr = _il.GetInt16(operandStart).ToString(); break; case OperandType.ShortInlineBrTarget: break; case OperandType.ShortInlineI: operandStr = ((int) _il[operandStart]).ToString(); break; case OperandType.ShortInlineR: operandStr = _il.GetSingle(operandStart).ToString(); break; case OperandType.ShortInlineVar: operandStr = ((int) _il[operandStart]).ToString(); break; } return opCode.Name + " " + operandStr; }
private object ReadOperand(OpCode code, Module module, ref long localVariableIndex) { object operand = null; switch (code.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: int length = stream.ReadInt32(); int[] branches = new int[length]; int[] offsets = new int[length]; for (int i = 0; i < length; i++) { offsets[i] = stream.ReadInt32(); } for (int i = 0; i < length; i++) { branches[i] = (int)stream.BaseStream.Position + offsets[i]; } operand = (object) branches; // Just forget to save readed offsets break; case OperandType.ShortInlineBrTarget: if (code.FlowControl != FlowControl.Branch && code.FlowControl != FlowControl.Cond_Branch) { operand = stream.ReadSByte(); } else { operand = stream.ReadSByte() + stream.BaseStream.Position; } break; case OperandType.InlineBrTarget: operand = stream.ReadInt32()+ stream.BaseStream.Position;; break; case OperandType.ShortInlineI: if (code == OpCodes.Ldc_I4_S) operand = (sbyte)stream.ReadByte(); else operand = stream.ReadByte(); break; case OperandType.InlineI: operand = stream.ReadInt32(); break; case OperandType.ShortInlineR: operand = stream.ReadSingle(); break; case OperandType.InlineR: operand = stream.ReadDouble(); break; case OperandType.InlineI8: operand = stream.ReadInt64(); break; case OperandType.InlineSig: operand = module.ResolveSignature(stream.ReadInt32()); break; case OperandType.InlineString: operand = module.ResolveString(stream.ReadInt32()); break; case OperandType.InlineTok: case OperandType.InlineType: case OperandType.InlineMethod: case OperandType.InlineField: operand = module.ResolveMember(stream.ReadInt32(), typeArgs, methodArgs); break; case OperandType.ShortInlineVar: { int index = stream.ReadByte(); operand = GetVariable(code, index); localVariableIndex = index; } break; case OperandType.InlineVar: { int index = stream.ReadUInt16(); operand = GetVariable(code, index); localVariableIndex = index; } break; default: throw new NotSupportedException(); } return operand; }