Exemplo n.º 1
0
 /// <summary>
 /// The meshing algorithm, which will mesh the unconditional jumps in a routine
 /// </summary>
 /// <param name="rtn">The routine which will be meshed up</param>
 public static void MeshUnconditionals(Routine rtn)
 {
     /// Meshing of the unconditional jumps
     foreach (Function funct in rtn.Functions)
     {
         List <BasicBlock> basicblocks = funct.BasicBlocks.FindAll(x => x.Instructions.Last().statementType == Objects.Common.StatementType.UnconditionalJump);
         foreach (BasicBlock bb in basicblocks)
         {
             int i = Randomizer.SingleNumber(0, 100);
             if (i <= Common.UnconditionalMeshingProbability)
             {
                 BasicBlock originalSuccessor = bb.getSuccessors.First();
                 BasicBlock falseLane         = new BasicBlock(bb.parent);
                 //The false lane involves fake variables only in other to provided the correct output
                 falseLane.Involve  = BasicBlock.InvolveInFakeCodeGeneration.FakeVariablesOnly;
                 falseLane.Meshable = false;
                 BasicBlock trueLane = new BasicBlock(bb.parent);
                 //The true lane should involve both fake and original variables in other to provided the wrong output
                 if (funct.containsDivisionModulo == false || originalSuccessor.Instructions.FindAll(x => x.TACtext.Contains("return")).Count > 0)
                 {
                     trueLane.Involve = BasicBlock.InvolveInFakeCodeGeneration.Both;
                 }
                 trueLane.Meshable   = false;
                 trueLane.inFakeLane = true;
                 //Linking first the false lane
                 bb.LinkToSuccessor(falseLane, true);
                 //Creating the jump to the true lane
                 MakeInstruction.RandomConditionalJump(bb.Instructions.Last(), Instruction.ConditionType.AlwaysFalse, trueLane);
                 ExpandMainRoute(falseLane, originalSuccessor, false);
                 ExpandFakeRoute(trueLane, originalSuccessor, false);
             }
         }
     }
 }
