예제 #1
0
        /// <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);
        }
예제 #2
0
파일: ILReader.cs 프로젝트: rmhasan/FlingOS
        /// <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;
        }