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; }
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; }
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; }
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); }
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); }