示例#1
0
        public void Run(VMContext ctx, out ExecutionState state)
        {
            var sp   = ctx.Registers[Constants.REG_SP].U4;
            var type = ctx.Stack[sp--].U1;

            var frame = new EHFrame();

            frame.EHType = type;
            if (type == Constants.EH_CATCH)
            {
                frame.CatchType = (Type)ctx.Instance.Data.LookupReference(ctx.Stack[sp--].U4);
            }
            else if (type == Constants.EH_FILTER)
            {
                frame.FilterAddr = ctx.Stack[sp--].U8;
            }
            frame.HandlerAddr = ctx.Stack[sp--].U8;

            ctx.Stack.SetTopPosition(sp);
            ctx.Registers[Constants.REG_SP].U4 = sp;

            frame.BP = ctx.Registers[Constants.REG_BP];
            frame.SP = ctx.Registers[Constants.REG_SP];
            ctx.EHStack.Add(frame);

            state = ExecutionState.Next;
        }
示例#2
0
        public void Load(DarksVMContext ctx, out ExecutionState state)
        {
            uint sp   = ctx.Registers[DarksVMConstants.REG_SP].U4;
            byte type = ctx.Stack[sp--].U1;

            var frame = new EHFrame
            {
                EHType = type
            };

            if (type != DarksVMConstants.EH_CATCH)
            {
                if (type == DarksVMConstants.EH_FILTER)
                {
                    frame.FilterAddr = ctx.Stack[sp--].U8;
                }
            }
            else
            {
                frame.CatchType = (Type)ctx.Instance.Data.LookupReference(ctx.Stack[sp--].U4);
            }
            frame.HandlerAddr = ctx.Stack[sp--].U8;

            ctx.Stack.SetTopPosition(sp);
            ctx.Registers[DarksVMConstants.REG_SP].U4 = sp;

            frame.BP = ctx.Registers[DarksVMConstants.REG_BP];
            frame.SP = ctx.Registers[DarksVMConstants.REG_SP];
            ctx.EHStack.Add(frame);

            state = ExecutionState.Next;
        }
示例#3
0
        public void Load(DarksVMContext ctx, out ExecutionState state)
        {
            uint  sp      = ctx.Registers[DarksVMConstants.REG_SP].U4;
            ulong handler = ctx.Stack[sp--].U8;

            int     frameIndex = ctx.EHStack.Count - 1;
            EHFrame frame      = ctx.EHStack[frameIndex];

            if (frame.HandlerAddr != handler)
            {
                throw new InvalidProgramException();
            }
            ctx.EHStack.RemoveAt(frameIndex);

            if (frame.EHType == DarksVMConstants.EH_FINALLY)
            {
                ctx.Stack[++sp] = ctx.Registers[DarksVMConstants.REG_IP];
                ctx.Registers[DarksVMConstants.REG_K1].U1 = 0;
                ctx.Registers[DarksVMConstants.REG_IP].U8 = frame.HandlerAddr;
            }

            ctx.Stack.SetTopPosition(sp);
            ctx.Registers[DarksVMConstants.REG_SP].U4 = sp;

            state = ExecutionState.Next;
        }
示例#4
0
        private void AddAbnormalEdge(ControlFlowGraph graph, Node node, EHFrame ehFrame, Node handlerEntry)
        {
            node.UserData[ControlFlowGraph.TopMostEHProperty] = ehFrame;
            var edge = CreateEdge(node, handlerEntry,
                                  ControlFlowGraph.ExceptionConditionLabel);

            graph.Edges.Add(edge);
        }
示例#5
0
 public string GetClusterName(EHFrame frame)
 {
     return(frame.ToString());
 }
        private IEnumerable <ProgramState> ProcessTry(ILInstruction instruction, ProgramState next)
        {
            var result = new List <ProgramState> {
                next
            };

            int dependencyIndex = 0;

            // Pop and infer handler type.
            var symbolicType = next.Stack.Pop();

            instruction.Dependencies.AddOrMerge(dependencyIndex++, symbolicType);

            var frame = new EHFrame
            {
                Type     = Constants.EHTypes[symbolicType.InferStackValue().U1],
                TryStart = (ulong)(instruction.Offset + instruction.Size)
            };

            next.EHStack.Push(frame);

            bool pushException          = false;
            bool ignoreExitKeyInHandler = false;

            switch (frame.Type)
            {
            case EHType.CATCH:
                // Pop and infer catch type.
                var  symbolicCatchType = next.Stack.Pop();
                uint catchTypeId       = symbolicCatchType.InferStackValue().U4;
                frame.CatchType = (ITypeDefOrRef)KoiStream.ResolveReference(Logger, instruction.Offset, catchTypeId,
                                                                            TableIndex.TypeDef, TableIndex.TypeRef, TableIndex.TypeSpec);
                instruction.Dependencies.AddOrMerge(dependencyIndex++, symbolicCatchType);
                pushException = true;
                break;

            case EHType.FILTER:
                // Pop and infer filter address.
                var symbolicFilterAddress = next.Stack.Pop();
                frame.FilterAddress = symbolicFilterAddress.InferStackValue().U8;
                instruction.Dependencies.AddOrMerge(dependencyIndex++, symbolicFilterAddress);
                pushException = true;
                break;

            case EHType.FAULT:
            case EHType.FINALLY:
                // No extra values on the stack.
                ignoreExitKeyInHandler = true;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            // Pop and infer handler address.
            var symbolicHandlerAddress = next.Stack.Pop();

            instruction.Dependencies.AddOrMerge(dependencyIndex, symbolicHandlerAddress);
            frame.HandlerAddress = symbolicHandlerAddress.InferStackValue().U8;

            // Branch to handler block.
            var handlerState = next.Copy();

            handlerState.Key = 0;
            handlerState.IP  = frame.HandlerAddress;
            handlerState.EHStack.Pop();
            handlerState.IgnoreExitKey = ignoreExitKeyInHandler;

            // Push exception object on stack of handler when needed.
            if (pushException)
            {
                handlerState.Stack.Push(new SymbolicValue(
                                            new ILInstruction(PushExceptionOffset, ILOpCodes.__PUSH_EXCEPTION, frame.CatchType),
                                            VMType.Object));
            }

            result.Add(handlerState);

            // Branch to filter block if necessary.
            if (frame.FilterAddress != 0)
            {
                var filterState = next.Copy();
                filterState.Key = 0;
                filterState.IP  = frame.FilterAddress;
                result.Add(filterState);
            }

            instruction.Annotation = new Annotation
            {
                InferredPopCount  = instruction.Dependencies.Count,
                InferredPushCount = 0,
            };

            Logger.Debug2(Tag, $"Entered exception handler (Type: {frame.Type}, Try: IL_{instruction.Offset:X4}, Handler: IL_{frame.HandlerAddress:X4}).");
            return(result);
        }