Exemplo n.º 2
0
        /// <summary>
        /// Expands the Main Route into the CFG, creating the conditional jump for both Main Route and Fake Route
        /// </summary>
        /// <param name="fake1">The first fake basic block to be used in the expansion</param>
        /// <param name="mainLaneBB">The original basic block we should jump to stay in the Main Route</param>
        /// <param name="atFakeCodeGeneration">Wheter we are or not at the fake code generation phase</param>
        private static void ExpandMainRoute(BasicBlock fake1, BasicBlock originalSuccessor, bool atFakeCodeGeneration)
        {
            //Fetching the Conditional Jump (AlwaysFalse) created in the previous basic block
            Instruction originalInstruction = fake1.getPredecessors.First().Instructions.Last();

            //Defining the constant and relational operator for the fake1 conditional jump
            Instruction.RelationalOperationType relationalOperation;
            int rightValue = 0;

            if (originalInstruction.GetConstFromCondition() >= originalInstruction.GetVarFromCondition().fixedMax.Value)
            {
                //If the variable's fixed minimun is diferent from the global min plus the maximun loop range, we should try
                //to get a value different from the variable's fixed minimun in order to have a more belieavable code
                do
                {
                    rightValue = Randomizer.SingleNumber(Common.GlobalMinValue + Common.LoopConditionalJumpMaxRange,
                                                         originalInstruction.GetVarFromCondition().fixedMin.Value);
                } while (rightValue == originalInstruction.GetVarFromCondition().fixedMin.Value&&
                         originalInstruction.GetVarFromCondition().fixedMin.Value != Common.GlobalMinValue + Common.LoopConditionalJumpMaxRange);

                relationalOperation = (Instruction.RelationalOperationType)
                                      Randomizer.OneFromMany(Instruction.RelationalOperationType.Smaller,
                                                             Instruction.RelationalOperationType.SmallerOrEquals);
            }
            else
            {
                //If the variable's fixed maximun is diferent from the global max minus the maximun loop range, we should try
                //to get a value different from the variable's fixed maximun in order to have a more belieavable code
                do
                {
                    rightValue = Randomizer.SingleNumber(originalInstruction.GetVarFromCondition().fixedMax.Value,
                                                         Common.GlobalMaxValue - Common.LoopConditionalJumpMaxRange);
                } while (rightValue == originalInstruction.GetVarFromCondition().fixedMax.Value&&
                         originalInstruction.GetVarFromCondition().fixedMax.Value != Common.GlobalMaxValue - Common.LoopConditionalJumpMaxRange);

                relationalOperation = (Instruction.RelationalOperationType)
                                      Randomizer.OneFromMany(Instruction.RelationalOperationType.Greater,
                                                             Instruction.RelationalOperationType.GreaterOrEquals);
            }

            //Creating and expanding the false lane that stays in the Main Route
            fake1.LinkToSuccessor(ExpandMainRoute(originalSuccessor), true);

            //Creating fake2 to hold the true lane for the conditional jump
            BasicBlock fake2 = new BasicBlock(fake1.parent);

            fake2.Meshable = false;
            if (fake2.parent.containsDivisionModulo == false || originalSuccessor.Instructions.FindAll(x => x.TACtext.Contains("return")).Count > 0)
            {
                fake2.Involve = BasicBlock.InvolveInFakeCodeGeneration.Both;
            }

            //Creating the conditional jump (always false) to fake route
            Variable var = originalInstruction.GetVarFromCondition();

            MakeInstruction.ConditionalJump(fake1.Instructions.Last(), var, rightValue, relationalOperation, fake2);
            //Expanding the fake route
            ExpandFakeRoute(fake2, originalSuccessor, atFakeCodeGeneration);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Updates all CALLs according to the number of fake and original parameters of the called functions
        /// </summary>
        public static void UpdateAllFunctionCalls(Function func)
        {
            //We use a dictionary to store the "call" instruction and its index inside the basic block
            Dictionary <Instruction, int> allCalls = new Dictionary <Instruction, int>();
            List <Instruction>            bbCalls  = new List <Instruction>();

            foreach (BasicBlock bb in func.BasicBlocks)
            {
                //We collect all "call" instructions in this basic block

                bbCalls = bb.Instructions.FindAll(x => x.TACtext.Contains("call") && !x.TACtext.Contains("printf") &&
                                                  !x.TACtext.Contains("scanf"));
                foreach (Instruction ins in bbCalls)
                {
                    //Storing all "call" instructions in the actual basic block with their indexes
                    allCalls.Add(ins, bb.Instructions.IndexOf(ins));
                }
            }

            //We check wheter we have any "call" instruction in this function
            if (allCalls.Count > 0)
            {
                foreach (Instruction call in allCalls.Keys)
                {
                    //Splitting the call in tokens - tokens[0] = "call", tokens[1] = "function_ID", tokens[2] = "numParams"
                    string[] tokens = call.TACtext.Split(' ');
                    //Checking wheter if the called function is present in our routine (internal function)
                    if (func.parent.Functions.Exists(x => x.ID == tokens[1]))
                    {
                        //Getting the number of parameters to update it later
                        int numParams = int.Parse(tokens[2]);
                        //Fetching fake input parameters
                        List <Variable> fakeInputsParams = func.LocalVariables.FindAll(x => x.kind == Variable.Kind.Input && x.fake == true);
                        //Number of lines that are shifted during the injection of fake "param" instructions
                        int shift = 0;
                        foreach (Variable fakeInputVar in fakeInputsParams)
                        {
                            Instruction param = new Instruction(call.parent);
                            MakeInstruction.ProceduralParam(param, fakeInputVar, null);
                            //Inserting the "param" instruction right before the "call" instruction
                            call.parent.Instructions.Insert(allCalls[call] + shift, param);
                            shift++;
                            //Updating the number of parameters for this call
                            numParams++;
                        }

                        //Updating the TAC text of the call with the new number of parameters
                        call.parent.Instructions[allCalls[call] + shift].TACtext = string.Join(" ", "call", tokens[1],
                                                                                               numParams);
                    }
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Inserts two additional instructions for constant coverage
        /// </summary>
        /// <param name="const_inst">The instruction with a constant value</param>
        /// <param name="const_value">Numerical constant value to be covered</param>
        private static void ProcessConstant(Instruction const_inst, int const_value)
        {
            List <int>  two_places = Randomizer.MultipleNumbers(2, 0, const_inst.parent.Instructions.BinarySearch(const_inst), true, true);
            Instruction nop1       = new Instruction(const_inst.parent);
            Instruction nop2       = new Instruction(const_inst.parent);
            // We assume that we need 4 bytes for each constant.
            Variable t1           = const_inst.parent.parent.NewLocalVariable(Variable.Purpose.ConstRecalculation, Objects.Common.MemoryRegionSize.Integer);
            Variable t2           = const_inst.parent.parent.NewLocalVariable(Variable.Purpose.ConstRecalculation, Objects.Common.MemoryRegionSize.Integer);
            int      first_number = Randomizer.SingleNumber(Common.GlobalMinValue, Common.GlobalMaxValue);

            Instruction.ArithmeticOperationType op = first_number < const_value ? Instruction.ArithmeticOperationType.Addition : Instruction.ArithmeticOperationType.Subtraction;
            int second_number = Math.Abs(first_number - const_value);

            MakeInstruction.Copy(nop1, t2, null, first_number);
            MakeInstruction.FullAssignment(nop2, t1, t2, null, second_number, op);
            const_inst.parent.Instructions.Insert(two_places[1], nop2);
            const_inst.parent.Instructions.Insert(two_places[0], nop1);
            const_inst.ModifyConstInstruction(t1, const_value);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Function to make a Conditional Jump out of a Nop.
        /// </summary>
        /// <param name="ins">The nop we want to work on.</param>
        private static void GenerateConditionalJump(Instruction ins)
        {
            /*
             * Before doing anything, we have to split the basic block holding this
             * instruction, so we can make a conditional jump at the end of the
             * new basic block, unless it is already the last instruction.
             */
            if (!ins.Equals(ins.parent.Instructions.Last()))
            {
                ins.parent.SplitAfterInstruction(ins);
            }


            // We create a jump target.
            BasicBlock jumptarget = new BasicBlock(ins.parent.parent);

            // We make a random conditional jump here, which has to be always false.
            MakeInstruction.RandomConditionalJump(ins, Instruction.ConditionType.AlwaysFalse, jumptarget);

            //We expand the Fake Route as we did during meshing
            Meshing.ExpandFakeRoute(jumptarget, ins.parent.getSuccessors.Last(), true);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Expands the Main Route into the CFG, inserting "FakeVariablesOnly" basic blocks and random conditional jump
        /// between them
        /// </summary>
        /// <param name="originaltarget">The basic block we should go to stay in the Main Route</param>
        private static BasicBlock ExpandMainRoute(BasicBlock originaltarget)
        {
            // Creating a new basic block
            BasicBlock fake1 = new BasicBlock(originaltarget.parent);

            fake1.Instructions.Add(new Instruction(fake1));
            fake1.Meshable = false;

            // Creating the second fake block
            BasicBlock fake2 = new BasicBlock(originaltarget.parent);

            fake2.Instructions.Add(new Instruction(fake2));

            // Starting the linking
            MakeInstruction.UnconditionalJump(fake1.Instructions.Last(), fake2);

            BasicBlock polyrequtarget = null;

            // Creating a clone of the original target in order to make the CFT more obfuscated
            if (originaltarget.Instructions.Last().statementType == Objects.Common.StatementType.UnconditionalJump)
            {
                polyrequtarget = new BasicBlock(originaltarget, originaltarget.getSuccessors);
            }
            else
            {
                polyrequtarget = originaltarget;
            }

            // And now setting the edges
            MakeInstruction.UnconditionalJump(fake2.Instructions.Last(), polyrequtarget);

            // And then converting its nop instruction into a ConditionalJump
            MakeInstruction.RandomConditionalJump(fake1.Instructions.Last(), Instruction.ConditionType.Random, originaltarget);

            return(fake1);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Makes random conditional jump instruction + links basic blocks and sets RefVars
        /// </summary>
        /// <param name="nop">NoOperation instruction (will be made into ConditionalJump)</param>
        /// <param name="condition">Type of condition</param>
        /// <param name="target">Target basic block the control flow is transfered to, if the relation holds true.</param>
        public static void RandomConditionalJump(Instruction nop, Instruction.ConditionType condition, BasicBlock target)
        {
            if (nop.statementType != Objects.Common.StatementType.NoOperation && nop.statementType != Objects.Common.StatementType.UnconditionalJump)
            {
                throw new ObfuscatorException("Only NoOperation and UnconditionalJump instructions can be modified to ConditionalJump!");
            }
            if (nop.parent == null || nop.parent.parent == null)
            {
                throw new ObfuscatorException("Instruction -> basic block -> function parent link is broken.");
            }
            if (nop.parent.parent != target.parent)
            {
                throw new ObfuscatorException("The instruction and the basic block should be contained in the same function.");
            }

            Variable var = FakeParameters.GetRandom(nop.parent.parent);

            if (var.fixedMax.HasValue && var.fixedMax.Value > Common.GlobalMaxValue)
            {
                throw new ObfuscatorException("The fixedMax value is greated then the globally accepted maximum.");
            }
            if (var.fixedMin.HasValue && var.fixedMin.Value < Common.GlobalMinValue)
            {
                throw new ObfuscatorException("The fixedMin value is smaller then the globally accepted minimum.");
            }
            int right_value = 0;

            Instruction.RelationalOperationType relop = Instruction.RelationalOperationType.Equals;
            bool use_min_limit = false;

            // Here we chose to use a FixedMin or FixedMax for logical relation
            if (var.fixedMin.HasValue && var.fixedMax.HasValue)
            {
                use_min_limit = (bool)Randomizer.OneFromMany(true, false);
            }
            else if (var.fixedMin.HasValue)
            {
                use_min_limit = true;
            }

            if (use_min_limit)  // FixedMin will be used
            {
                right_value = Randomizer.OneFromSectionWithDescendingProbability(var.fixedMin.Value, Common.GlobalMinValue + Common.LoopConditionalJumpMaxRange);
                switch (condition)
                {
                case Instruction.ConditionType.AlwaysTrue:
                    relop = (Instruction.RelationalOperationType)Randomizer.OneFromMany(Instruction.RelationalOperationType.Greater,
                                                                                        Instruction.RelationalOperationType.GreaterOrEquals);
                    break;

                case Instruction.ConditionType.AlwaysFalse:
                    relop = (Instruction.RelationalOperationType)Randomizer.OneFromMany(Instruction.RelationalOperationType.Smaller,
                                                                                        Instruction.RelationalOperationType.SmallerOrEquals);
                    break;

                case Instruction.ConditionType.Random:
                    relop = (Instruction.RelationalOperationType)Randomizer.OneFromMany(Instruction.RelationalOperationType.Smaller,
                                                                                        Instruction.RelationalOperationType.SmallerOrEquals,
                                                                                        Instruction.RelationalOperationType.Greater,
                                                                                        Instruction.RelationalOperationType.GreaterOrEquals);
                    break;

                default:
                    throw new ObfuscatorException("Unrecognized condition type.");
                }
            }

            if (!use_min_limit)     // FixedMax will be used
            {
                right_value = Randomizer.OneFromSectionWithDescendingProbability(var.fixedMax.Value, Common.GlobalMaxValue - Common.LoopConditionalJumpMaxRange);
                switch (condition)
                {
                case Instruction.ConditionType.AlwaysTrue:
                    relop = (Instruction.RelationalOperationType)Randomizer.OneFromMany(Instruction.RelationalOperationType.Smaller,
                                                                                        Instruction.RelationalOperationType.SmallerOrEquals);
                    break;

                case Instruction.ConditionType.AlwaysFalse:
                    relop = (Instruction.RelationalOperationType)Randomizer.OneFromMany(Instruction.RelationalOperationType.Greater,
                                                                                        Instruction.RelationalOperationType.GreaterOrEquals);
                    break;

                case Instruction.ConditionType.Random:
                    relop = (Instruction.RelationalOperationType)Randomizer.OneFromMany(Instruction.RelationalOperationType.Smaller,
                                                                                        Instruction.RelationalOperationType.SmallerOrEquals,
                                                                                        Instruction.RelationalOperationType.Greater,
                                                                                        Instruction.RelationalOperationType.GreaterOrEquals);
                    break;

                default:
                    throw new ObfuscatorException("Unrecognized condition type.");
                }
            }
            MakeInstruction.ConditionalJump(nop, var, right_value, relop, target);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Function to make an actual fake instruction out of a Nop.
        /// </summary>
        /// <param name="ins">The nop we want to work on.</param>
        private static void _GenerateFakeInstruction(Instruction ins)
        {
            /* First we get a left value. */
            Variable leftvalue = GetLeftValueForInstruction(ins);

            /* Then we check how many variables can we use as right value. */
            List <Variable> rightvalues = GetRandomRightValues(ins, 2);

            /* We random generate a statement type which we may not use according to the available right values. */
            Objects.Common.StatementType statementType =
                (Objects.Common.StatementType)Randomizer.OneFromManyWithProbability(
                    new int[3] {
                25, 15, 60
            },
                    Objects.Common.StatementType.Copy,
                    Objects.Common.StatementType.UnaryAssignment,
                    Objects.Common.StatementType.FullAssignment);

            /*
             * The number of the available right values determines which kind of instructions
             * can we generate.
             *
             *  - If we don't have any, then we must make a Copy with a constant.
             *
             *  - If we have one, and it's the same as the left value, then we have to make
             *    a Unary Assignment.
             *
             *  - If we have one, but it's different from the left value, then we can make
             *    a Copy (1), a Unary Assignment (2) and a Full Assignment with a constant (3).
             *
             *  - If we have two, we can make all these and a Full Assignment with two
             *    variables.
             *
             * Another important thing is that we cannot fill the variables with a value
             * without using themselves (like t = t + 1) while inside a loop.
             */
            switch (rightvalues.Count)
            {
            case 0:
                /* If we have no available right values, and we are in a loop, then we can't do anything. */
                if (DataAnalysis.isLoopBody[ins.parent])
                {
                    return;
                }

                /* We don't have any right values, so we have to copy a constant value. */
                else
                {
                    MakeInstruction.Copy(ins, leftvalue, null, Randomizer.SingleNumber(Common.GlobalMinValue, Common.GlobalMaxValue));
                }
                break;

            case 1:
                /* We choose Full Assignment, or rightvalue is the same as leftvalue, or we are in a loop body. */
                if (DataAnalysis.isLoopBody[ins.parent] || leftvalue.Equals(rightvalues[0]) ||
                    statementType == Objects.Common.StatementType.FullAssignment ||
                    (ins.DeadVariables.Keys.Contains(leftvalue) &&
                     ins.DeadVariables[leftvalue] == Variable.State.Filled))
                {
                    /* Here we random generate an operator. */
                    Instruction.ArithmeticOperationType op =
                        (Instruction.ArithmeticOperationType)Randomizer.OneFromMany(Instruction.ArithmeticOperationType.Addition,
                                                                                    Instruction.ArithmeticOperationType.Division,
                                                                                    Instruction.ArithmeticOperationType.Multiplication,
                                                                                    Instruction.ArithmeticOperationType.Subtraction);

                    int num;

                    if (op == Instruction.ArithmeticOperationType.Addition || op == Instruction.ArithmeticOperationType.Subtraction)
                    {
                        num = Randomizer.SingleNumber(Common.GlobalMinValue, Common.GlobalMaxValue);
                    }

                    else
                    {
                        /*
                         * Here we generate an integer number which is the power of 2, and is
                         * within the boundaries of GlobalMinNumber and GlobalMaxNumber.
                         */
                        int min = Convert.ToInt32(Math.Ceiling(Math.Log(Common.GlobalMinValue, 2)));
                        int max = Convert.ToInt32(Math.Floor(Math.Log(Common.GlobalMaxValue, 2)));
                        int pow = Randomizer.SingleNumber(min, max);
                        num = Convert.ToInt32(Math.Pow(2, pow));
                    }

                    MakeInstruction.FullAssignment(ins, leftvalue, rightvalues.First(), null, num, op);
                }

                /* If we choose Unary Assignment. */
                else if (statementType == Objects.Common.StatementType.UnaryAssignment)
                {
                    MakeInstruction.UnaryAssignment(ins, leftvalue, rightvalues.First(), Instruction.UnaryOperationType.ArithmeticNegation);
                }

                /* If we choose Copy. */
                else
                {
                    MakeInstruction.Copy(ins, leftvalue, rightvalues.First(), null);
                }
                break;

            case 2:
                /* We make sure that the first right value isn't the same as the left value. */
                if (leftvalue.Equals(rightvalues.First()))
                {
                    Variable tmp = rightvalues[0];
                    rightvalues[0] = rightvalues[1];
                    rightvalues[1] = tmp;
                }

                /*
                 * If we are in a loop body, then we can only make a full assignment like that:
                 * t1 = t2 op t1
                 */
                if (DataAnalysis.isLoopBody[ins.parent] || statementType == Objects.Common.StatementType.FullAssignment ||
                    (ins.DeadVariables.Keys.Contains(leftvalue) &&
                     ins.DeadVariables[leftvalue] == Variable.State.Filled))
                {
                    /* Here we random generate an operator: + or - */
                    /* TODO: (efficient) * and / */
                    Instruction.ArithmeticOperationType op =
                        (Instruction.ArithmeticOperationType)Randomizer.OneFromMany(Instruction.ArithmeticOperationType.Addition,
                                                                                    Instruction.ArithmeticOperationType.Subtraction);

                    if (DataAnalysis.isLoopBody[ins.parent] ||
                        (ins.DeadVariables.Keys.Contains(leftvalue) &&
                         ins.DeadVariables[leftvalue] == Variable.State.Filled))
                    {
                        MakeInstruction.FullAssignment(ins, leftvalue, rightvalues[0], leftvalue, null, op);
                    }

                    else
                    {
                        MakeInstruction.FullAssignment(ins, leftvalue, rightvalues[0], rightvalues[1], null, op);
                    }
                }

                /* If we choose Copy. */
                else if (statementType == Objects.Common.StatementType.Copy)
                {
                    MakeInstruction.Copy(ins, leftvalue, rightvalues.First(), null);
                }

                /* If we choose Unary Assignment. */
                else
                {
                    MakeInstruction.UnaryAssignment(ins, leftvalue, rightvalues.First(), Instruction.UnaryOperationType.ArithmeticNegation);
                }
                break;
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// This function generates the BasicBlocks into the function, based on the condition list
        /// </summary>
        /// <param name="bb">The actual basicblock with the conditional jump at the end</param>
        /// <param name="truelane">The true successor</param>
        /// <param name="falselane">The false successor</param>
        /// <param name="condlist">The condition list</param>
        /// <returns>The list of the generated BasicBlocks</returns>
        private static void GenerateBlocks(BasicBlock bb, Variable var, BasicBlock truelane, BasicBlock falselane, List <Cond> condlist, int originalconstant, Instruction.RelationalOperationType originalrelop)
        {
            List <BasicBlock> bblist = new List <BasicBlock>();

            foreach (Cond c in condlist)
            {
                bblist.Add(new BasicBlock(bb.parent));
                bblist.Last().Instructions.Add(new Instruction(bblist.Last()));
            }

            bb.Instructions.Remove(bb.Instructions.Last());
            bb.Instructions.Add(new Instruction(bb));

            /// Replacing the first one, with the original
            bb.parent.BasicBlocks.Remove(bblist.First());
            bblist.Remove(bblist.First());
            bblist.Insert(0, bb);

            /// Creating the polyRequired list
            List <BasicBlock> truelist = new List <BasicBlock>();

            truelist.Add(truelane);
            List <BasicBlock> falselist = new List <BasicBlock>();

            falselist.Add(falselane);

            for (int i = 0; i < condlist.Count(); i++)
            {
                switch (condlist[i].JumpType)
                {
                case Cond.BlockJumpType.True:
                case Cond.BlockJumpType.Last:
                    if (i != condlist.Count() - 1)
                    {
                        bblist[i].LinkToSuccessor(bblist[i + 1], true);
                    }
                    else
                    {
                        bblist[i].LinkToSuccessor(GeneratePolyReqJumpTarget(falselist), true);
                    }
                    MakeInstruction.ConditionalJump(bblist[i].Instructions.Last(), var, condlist[i].value, condlist[i].relop, GeneratePolyReqJumpTarget(truelist));
                    break;

                case Cond.BlockJumpType.False:
                    if (i != condlist.Count() - 1)
                    {
                        bblist[i].LinkToSuccessor(bblist[i + 1], true);
                    }
                    else
                    {
                        bblist[i].LinkToSuccessor(GeneratePolyReqJumpTarget(falselist), true);
                    }
                    MakeInstruction.ConditionalJump(bblist[i].Instructions.Last(), var, condlist[i].value, condlist[i].relop, GeneratePolyReqJumpTarget(falselist));
                    break;

                case Cond.BlockJumpType.Ambigious:
                    BasicBlock ambhelper = new BasicBlock(bb.parent);
                    bblist[i].LinkToSuccessor(ambhelper, true);
                    ambhelper.Instructions.Add(new Instruction(ambhelper));
                    if ((condlist[i].value + 1 == originalconstant || condlist[i].value - 1 == originalconstant) &&
                        originalrelop == Instruction.RelationalOperationType.NotEquals)
                    {
                        MakeInstruction.UnconditionalJump(ambhelper.Instructions.Last(), GeneratePolyReqJumpTarget(bblist.GetRange(i + 1, bblist.Count - (i + 1))));
                        MakeInstruction.ConditionalJump(bblist[i].Instructions.Last(), var, condlist[i].value, condlist[i].relop, truelist.First());
                    }
                    else
                    {
                        if ((originalconstant > condlist[i].value && (condlist[i].relop == Instruction.RelationalOperationType.Greater ||
                                                                      condlist[i].relop == Instruction.RelationalOperationType.GreaterOrEquals) &&
                             (originalrelop == Instruction.RelationalOperationType.Greater ||
                              originalrelop == Instruction.RelationalOperationType.GreaterOrEquals)) ||
                            (originalconstant < condlist[i].value && (condlist[i].relop == Instruction.RelationalOperationType.Smaller ||
                                                                      condlist[i].relop == Instruction.RelationalOperationType.SmallerOrEquals) &&
                             (originalrelop == Instruction.RelationalOperationType.Smaller ||
                              originalrelop == Instruction.RelationalOperationType.SmallerOrEquals)) ||
                            (originalconstant < condlist[i].value && (originalrelop == Instruction.RelationalOperationType.Smaller ||
                                                                      originalrelop == Instruction.RelationalOperationType.SmallerOrEquals) &&
                             (condlist[i].relop == Instruction.RelationalOperationType.NotEquals)) ||
                            (originalconstant > condlist[i].value && (originalrelop == Instruction.RelationalOperationType.Greater ||
                                                                      originalrelop == Instruction.RelationalOperationType.GreaterOrEquals) &&
                             (condlist[i].relop == Instruction.RelationalOperationType.NotEquals)))
                        {
                            MakeInstruction.UnconditionalJump(ambhelper.Instructions.Last(), GeneratePolyReqJumpTarget(falselist));
                        }
                        else
                        {
                            MakeInstruction.UnconditionalJump(ambhelper.Instructions.Last(), GeneratePolyReqJumpTarget(truelist));
                        }
                        MakeInstruction.ConditionalJump(bblist[i].Instructions.Last(), var, condlist[i].value, condlist[i].relop, bblist[i + 1]);
                    }
                    break;

                default:
                    break;
                }
            }
            /// Checking if there is a jump to the original targets, and if there is not, we can delete that
            /// BasicBlock, there must be a polyRequired clone of that.
            if (falselane.getPredecessors.Count() == 0)
            {
                foreach (BasicBlock succ in falselane.getSuccessors)
                {
                    succ.getPredecessors.Remove(falselane);
                }
                falselane.parent.BasicBlocks.Remove(falselane);
            }
            if (truelane.getPredecessors.Count() == 0)
            {
                foreach (BasicBlock succ in truelane.getSuccessors)
                {
                    succ.getPredecessors.Remove(truelane);
                }
                truelane.parent.BasicBlocks.Remove(truelane);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Expands the fake route into the CFG and creates the conditional jumps for both Loop and Fake code
        /// </summary>
        /// <param name="fake1">The first fake basic block to be used in the expansion</param>
        /// <param name="mainLaneBB">The basic block we should go in case of no-loop</param>
        /// <param name="atFakeCodeGeneration">Wheter we are or not at the fake code generation phase</param>
        public static void ExpandFakeRoute(BasicBlock fake1, BasicBlock originalSuccessor, bool atFakeJumpGeneration)
        {
            //Creating fake2 to hold the next Loop condition
            BasicBlock fake2 = new BasicBlock(fake1.parent);

            fake2.Meshable = false;
            if (fake2.parent.containsDivisionModulo == false ||
                originalSuccessor.Instructions.FindAll(x => x.TACtext.Contains("return")).Count > 0)
            {
                fake2.Involve = BasicBlock.InvolveInFakeCodeGeneration.Both;
            }
            fake2.inFakeLane = true;

            //Creating fake3 to hold the extra fake code in case of No-Loop
            BasicBlock fake3 = new BasicBlock(fake1.parent);

            if (fake3.parent.containsDivisionModulo == false ||
                originalSuccessor.Instructions.FindAll(x => x.TACtext.Contains("return")).Count > 0)
            {
                fake3.Involve = BasicBlock.InvolveInFakeCodeGeneration.Both;
            }
            fake3.inFakeLane = true;

            //Creating the fake3 unconditional jump back to the Main Lane
            MakeInstruction.UnconditionalJump(fake3.Instructions.Last(), originalSuccessor);

            //Linking fake3 to fake2
            fake2.LinkToSuccessor(fake3);

            //Creating fake4 to hold the extra fake code in case of No-Loop
            BasicBlock fake4 = new BasicBlock(fake1.parent);

            if (fake4.parent.containsDivisionModulo == false ||
                originalSuccessor.Instructions.FindAll(x => x.TACtext.Contains("return")).Count > 0)
            {
                fake4.Involve = BasicBlock.InvolveInFakeCodeGeneration.Both;
            }
            fake4.inFakeLane = true;

            //Creating the fake4 unconditional jump back to the Main Lane
            MakeInstruction.UnconditionalJump(fake4.Instructions.Last(), originalSuccessor);

            //Linking fake4 to fake1
            fake1.LinkToSuccessor(fake4);

            //Fetching the Conditional Jump (AlwaysFalse) created in the previous basic block
            Instruction originalInstruction = fake1.getPredecessors.First().Instructions.Last();

            //Defining the relational operator for the fake1 conditional jump
            Instruction.RelationalOperationType relationalOperationEF1 = (Instruction.RelationalOperationType)
                                                                         Randomizer.OneFromMany(Instruction.RelationalOperationType.Smaller,
                                                                                                Instruction.RelationalOperationType.SmallerOrEquals,
                                                                                                Instruction.RelationalOperationType.Greater,
                                                                                                Instruction.RelationalOperationType.GreaterOrEquals);

            //Defining the constant for the fake1 conditional jump
            int rightValueEF1 = 0;

            if (originalInstruction.GetConstFromCondition() >= originalInstruction.GetVarFromCondition().fixedMax.Value)
            {
                //If the original instruction's contant is diferent from the global max minus the max loop range, we should try
                //to get a value different from the original instruction's constant in order to have a more belieavable code
                do
                {
                    rightValueEF1 = Randomizer.SingleNumber((int)originalInstruction.GetConstFromCondition(),
                                                            Common.GlobalMaxValue - Common.LoopConditionalJumpMaxRange);
                } while (rightValueEF1 == (int)originalInstruction.GetConstFromCondition() &&
                         (int)originalInstruction.GetConstFromCondition() != Common.GlobalMaxValue - Common.LoopConditionalJumpMaxRange);
            }
            else
            {
                //If the original instruction's contant is diferent from the global min plus the max loop range, we should try
                //to get a value different from the original instruction's constant in order to have a more belieavable code
                do
                {
                    rightValueEF1 = Randomizer.SingleNumber(Common.GlobalMinValue + Common.LoopConditionalJumpMaxRange,
                                                            (int)originalInstruction.GetConstFromCondition());
                } while (rightValueEF1 == (int)originalInstruction.GetConstFromCondition() &&
                         (int)originalInstruction.GetConstFromCondition() != Common.GlobalMinValue + Common.LoopConditionalJumpMaxRange);
            }
            //Creating the fake1 conditional jump
            Variable var = originalInstruction.GetVarFromCondition();

            MakeInstruction.ConditionalJump(fake1.Instructions.Last(), var, rightValueEF1, relationalOperationEF1, fake2);

            //Defining the range for the fake2 conditional jump constant
            int range = Randomizer.SingleNumber(0, Common.LoopConditionalJumpMaxRange);

            //Defining relational operation for the extraFake2 conditional jump based on the extraFake1 condtional jump relational operation and the range
            Instruction.RelationalOperationType relationalOperationEF2 = Instruction.RelationalOperationType.Equals;
            switch (relationalOperationEF1)
            {
            case Instruction.RelationalOperationType.Smaller:
            case Instruction.RelationalOperationType.SmallerOrEquals:
                if (range <= 1)
                {
                    relationalOperationEF2 = Instruction.RelationalOperationType.Equals;
                }
                else if (range == 2)
                {
                    relationalOperationEF2 = (Instruction.RelationalOperationType)
                                             Randomizer.OneFromMany(Instruction.RelationalOperationType.GreaterOrEquals,
                                                                    Instruction.RelationalOperationType.Equals);
                }
                else
                {
                    relationalOperationEF2 = (Instruction.RelationalOperationType)
                                             Randomizer.OneFromMany(Instruction.RelationalOperationType.Greater,
                                                                    Instruction.RelationalOperationType.GreaterOrEquals,
                                                                    Instruction.RelationalOperationType.Equals);
                }
                break;

            case Instruction.RelationalOperationType.Greater:
            case Instruction.RelationalOperationType.GreaterOrEquals:
                if (range <= 1)
                {
                    relationalOperationEF2 = Instruction.RelationalOperationType.Equals;
                }
                else if (range == 2)
                {
                    relationalOperationEF2 = (Instruction.RelationalOperationType)
                                             Randomizer.OneFromMany(Instruction.RelationalOperationType.SmallerOrEquals,
                                                                    Instruction.RelationalOperationType.Equals);
                }
                else
                {
                    relationalOperationEF2 = (Instruction.RelationalOperationType)
                                             Randomizer.OneFromMany(Instruction.RelationalOperationType.Smaller,
                                                                    Instruction.RelationalOperationType.SmallerOrEquals,
                                                                    Instruction.RelationalOperationType.Equals);
                }
                break;
            }

            //Defining the constant for the fake2 conditional jump
            int rightValueEF2 = 0;

            if (rightValueEF1 == Common.GlobalMinValue || rightValueEF1 == Common.GlobalMaxValue)
            {
                rightValueEF2 = rightValueEF1;
            }
            else
            {
                switch (relationalOperationEF2)
                {
                case Instruction.RelationalOperationType.Smaller:
                case Instruction.RelationalOperationType.SmallerOrEquals:
                    if (rightValueEF1 + range > Common.GlobalMaxValue)
                    {
                        rightValueEF2 = Randomizer.SingleNumber(rightValueEF1, Common.GlobalMaxValue);
                    }
                    else if (rightValueEF1 + range > (int)originalInstruction.GetConstFromCondition() &&
                             (originalInstruction.GetRelopFromCondition() == Instruction.RelationalOperationType.Smaller ||
                              originalInstruction.GetRelopFromCondition() == Instruction.RelationalOperationType.SmallerOrEquals))
                    {
                        rightValueEF2 = Randomizer.SingleNumber(rightValueEF1, (int)originalInstruction.GetConstFromCondition());
                    }
                    else
                    {
                        rightValueEF2 = Randomizer.SingleNumber(rightValueEF1, rightValueEF1 + range);
                    }
                    break;

                case Instruction.RelationalOperationType.Greater:
                case Instruction.RelationalOperationType.GreaterOrEquals:
                    if (rightValueEF1 - range < Common.GlobalMinValue)
                    {
                        rightValueEF2 = Randomizer.SingleNumber(Common.GlobalMinValue, rightValueEF1);
                    }
                    else if (rightValueEF1 - range < (int)originalInstruction.GetConstFromCondition() &&
                             (originalInstruction.GetRelopFromCondition() == Instruction.RelationalOperationType.Greater ||
                              originalInstruction.GetRelopFromCondition() == Instruction.RelationalOperationType.GreaterOrEquals))
                    {
                        rightValueEF2 = Randomizer.SingleNumber((int)originalInstruction.GetConstFromCondition(), rightValueEF1);
                    }
                    else
                    {
                        rightValueEF2 = Randomizer.SingleNumber(rightValueEF1 - range, rightValueEF1);
                    }
                    break;

                case Instruction.RelationalOperationType.Equals:
                {
                    switch (relationalOperationEF1)
                    {
                    case Instruction.RelationalOperationType.Smaller:
                    case Instruction.RelationalOperationType.SmallerOrEquals:
                        if (rightValueEF1 - range < Common.GlobalMinValue)
                        {
                            rightValueEF2 = Randomizer.SingleNumber(Common.GlobalMinValue, rightValueEF1);
                        }
                        else if (rightValueEF1 - range < (int)originalInstruction.GetConstFromCondition() &&
                                 (originalInstruction.GetRelopFromCondition() == Instruction.RelationalOperationType.Greater ||
                                  originalInstruction.GetRelopFromCondition() == Instruction.RelationalOperationType.GreaterOrEquals))
                        {
                            rightValueEF2 = Randomizer.SingleNumber((int)originalInstruction.GetConstFromCondition(), rightValueEF1);
                        }
                        else
                        {
                            rightValueEF2 = Randomizer.SingleNumber(rightValueEF1 - range, rightValueEF1);
                        }
                        break;

                    case Instruction.RelationalOperationType.Greater:
                    case Instruction.RelationalOperationType.GreaterOrEquals:
                        if (rightValueEF1 + range > Common.GlobalMaxValue)
                        {
                            rightValueEF2 = Randomizer.SingleNumber(rightValueEF1, Common.GlobalMaxValue);
                        }
                        else if (rightValueEF1 + range > (int)originalInstruction.GetConstFromCondition() &&
                                 (originalInstruction.GetRelopFromCondition() == Instruction.RelationalOperationType.Smaller ||
                                  originalInstruction.GetRelopFromCondition() == Instruction.RelationalOperationType.SmallerOrEquals))
                        {
                            rightValueEF2 = Randomizer.SingleNumber(rightValueEF1, (int)originalInstruction.GetConstFromCondition());
                        }
                        else
                        {
                            rightValueEF2 = Randomizer.SingleNumber(rightValueEF1, rightValueEF1 + range);
                        }
                        break;
                    }
                    break;
                }
                }
            }

            //Selecting the target for fake2 in order to create a loop
            List <BasicBlock> reacheableBasicBlocks = DataAnalysis.GetReachableBasicBlocks(fake2, Common.Direction.Up);

            //In case we are at fake jump generation, we should try to choose reachable basic blocks in a loop body
            //in order to make the CFG irreducible
            if (atFakeJumpGeneration)
            {
                List <BasicBlock> loopReachableBasicBlocks = reacheableBasicBlocks.FindAll(x => DataAnalysis.isLoopBody.Keys.Contains(x) &&
                                                                                           DataAnalysis.isLoopBody[x] == true);
                //If we have reachable basic blocks in a loop body, we can use them
                if (loopReachableBasicBlocks.Count > 0)
                {
                    int i = Randomizer.SingleNumber(0, 100);
                    if (!fake2.parent.irreducibleCFG || i <= Common.JumpLoopBodyProbability)
                    {
                        reacheableBasicBlocks       = loopReachableBasicBlocks;
                        fake2.parent.irreducibleCFG = true;
                    }
                }
            }
            //Check whether the amount of reachable basic blocks we have is greater than MaxJumpForLoop.
            //This parameter is used to control the chance of problems ("nops" left in the end) during
            //fake instructions generation.
            if (reacheableBasicBlocks.Count > Common.MaxJumpBackForLoop)
            {
                reacheableBasicBlocks.RemoveRange(Common.MaxJumpBackForLoop, reacheableBasicBlocks.Count - Common.MaxJumpBackForLoop);
            }

            //Defining the target basic block for the conditional jump
            BasicBlock loopTarget = (BasicBlock)Randomizer.OneFromMany(reacheableBasicBlocks.ToArray());

            //Creating the fake2 conditional jump to the loop target
            MakeInstruction.ConditionalJump(fake2.Instructions.Last(), var, rightValueEF2, relationalOperationEF2, loopTarget);
        }