示例#1
0
        /// <summary>
        /// Compute delta of pushing according to given instruction
        /// <remarks>Modified method taken from http://cecil.googlecode.com/svn/trunk/decompiler/Cecil.Decompiler/Cecil.Decompiler.Cil/ControlFlowGraphBuilder.cs </remarks>.
        /// </summary>
        /// <param name="instruction">Instruction which delta is computed.</param>
        /// <returns>Push delta.</returns>
        int getPushDelta(CILInstruction instruction)
        {
            var stackBehaviour = instruction.OpCode.StackBehaviourPush;

            switch (stackBehaviour)
            {
            case StackBehaviour.Push0:
                return(0);

            case StackBehaviour.Push1:
            case StackBehaviour.Pushi:
            case StackBehaviour.Pushi8:
            case StackBehaviour.Pushr4:
            case StackBehaviour.Pushr8:
            case StackBehaviour.Pushref:
                return(1);

            case StackBehaviour.Push1_push1:
                return(2);

            case StackBehaviour.Varpush:
                if (instruction.MethodOperand == null)
                {
                    //cannot be determined
                    return(0);
                }

                return(instruction.MethodOperand.ReturnType.TypeName == typeof(void).FullName ? 0 : 1);

            default:
                //unknown behaviour
                return(0);
            }
        }
示例#2
0
        /// <summary>
        /// Transcript given instructions in context of given method.
        /// Transcription is processed by given emitter.
        /// </summary>
        /// <param name="method">Context method of transcription</param>
        /// <param name="instructions">Transcripted instructions</param>
        /// <param name="emitter">Emitter where transcription is emitted</param>
        internal static void Transcript(TypeMethodInfo method, IEnumerable <CILInstruction> instructions, EmitterBase emitter)
        {
            E           = emitter;
            Method      = method;
            LocalTmpVar = E.GetTemporaryVariable("local");

            //prepare labels table
            Labels.Clear();
            foreach (var instruction in instructions)
            {
                var labelName = string.Format("L_0x{0:x4}", instruction.Address);
                Labels.Add(instruction.Address, E.CreateLabel(labelName));
            }

            foreach (var instruction in instructions)
            {
                Instruction = instruction;
                E.SetLabel(Labels[instruction.Address]);

                var block = E.StartNewInfoBlock();
                block.Comment = "\n---" + Instruction.ToString();

                Action transcriptor;
                if (_transcriptors.TryGetValue(Name, out transcriptor))
                {
                    transcriptor();
                }
                else
                {
                    unknownInstruction();
                }
            }
        }
示例#3
0
        /// <summary>
        /// Compute delta of popping according to given instruction
        /// <remarks>Modified method taken from http://cecil.googlecode.com/svn/trunk/decompiler/Cecil.Decompiler/Cecil.Decompiler.Cil/ControlFlowGraphBuilder.cs </remarks>.
        /// </summary>
        /// <param name="instruction">Instruction which delta is computed.</param>
        /// <param name="stackHeight">Current height of stack that should be popped.</param>
        /// <returns>Pop delta.</returns>
        int getPopDelta(CILInstruction instruction, int stackHeight)
        {
            var stackBehaviour = instruction.OpCode.StackBehaviourPop;

            switch (stackBehaviour)
            {
            case StackBehaviour.Pop0:
                return(0);

            case StackBehaviour.Popi:
            case StackBehaviour.Popref:
            case StackBehaviour.Pop1:
                return(1);

            case StackBehaviour.Pop1_pop1:
            case StackBehaviour.Popi_pop1:
            case StackBehaviour.Popi_popi:
            case StackBehaviour.Popi_popi8:
            case StackBehaviour.Popi_popr4:
            case StackBehaviour.Popi_popr8:
            case StackBehaviour.Popref_pop1:
            case StackBehaviour.Popref_popi:
                return(2);

            case StackBehaviour.Popi_popi_popi:
            case StackBehaviour.Popref_popi_popi:
            case StackBehaviour.Popref_popi_popi8:
            case StackBehaviour.Popref_popi_popr4:
            case StackBehaviour.Popref_popi_popr8:
            case StackBehaviour.Popref_popi_popref:
                return(3);

            case StackBehaviour.PopAll:
                return(stackHeight);

            case StackBehaviour.Varpop:
                if (instruction.MethodOperand != null)
                {
                    var method = instruction.MethodOperand;
                    int count  = method.Parameters.Length;
                    if (method.HasThis && OpCodes.Newobj.Value != instruction.OpCode.Value)
                    {
                        ++count;
                    }

                    return(count);
                }

                //if (instruction.OpCode.Code == Code.Ret)
                //return IsVoidMethod() ? 0 : 1;
                return(0);    //we dont now if we are in void method
            }

            return(0);
        }