/// <summary> /// Reads a non-plugged method. /// </summary> /// <param name="aMethodInfo">The method to read.</param> /// <returns>The new IL block for the method.</returns> public static ILBlock ReadNonPlugged(Types.MethodInfo aMethodInfo) { ILBlock result = new ILBlock() { TheMethodInfo = aMethodInfo }; MethodBody methodBody = aMethodInfo.MethodBody; //Method body for something like [DelegateType].Invoke() is null. // So just return an empty method if that is this case. if (methodBody != null) { foreach (LocalVariableInfo aLocal in methodBody.LocalVariables) { aMethodInfo.LocalInfos.Add(new Types.VariableInfo() { UnderlyingType = aLocal.LocalType, Position = aLocal.LocalIndex }); } byte[] ILBytes = methodBody.GetILAsByteArray(); int ILBytesPos = 0; while (ILBytesPos < ILBytes.Length) { OpCode currOpCode; ushort currOpCodeID = 0; int currOpBytesSize = 0; if (ILBytes[ILBytesPos] == 0xFE) { currOpCodeID = (ushort)(0xFE00 + (short)ILBytes[ILBytesPos + 1]); currOpBytesSize += 2; } else { currOpCodeID = (ushort)ILBytes[ILBytesPos]; currOpBytesSize++; } currOpCode = AllOpCodes[currOpCodeID]; int operandSize = 0; switch (currOpCode.OperandType) { #region Operands case OperandType.InlineBrTarget: operandSize = 4; break; case OperandType.InlineField: operandSize = 4; break; case OperandType.InlineI: operandSize = 4; break; case OperandType.InlineI8: operandSize = 8; break; case OperandType.InlineMethod: operandSize = 4; break; case OperandType.InlineNone: //No operands = no op size break; case OperandType.InlineR: operandSize = 8; break; case OperandType.InlineSig: operandSize = 4; break; case OperandType.InlineString: operandSize = 4; break; case OperandType.InlineSwitch: { uint count = Utilities.ReadUInt32(ILBytes, ILBytesPos + currOpBytesSize); currOpBytesSize += 4; operandSize = (int)(count * 4); } break; case OperandType.InlineTok: operandSize = 4; break; case OperandType.InlineType: operandSize = 4; break; case OperandType.InlineVar: operandSize = 2; break; case OperandType.ShortInlineBrTarget: operandSize = 1; break; case OperandType.ShortInlineI: operandSize = 1; break; case OperandType.ShortInlineR: operandSize = 4; break; case OperandType.ShortInlineVar: operandSize = 1; break; default: throw new Exception("Unrecognised operand type!"); #endregion } MethodBase methodToCall = null; byte[] valueBytes = new byte[operandSize]; if (operandSize > 0) { Array.Copy(ILBytes, ILBytesPos + currOpBytesSize, valueBytes, 0, operandSize); if (currOpCode.Equals(OpCodes.Call) || currOpCode.Equals(OpCodes.Calli) || currOpCode.Equals(OpCodes.Callvirt) || currOpCode.Equals(OpCodes.Ldftn) || currOpCode.Equals(OpCodes.Newobj)) { int MethodMetadataToken = Utilities.ReadInt32(valueBytes, 0); methodToCall = aMethodInfo.UnderlyingInfo.Module.ResolveMethod(MethodMetadataToken); } } result.ILOps.Add(new ILOp() { opCode = currOpCode, Offset = ILBytesPos, BytesSize = currOpBytesSize + operandSize, ValueBytes = valueBytes, MethodToCall = methodToCall }); ILBytesPos += currOpBytesSize + operandSize; } foreach (ExceptionHandlingClause aClause in methodBody.ExceptionHandlingClauses) { ExceptionHandledBlock exBlock = result.GetExactExceptionHandledBlock(aClause.TryOffset); if (exBlock == null) { exBlock = new ExceptionHandledBlock(); exBlock.Offset = aClause.TryOffset; exBlock.Length = aClause.TryLength; result.ExceptionHandledBlocks.Add(exBlock); } switch (aClause.Flags) { case ExceptionHandlingClauseOptions.Fault: case ExceptionHandlingClauseOptions.Clause: { CatchBlock catchBlock = new CatchBlock() { Offset = aClause.HandlerOffset, Length = aClause.HandlerLength, //Though not used, we may as well set it anyway FilterType = aClause.CatchType }; exBlock.CatchBlocks.Add(catchBlock); } break; case ExceptionHandlingClauseOptions.Finally: { FinallyBlock finallyBlock = new FinallyBlock() { Offset = aClause.HandlerOffset, Length = aClause.HandlerLength }; exBlock.FinallyBlocks.Add(finallyBlock); } break; default: Logger.LogError("IL0010", "", 0, "Exception handling clause not supported! Type: " + aClause.Flags.ToString()); break; } } } return(result); }
/// <summary> /// Reads a non-plugged method. /// </summary> /// <param name="aMethodInfo">The method to read.</param> /// <returns>The new IL block for the method.</returns> public static ILBlock ReadNonPlugged(Types.MethodInfo aMethodInfo) { ILBlock result = new ILBlock() { TheMethodInfo = aMethodInfo }; MethodBody methodBody = aMethodInfo.MethodBody; //Method body for something like [DelegateType].Invoke() is null. // So just return an empty method if that is this case. if (methodBody != null) { foreach (LocalVariableInfo aLocal in methodBody.LocalVariables) { aMethodInfo.LocalInfos.Add(new Types.VariableInfo() { UnderlyingType = aLocal.LocalType, Position = aLocal.LocalIndex }); } byte[] ILBytes = methodBody.GetILAsByteArray(); int ILBytesPos = 0; while (ILBytesPos < ILBytes.Length) { OpCode currOpCode; ushort currOpCodeID = 0; int currOpBytesSize = 0; if (ILBytes[ILBytesPos] == 0xFE) { currOpCodeID = (ushort)(0xFE00 + (short)ILBytes[ILBytesPos + 1]); currOpBytesSize += 2; } else { currOpCodeID = (ushort)ILBytes[ILBytesPos]; currOpBytesSize++; } currOpCode = AllOpCodes[currOpCodeID]; int operandSize = 0; switch (currOpCode.OperandType) { #region Operands case OperandType.InlineBrTarget: operandSize = 4; break; case OperandType.InlineField: operandSize = 4; break; case OperandType.InlineI: operandSize = 4; break; case OperandType.InlineI8: operandSize = 8; break; case OperandType.InlineMethod: operandSize = 4; break; case OperandType.InlineNone: //No operands = no op size break; case OperandType.InlineR: operandSize = 8; break; case OperandType.InlineSig: operandSize = 4; break; case OperandType.InlineString: operandSize = 4; break; case OperandType.InlineSwitch: { uint count = Utilities.ReadUInt32(ILBytes, ILBytesPos + currOpBytesSize); currOpBytesSize += 4; operandSize = (int)(count * 4); } break; case OperandType.InlineTok: operandSize = 4; break; case OperandType.InlineType: operandSize = 4; break; case OperandType.InlineVar: operandSize = 2; break; case OperandType.ShortInlineBrTarget: operandSize = 1; break; case OperandType.ShortInlineI: operandSize = 1; break; case OperandType.ShortInlineR: operandSize = 4; break; case OperandType.ShortInlineVar: operandSize = 1; break; default: throw new Exception("Unrecognised operand type!"); #endregion } MethodBase methodToCall = null; byte[] valueBytes = new byte[operandSize]; if (operandSize > 0) { Array.Copy(ILBytes, ILBytesPos + currOpBytesSize, valueBytes, 0, operandSize); if (currOpCode.Equals(OpCodes.Call) || currOpCode.Equals(OpCodes.Calli) || currOpCode.Equals(OpCodes.Callvirt) || currOpCode.Equals(OpCodes.Ldftn) || currOpCode.Equals(OpCodes.Newobj)) { int MethodMetadataToken = Utilities.ReadInt32(valueBytes, 0); methodToCall = aMethodInfo.UnderlyingInfo.Module.ResolveMethod(MethodMetadataToken); } } result.ILOps.Add(new ILOp() { opCode = currOpCode, Offset = ILBytesPos, BytesSize = currOpBytesSize + operandSize, ValueBytes = valueBytes, MethodToCall = methodToCall }); ILBytesPos += currOpBytesSize + operandSize; } foreach (ExceptionHandlingClause aClause in methodBody.ExceptionHandlingClauses) { ExceptionHandledBlock exBlock = result.GetExactExceptionHandledBlock(aClause.TryOffset); if (exBlock == null) { exBlock = new ExceptionHandledBlock(); exBlock.Offset = aClause.TryOffset; exBlock.Length = aClause.TryLength; result.ExceptionHandledBlocks.Add(exBlock); } switch (aClause.Flags) { case ExceptionHandlingClauseOptions.Fault: case ExceptionHandlingClauseOptions.Clause: { CatchBlock catchBlock = new CatchBlock() { Offset = aClause.HandlerOffset, Length = aClause.HandlerLength, //Though not used, we may as well set it anyway FilterType = aClause.CatchType }; exBlock.CatchBlocks.Add(catchBlock); } break; case ExceptionHandlingClauseOptions.Finally: { FinallyBlock finallyBlock = new FinallyBlock() { Offset = aClause.HandlerOffset, Length = aClause.HandlerLength }; exBlock.FinallyBlocks.Add(finallyBlock); } break; default: Logger.LogError("IL0010", "", 0, "Exception handling clause not supported! Type: " + aClause.Flags.ToString()); break; } } } return result; }