Пример #1
0
        private bool Solve_Brtrue(CflowStack stack)
        {
            var val1 = stack.Pop();

            if (val1 is BitVecExpr)
            {
                FinalExpr = ctx.MkEq(val1 as BitVecExpr, ctx.MkBV(0, 32));

                if ((val1 as BitVecExpr).Simplify().IsNumeral)
                {
                    Microsoft.Z3.Solver s = ctx.MkSolver();
                    s.Assert(FinalExpr);
                    if (s.Check() == Status.UNSATISFIABLE)
                    {
                        this.PopPushedArgs(1);

                        block.ReplaceBccWithBranch(true);

                        return(true);
                    }
                    else
                    {
                        this.PopPushedArgs(1);

                        block.ReplaceBccWithBranch(false);

                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #2
0
 public CflowTranslatorCtx(Context ctx, CflowStack stack, List <BitVecExpr> args, List <BitVecExpr> locals)
 {
     this.Stack     = stack;
     this.Stack.ctx = ctx;
     this.Args      = args;
     this.Locals    = locals;
 }
Пример #3
0
        private BitVecExpr GetLocal(CflowStack stack, List <BitVecExpr> locals, Local local)
        {
            if (local == null)
            {
                return(GetUnknownLocal(stack));
            }

            return(GetLocal(stack, locals, local.Index));
        }
Пример #4
0
        private BitVecExpr GetLocal(CflowStack stack, List <BitVecExpr> locals, int i)
        {
            if (0 <= i && i < locals.Count)
            {
                return(locals[i]);
            }

            return(GetUnknownLocal(stack));
        }
Пример #5
0
        private BitVecExpr GetArg(CflowStack stack, List <BitVecExpr> args, Parameter arg)
        {
            if (arg == null)
            {
                return(GetUnknownArg(stack));
            }

            return(GetArg(stack, args, arg.Index));
        }
Пример #6
0
        private BitVecExpr GetArg(CflowStack stack, List <BitVecExpr> args, int i)
        {
            if (0 <= i && i < args.Count)
            {
                return(args[i]);
            }

            return(GetUnknownArg(stack));
        }
Пример #7
0
        private void Translate_Stloc(CflowStack stack, List <BitVecExpr> locals, int index)
        {
            var val = stack.Pop();

            if (val is BitVecExpr)
            {
                SetLocal(locals, index, val as BitVecExpr);
            }
            else
            {
                SetLocal(locals, index, GetUnknownLocal(stack));
            }
        }
Пример #8
0
        private void Translate_Ldind_I4(CflowStack stack, Instruction instr)
        {
            var addr = stack.Pop();

            if (addr is Address && (addr as Address).Value is BitVecExpr)
            {
                stack.Push((addr as Address).Value);
            }
            else
            {
                stack.PushUnknown();
            }
        }
Пример #9
0
        private void Translate_Starg(CflowStack stack, List <BitVecExpr> args, Parameter arg)
        {
            var val = stack.Pop();

            if (val is BitVecExpr)
            {
                SetArg(args, arg == null ? -1 : arg.Index, val as BitVecExpr);
            }
            else
            {
                SetArg(args, arg == null ? -1 : arg.Index, GetUnknownArg(stack));
            }
        }
Пример #10
0
        private void Translate_Not(CflowStack stack, Instruction instr)
        {
            var val1 = stack.Pop();

            if (val1 is BitVecExpr)
            {
                stack.Push(ctx.MkBVNot(val1 as BitVecExpr));
            }
            else
            {
                stack.PushUnknown();
            }
        }
Пример #11
0
        private void Translate_Clt_Un(CflowStack stack, Instruction instr)
        {
            var val2 = stack.Pop();
            var val1 = stack.Pop();

            if (val1 is BitVecExpr && (val1 as BitVecExpr).Simplify().IsNumeral&& val2 is BitVecExpr && (val2 as BitVecExpr).Simplify().IsNumeral)
            {
                stack.Push((BitVecExpr)ctx.MkITE(ctx.MkBVULT(val1 as BitVecExpr, val2 as BitVecExpr), ctx.MkBV(1, 32), ctx.MkBV(0, 32)));
            }
            else
            {
                stack.PushUnknown();
            }
        }
Пример #12
0
        private void Translate_Mul_Ovf_Un(CflowStack stack, Instruction instr)
        {
            var val2 = stack.Pop();
            var val1 = stack.Pop();

            if (val1 is BitVecExpr && val2 is BitVecExpr)
            {
                stack.Push((BitVecExpr)ctx.MkITE(ctx.MkBVMulNoOverflow(val1 as BitVecExpr, val2 as BitVecExpr, false), ctx.MkBVMul(val1 as BitVecExpr, val2 as BitVecExpr), stack.Unknown() as BitVecExpr));
            }
            else
            {
                stack.PushUnknown();
            }
        }
Пример #13
0
        private void Translate_Sub_Ovf(CflowStack stack, Instruction instr)
        {
            var val2 = stack.Pop();
            var val1 = stack.Pop();

            if (val1 is BitVecExpr && val2 is BitVecExpr)
            {
                stack.Push((BitVecExpr)ctx.MkITE(ctx.MkBVSubNoUnderflow(val1 as BitVecExpr, val2 as BitVecExpr, true), ctx.MkBVSub(val1 as BitVecExpr, val2 as BitVecExpr), stack.Unknown() as BitVecExpr));
            }
            else
            {
                stack.PushUnknown();
            }
        }
Пример #14
0
        private void Translate_Shr_Un(CflowStack stack, Instruction instr)
        {
            var val2 = stack.Pop();
            var val1 = stack.Pop();

            if (val1 is BitVecExpr && val2 is BitVecExpr)
            {
                stack.Push(ctx.MkBVLSHR(val1 as BitVecExpr, val2 as BitVecExpr));
            }
            else
            {
                stack.PushUnknown();
            }
        }
Пример #15
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);
            }
        }
Пример #16
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();
        }
