Ejemplo n.º 1
0
        private static void SetupFinallyFrame(DarksVMContext ctx, EHFrame frame)
        {
            frame.SP.U4++;
            ctx.Registers[DarksVMConstants.REG_K1].U1 = 0;
            ctx.Registers[DarksVMConstants.REG_SP]    = frame.SP;
            ctx.Registers[DarksVMConstants.REG_BP]    = frame.BP;
            ctx.Registers[DarksVMConstants.REG_IP].U8 = frame.HandlerAddr;

            ctx.Stack[frame.SP.U4] = new DarksVMSlot {
                U8 = 1
            };
        }
Ejemplo n.º 2
0
        private static void HandleAbnormalExit(DarksVMContext ctx)
        {
            DarksVMSlot oldBP = ctx.Registers[DarksVMConstants.REG_BP];
            DarksVMSlot oldSP = ctx.Registers[DarksVMConstants.REG_SP];

            for (int i = ctx.EHStack.Count - 1; i >= 0; i--)
            {
                EHFrame frame = ctx.EHStack[i];
                if (frame.EHType == DarksVMConstants.EH_FAULT || frame.EHType == DarksVMConstants.EH_FINALLY)
                {
                    SetupFinallyFrame(ctx, frame);
                    Load(ctx);
                }
            }
            ctx.EHStack.Clear();
        }
Ejemplo n.º 3
0
        private static void HandleEH(DarksVMContext ctx, ref ExecutionState state)
        {
            EHState ehState = ctx.EHStates[ctx.EHStates.Count - 1];

            switch (ehState.CurrentProcess)
            {
            case EHState.EHProcess.Searching:
            {
                if (ehState.CurrentFrame != null)
                {
                    // Return from filter
                    bool filterResult = ctx.Registers[DarksVMConstants.REG_R1].U1 != 0;
                    if (filterResult)
                    {
                        ehState.CurrentProcess = EHState.EHProcess.Unwinding;
                        ehState.HandlerFrame   = ehState.CurrentFrame;
                        ehState.CurrentFrame   = ctx.EHStack.Count;
                        state = ExecutionState.Next;
                        goto case EHState.EHProcess.Unwinding;
                    }
                    ehState.CurrentFrame--;
                }
                else
                {
                    ehState.CurrentFrame = ctx.EHStack.Count - 1;
                }

                Type exType = ehState.ExceptionObj.GetType();
                for (; ehState.CurrentFrame >= 0 && ehState.HandlerFrame == null; ehState.CurrentFrame--)
                {
                    EHFrame frame = ctx.EHStack[ehState.CurrentFrame.Value];
                    if (frame.EHType == DarksVMConstants.EH_FILTER)
                    {
                        // Run filter
                        uint sp = ehState.OldSP.U4;
                        ctx.Stack.SetTopPosition(++sp);
                        ctx.Stack[sp] = new DarksVMSlot {
                            O = ehState.ExceptionObj
                        };
                        ctx.Registers[DarksVMConstants.REG_K1].U1 = 0;
                        ctx.Registers[DarksVMConstants.REG_SP].U4 = sp;
                        ctx.Registers[DarksVMConstants.REG_BP]    = frame.BP;
                        ctx.Registers[DarksVMConstants.REG_IP].U8 = frame.FilterAddr;
                        break;
                    }
                    if (frame.EHType == DarksVMConstants.EH_CATCH)
                    {
                        if (frame.CatchType.IsAssignableFrom(exType))
                        {
                            ehState.CurrentProcess = EHState.EHProcess.Unwinding;
                            ehState.HandlerFrame   = ehState.CurrentFrame;
                            ehState.CurrentFrame   = ctx.EHStack.Count;
                            goto case EHState.EHProcess.Unwinding;
                        }
                    }
                }
                if (ehState.CurrentFrame == -1 && ehState.HandlerFrame == null)
                {
                    ctx.EHStates.RemoveAt(ctx.EHStates.Count - 1);
                    state = ExecutionState.Rethrow;
                    if (ctx.EHStates.Count == 0)
                    {
                        HandleRethrow(ctx, ehState.ExceptionObj);
                    }
                }
                else
                {
                    state = ExecutionState.Next;
                }
                break;
            }

            case EHState.EHProcess.Unwinding:
            {
                ehState.CurrentFrame--;
                int i;
                for (i = ehState.CurrentFrame.Value; i > ehState.HandlerFrame.Value; i--)
                {
                    EHFrame frame = ctx.EHStack[i];
                    ctx.EHStack.RemoveAt(i);
                    if (frame.EHType == DarksVMConstants.EH_FAULT || frame.EHType == DarksVMConstants.EH_FINALLY)
                    {
                        // Run finally
                        SetupFinallyFrame(ctx, frame);
                        break;
                    }
                }
                ehState.CurrentFrame = i;

                if (ehState.CurrentFrame == ehState.HandlerFrame)
                {
                    EHFrame frame = ctx.EHStack[ehState.HandlerFrame.Value];
                    ctx.EHStack.RemoveAt(ehState.HandlerFrame.Value);
                    // Run handler
                    frame.SP.U4++;
                    ctx.Stack.SetTopPosition(frame.SP.U4);
                    ctx.Stack[frame.SP.U4] = new DarksVMSlot {
                        O = ehState.ExceptionObj
                    };

                    ctx.Registers[DarksVMConstants.REG_K1].U1 = 0;
                    ctx.Registers[DarksVMConstants.REG_SP]    = frame.SP;
                    ctx.Registers[DarksVMConstants.REG_BP]    = frame.BP;
                    ctx.Registers[DarksVMConstants.REG_IP].U8 = frame.HandlerAddr;

                    ctx.EHStates.RemoveAt(ctx.EHStates.Count - 1);
                }
                state = ExecutionState.Next;
                break;
            }

            default:
                throw new ExecutionEngineException();
            }
        }