Beispiel #1
0
        private bool Solve_Blt(CflowStack stack)
        {
            var val2 = stack.Pop();
            var val1 = stack.Pop();

            if (val1 is BitVecExpr && val2 is BitVecExpr)
            {
                FinalExpr = ctx.MkBVSLT(val1 as BitVecExpr, val2 as BitVecExpr);

                if ((val1 as BitVecExpr).Simplify().IsNumeral&& (val2 as BitVecExpr).Simplify().IsNumeral)
                {
                    Microsoft.Z3.Solver s1 = ctx.MkSolver();
                    Microsoft.Z3.Solver s2 = ctx.MkSolver();

                    s1.Add(FinalExpr);
                    s2.Add(ctx.MkNot(FinalExpr));

                    return(this.CheckBranch(s1, s2));
                }
            }

            return(false);
        }
Beispiel #2
0
        private void Translate_Ldlen(CflowStack stack, Instruction instr)
        {
            var val = stack.Pop();

            if (val is IField)
            {
                if ((val as IField).FullName == "System.Type[] System.Type::EmptyTypes")
                {
                    stack.Push(ctx.MkBV(0, 32));
                    return;
                }
            }

            stack.PushUnknown();
        }
Beispiel #3
0
        private void UpdateStack(CflowStack stack, Instruction instr)
        {
            int pushes, pops;

            instr.CalculateStackUsage(out pushes, out pops);
            if (pops == -1)
            {
                stack.Clear();
            }
            else
            {
                stack.Pop(pops);
                stack.Push(pushes);
            }
        }
Beispiel #4
0
        private bool Solve_Switch(CflowStack stack)
        {
            Block        target;
            List <Block> targets;
            bool         modified = false;
            int          index;

            var val1 = stack.Pop();

            if (val1 is BitVecExpr && (val1 as BitVecExpr).Simplify().IsNumeral != true)
            {
                var cfg = CflowCFG.ControlFlow;

                foreach (List <Block> list in cfg)
                {
                    token.ThrowIfCancellationRequested();

                    CflowTranslatorCtx translator = TranslatorInit(true);

                    List <Instr> instructions = new List <Instr>();

                    foreach (Block b in list)
                    {
                        instructions.AddRange(b.Instructions);
                    }

                    for (int i = 0; i < instructions.Count - 1; i++)
                    {
                        var instr = instructions[i].Instruction;
                        TranslateInstruction(translator, instr);
                    }

                    object val2 = translator.Stack.Pop();

                    if (val2 is BitVecExpr && (val2 as BitVecExpr).Simplify().IsNumeral == true)
                    {
                        this.BifurcateBlocks(cfg, list);

                        if (!int.TryParse((val2 as BitVecExpr).Simplify().ToString(), out index))
                        {
                            index = -1;
                        }

                        var beforeSwitch = list[list.Count - 2];

                        if (beforeSwitch.LastInstr.IsConditionalBranch())
                        {
                            var newBlock = new Block();

                            for (int i = 0; i < list.Last().Instructions.Count - 1; i++)
                            {
                                var instr = list.Last().Instructions[i];
                                if (instr.OpCode != OpCodes.Nop)
                                {
                                    newBlock.Instructions.Add(true ? new Instr(instr.Instruction.Clone()) : instr);
                                }
                            }

                            newBlock.Insert(newBlock.Instructions.Count, OpCodes.Pop.ToInstruction()); // for switch

                            if (beforeSwitch.FallThrough != null && beforeSwitch.FallThrough == list.Last())
                            {
                                targets = block.Targets;
                                if (targets == null || index < 0 || index >= targets.Count)
                                {
                                    target = block.FallThrough;
                                }
                                else
                                {
                                    target = targets[index];
                                }

                                beforeSwitch.FallThrough.Parent.Add(newBlock);
                                beforeSwitch.SetNewFallThrough(newBlock);
                                newBlock.SetNewFallThrough(target);
                                modified = true;
                            }

                            if (beforeSwitch.Targets != null && beforeSwitch.Targets[0] == list.Last())
                            {
                                targets = block.Targets;
                                if (targets == null || index < 0 || index >= targets.Count)
                                {
                                    target = block.FallThrough;
                                }
                                else
                                {
                                    target = targets[index];
                                }

                                beforeSwitch.FallThrough.Parent.Add(newBlock);
                                beforeSwitch.SetNewTarget(0, newBlock);
                                newBlock.SetNewFallThrough(target);
                                modified = true;
                            }
                        }
                        else if (beforeSwitch.LastInstr.OpCode.Code == Code.Switch)
                        {
                            //just skip
                        }
                        else
                        {
                            var newBlock = new Block();

                            for (int i = 0; i < list.Last().Instructions.Count - 1; i++)
                            {
                                var instr = list.Last().Instructions[i];
                                if (instr.OpCode != OpCodes.Nop)
                                {
                                    newBlock.Instructions.Add(true ? new Instr(instr.Instruction.Clone()) : instr);
                                }
                            }

                            newBlock.Insert(newBlock.Instructions.Count, OpCodes.Pop.ToInstruction()); // for switch

                            targets = block.Targets;
                            if (targets == null || index < 0 || index >= targets.Count)
                            {
                                target = block.FallThrough;
                            }
                            else
                            {
                                target = targets[index];
                            }

                            beforeSwitch.FallThrough.Parent.Add(newBlock);
                            beforeSwitch.SetNewFallThrough(newBlock);
                            newBlock.SetNewFallThrough(target);
                            modified = true;
                        }

                        if (modified == true)
                        {
                            break;
                        }
                    }
                }

                return(modified);
            }
            else if (val1 is BitVecExpr)
            {
                index = int.Parse((val1 as BitVecExpr).Simplify().ToString());

                targets = block.Targets;
                if (targets == null || index < 0 || index >= targets.Count)
                {
                    target = block.FallThrough;
                }
                else
                {
                    target = targets[index];
                }

                block.Insert(block.Instructions.Count - 1, OpCodes.Pop.ToInstruction());

                block.ReplaceSwitchWithBranch(target);

                return(true);
            }

            return(false);
        }