Пример #17
0
        private bool Solve_Bne_Un(CflowStack stack)
        {
            var val2 = stack.Pop();
            var val1 = stack.Pop();

            if (val1 is BitVecExpr && val2 is BitVecExpr)
            {
                FinalExpr = ctx.MkNot(ctx.MkEq(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);
        }
Пример #18
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);
        }
Пример #19
0
 private BitVecExpr GetUnknownLocal(CflowStack stack)
 {
     return(stack.Unknown() as BitVecExpr);
 }
Пример #20
0
 private void Translate_Stloc(CflowStack stack, List <BitVecExpr> locals, Local local)
 {
     Translate_Stloc(stack, locals, local == null ? -1 : local.Index);
 }
Пример #21
0
 private void Translate_Ldloca(CflowStack stack, List <BitVecExpr> locals, Local local)
 {
     stack.Push(new Address(GetLocal(stack, locals, local)));
     SetLocal(locals, local == null ? -1 : local.Index, GetUnknownLocal(stack));
 }
Пример #22
0
        private void Translate_Sizeof(CflowStack stack, Instruction instr)
        {
            if (instr.Operand is TypeRef)
            {
                if ((instr.Operand as TypeRef).FullName == "System.Boolean")
                {
                    stack.Push(ctx.MkBV(sizeof(System.Boolean), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.Byte")
                {
                    stack.Push(ctx.MkBV(sizeof(System.Byte), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.SByte")
                {
                    stack.Push(ctx.MkBV(sizeof(System.SByte), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.Char")
                {
                    stack.Push(ctx.MkBV(sizeof(System.Char), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.Int16")
                {
                    stack.Push(ctx.MkBV(sizeof(System.Int16), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.Int32")
                {
                    stack.Push(ctx.MkBV(sizeof(System.Int32), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.Int64")
                {
                    stack.Push(ctx.MkBV(sizeof(System.Int64), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.UInt16")
                {
                    stack.Push(ctx.MkBV(sizeof(System.UInt16), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.UInt32")
                {
                    stack.Push(ctx.MkBV(sizeof(System.UInt32), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.UInt64")
                {
                    stack.Push(ctx.MkBV(sizeof(System.UInt64), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.Single")
                {
                    stack.Push(ctx.MkBV(sizeof(System.Single), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.Double")
                {
                    stack.Push(ctx.MkBV(sizeof(System.Double), 32));
                    return;
                }
                else if ((instr.Operand as TypeRef).FullName == "System.Guid")
                {
                    stack.Push(ctx.MkBV(0x10, 32));
                    return;
                }
            }

            stack.PushUnknown();
        }
Пример #23
0
 private void Translate_Ldsfld(CflowStack stack, Instruction instr)
 {
     stack.Push(instr.Operand as IField);
 }