Пример #1
0
        //----------------------------------------------------------------------------------------------------------------------
        // Predict that the last 0 or 1 pushed onto the stack being the value to be returned.  Returns false on error. Naughty me!
        //----------------------------------------------------------------------------------------------------------------------
        public bool GetBooleanValue(string methodName)
        {
            MethodInfo method = m_MasterType.GetMethod(methodName);

            if (method != null)
            {
                byte[] methodData = method.GetMethodBody().GetILAsByteArray();

                BinaryReader codeReader = new BinaryReader(
                    new MemoryStream(methodData)
                    );

                bool lastCode = false;

                while (codeReader.PeekChar() >= 0)
                {
                    OpCode op = OPCodeCache.Hit(codeReader.ReadByte());

                    if (op == OpCodes.Ldc_I4_1)
                    {
                        lastCode = true;
                    }
                    else if (op == OpCodes.Ldc_I4_0)
                    {
                        lastCode = false;
                    }
                }

                return(lastCode);
            }

            return(false);
        }
Пример #2
0
        // heart and soul, yay!
        private void AnalyseILCode(byte[] code)
        {
            BinaryReader codeReader = new BinaryReader(
                new MemoryStream(code)
                );

            while (codeReader.PeekChar() >= 0)
            {
                OpCode op = OPCodeCache.Hit(codeReader.ReadByte());

                if (op == OpCodes.Ldc_I4)
                {
                    m_Stack.Push(codeReader.ReadInt32());
                }
                else if (op == OpCodes.Ldc_R8)
                {
                    m_Stack.Push(codeReader.ReadDouble());
                }
                else if (op == OpCodes.Ldc_R4)
                {
                    m_Stack.Push(codeReader.ReadSingle());
                }
                else if (op.Value > 0x15 && op.Value < 0x1F)
                {
                    m_Stack.Push(op.Value - 0x16);
                }
                else if (op == OpCodes.Ldc_I4_M1)
                {
                    m_Stack.Push(-1);
                }
                else if (op == OpCodes.Ldc_I4_S)
                {
                    m_Stack.Push((int)codeReader.ReadByte());
                }
                else if (op == OpCodes.Ldstr)
                {
                    int stringDescriptor = codeReader.ReadInt32();

                    if (MatchMetadata(stringDescriptor, MetadataToken.String))                        // sanity check, am I really a string?
                    {
                        m_Stack.Push(m_Module.ResolveString(stringDescriptor));
                    }
                    else
                    {
                        m_Stack.Push("(error - string value couldn't be resolved.)");
                    }
                }
                else if (op == OpCodes.Call || op == OpCodes.Callvirt)
                {
                    int methodDescriptor = codeReader.ReadInt32();

                    if (MatchMetadata(methodDescriptor, MetadataToken.Method))                        // sanity check, am I really a method?
                    {
                        MethodBase mb = m_Module.ResolveMethod(methodDescriptor);

                        if ((mb.DeclaringType.IsSubclassOf(typeof(Mobile)) || mb.DeclaringType == typeof(Mobile)) && !mb.IsConstructor)
                        {
                            Dispatch(mb.Name, mb.GetParameters().Length);
                        }
                        else
                        {
                            Dispatch(mb.Name, mb.DeclaringType.Name, mb.GetParameters().Length);
                        }
                    }
                }
                else
                {
                    // all opcodes that push something onto the stack have been taken care of.
                    // now we have to check whether the given opcode has an operand or not.
                    // if so, we'll skip appropriate amount of bytes.

                    OperandType operandType = op.OperandType;

                    switch (operandType)
                    {
                    case OperandType.InlineNone:
                    {
                    }
                    break;

                    case OperandType.InlineR:
                    case OperandType.InlineI8:
                    {
                        codeReader.ReadInt64();
                    }
                    break;

                    case OperandType.InlineSwitch:
                    {
                        int switchBranches = codeReader.ReadInt32();

                        while (switchBranches-- > 0)
                        {
                            codeReader.ReadInt32();
                        }
                    }
                    break;

                    case OperandType.ShortInlineR:
                    case OperandType.InlineType:
                    case OperandType.InlineTok:
                    case OperandType.InlineString:
                    case OperandType.InlineSig:
                    case OperandType.InlineMethod:
                    case OperandType.InlineI:
                    case OperandType.InlineField:
                    case OperandType.InlineBrTarget:
                    {
                        codeReader.ReadInt32();
                    }
                    break;

                    case OperandType.InlineVar:
                    {
                        codeReader.ReadInt16();
                    }
                    break;

                    case OperandType.ShortInlineVar:
                    case OperandType.ShortInlineI:
                    case OperandType.ShortInlineBrTarget:
                    {
                        codeReader.ReadByte();
                    }
                    break;
                    }
                }
            }
        }