Пример #1
0
        /// <summary>
        /// This function meshes up a conditional jump
        /// </summary>
        /// <param name="bb">The block containing the conditional jump to mesh up</param>
        private static void InsertConditionals(BasicBlock bb)
        {
            Variable var = null, tmp;

            Instruction.RelationalOperationType relop = 0;
            int?       C         = 0;
            BasicBlock truesucc  = null;
            BasicBlock falsesucc = null;

            Parser.ConditionalJump(bb.Instructions.Last(), out var, out tmp, out C, out relop, out truesucc, out falsesucc);
            List <Cond> condlist = GenetateCondList((int)C, relop);

            GenerateBlocks(bb, var, truesucc, falsesucc, condlist, (int)C, relop);
        }
Пример #2
0
        /// <summary>
        /// Generates the surrounding CondConstants around a specific constant
        /// </summary>
        /// <param name="originalconstant">The actual constant which is the base of the generation</param>
        /// <param name="originalrelop">The original relational operator</param>
        /// <returns>The list of generated CondConstants</returns>
        private static List <Cond> GenetateCondList(int originalconstant, Instruction.RelationalOperationType originalrelop)
        {
            int         num        = Common.ConditionalJumpRadius;
            List <Cond> returnlist = new List <Cond>();

            for (int i = -1, n = 0; n < num; n++)
            {
                returnlist.Add(new Cond(originalconstant + i, originalrelop, originalconstant));

                if (i > 0)
                {
                    i++;
                }
                else if (i < -1)
                {
                    i--;
                }
                i *= -1;
            }
            returnlist.Shuffle <Cond>();
            RepositionLasts(returnlist);
            return(returnlist);
        }
Пример #3
0
        /// <summary>
        /// Extracts the relop from a condition
        /// </summary>
        /// <returns>The extracted variable</returns>
        public Instruction.RelationalOperationType GetRelopFromCondition()
        {
            Validate();
            Instruction.RelationalOperationType relop = 0;
            string relop_sign = Regex.Match(TACtext, @"( == )|( != )|( > )|( >= )|( < )|( <= )").Value.Trim();

            switch (relop_sign)
            {
            case "==":
                relop = Instruction.RelationalOperationType.Equals;
                break;

            case "!=":
                relop = Instruction.RelationalOperationType.NotEquals;
                break;

            case ">":
                relop = Instruction.RelationalOperationType.Greater;
                break;

            case ">=":
                relop = Instruction.RelationalOperationType.GreaterOrEquals;
                break;

            case "<":
                relop = Instruction.RelationalOperationType.Smaller;
                break;

            case "<=":
                relop = Instruction.RelationalOperationType.SmallerOrEquals;
                break;

            default:
                throw new ObjectException("Cannot parse relational operator.");
            }
            return(relop);
        }
Пример #4
0
 /// <summary>
 /// Sets the jump type of the Cond, based on the original relational operator, and a pattern
 /// </summary>
 /// <param name="originalrelop">The original relational operator</param>
 private void LessPattern(Instruction.RelationalOperationType originalrelop)
 {
     relop = (Instruction.RelationalOperationType)Randomizer.OneFromMany(Instruction.RelationalOperationType.Equals,
                                                                         Instruction.RelationalOperationType.Greater,
                                                                         Instruction.RelationalOperationType.GreaterOrEquals,
                                                                         Instruction.RelationalOperationType.NotEquals,
                                                                         Instruction.RelationalOperationType.Smaller,
                                                                         Instruction.RelationalOperationType.SmallerOrEquals);
     if (relop == Instruction.RelationalOperationType.Smaller || relop == Instruction.RelationalOperationType.SmallerOrEquals || relop == Instruction.RelationalOperationType.Equals)
     {
         if (originalrelop == Instruction.RelationalOperationType.Greater || originalrelop == Instruction.RelationalOperationType.GreaterOrEquals || originalrelop == Instruction.RelationalOperationType.Equals)
         {
             JumpType = BlockJumpType.False;
         }
         else
         {
             JumpType = BlockJumpType.True;
         }
     }
     else
     {
         JumpType = BlockJumpType.Ambigious;
     }
 }
Пример #5
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);
        }
Пример #6
0
        /// <summary>
        /// Makes ConditionalJump instruction type from NoOperation (+ links Successors and Predecessors)
        /// </summary>
        /// <param name="left_value">Left value in relation (only variable)</param>
        /// <param name="right_value">Left value in relation (only numerical value)</param>
        /// <param name="relop">Relational operation</param>
        /// <param name="target">Target basic block the control flow is transfered to, if the relation holds true</param>
        public static void ConditionalJump(Instruction ins, Variable left_value, int right_value, Instruction.RelationalOperationType relop, BasicBlock target)
        {
            if (ins.statementType != Objects.Common.StatementType.NoOperation && ins.statementType != Objects.Common.StatementType.UnconditionalJump)
            {
                throw new ObfuscatorException("Only NoOperation or UnconditionalJump instructions can be modified to ConditionalJump type!");
            }

            if (target.parent != ins.parent.parent)
            {
                throw new ObfuscatorException("Target basic block and original are in different functions.");
            }

            if (ins.parent.getSuccessors.Count != 1)
            {
                throw new ObfuscatorException("The basic block should have exactly one successor.");
            }

            if (left_value == null)
            {
                throw new ObfuscatorException("Wrong parameter passing.");
            }

            if (!ins.parent.Instructions.Last().Equals(ins))
            {
                throw new ObfuscatorException("Only the last instruction of a basic block can be modified to ConditionalJump.");
            }

            ins.RefVariables.Add(left_value);
            ins.statementType = Objects.Common.StatementType.ConditionalJump;
            string strRelop = string.Empty;

            switch (relop)
            {
            case Instruction.RelationalOperationType.Equals:
                strRelop = "==";
                break;

            case Instruction.RelationalOperationType.NotEquals:
                strRelop = "!=";
                break;

            case Instruction.RelationalOperationType.Greater:
                strRelop = ">";
                break;

            case Instruction.RelationalOperationType.GreaterOrEquals:
                strRelop = ">=";
                break;

            case Instruction.RelationalOperationType.Smaller:
                strRelop = "<";
                break;

            case Instruction.RelationalOperationType.SmallerOrEquals:
                strRelop = "<=";
                break;

            default:
                throw new ObfuscatorException("Unsupported relational operator type.");
            }
            ins.TACtext = string.Join(" ", "if", left_value.name, strRelop, right_value, "goto", target.ID);
            ins.parent.LinkToSuccessor(target, false, true);
        }
Пример #7
0
        /// <summary>
        /// Parses a conditional jump instruction
        /// </summary>
        /// <param name="inst">Instruction to be parsed (conditional jump statement only)</param>
        /// <param name="left_value">Left value of the condition (variable)</param>
        /// <param name="right_value">Right value of the condition (variable)</param>
        /// <param name="right_value_int">Right value of the condition (integer)</param>
        /// <param name="relop">Relational operator of the condition</param>
        /// <param name="true_bb">Basic block the control flow is transfered to if the condition returns TRUE</param>
        /// <param name="false_bb">Basic block the control flow is transfered to if the condition returns FALSE</param>
        public static void ConditionalJump(Instruction inst, out Variable left_value, out Variable right_value, out int?right_value_int, out Instruction.RelationalOperationType relop, out BasicBlock true_bb, out BasicBlock false_bb)
        {
            Validate(inst, Objects.Common.StatementType.ConditionalJump);

            System.Collections.Specialized.StringCollection refvarIDs = new System.Collections.Specialized.StringCollection();
            Match matchResult = Regex.Match(inst.TACtext, "ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}", RegexOptions.None);

            while (matchResult.Success)
            {
                refvarIDs.Add(matchResult.Value);
                matchResult = matchResult.NextMatch();
            }

            left_value = inst.RefVariables.Find(x => x.ID == refvarIDs[0]);

            if (refvarIDs.Count == 3)
            {
                right_value     = inst.RefVariables.Find(x => x.ID == refvarIDs[1]);
                right_value_int = null;
            }
            else
            {
                right_value_int = Convert.ToInt32(inst.TACtext.Split(' ')[3]);
                right_value     = null;
            }

            string relop_sign = Regex.Match(inst.TACtext, @"( == )|( != )|( > )|( >= )|( < )|( <= )").Value.Trim();

            switch (relop_sign)
            {
            case "==":
                relop = Instruction.RelationalOperationType.Equals;
                break;

            case "!=":
                relop = Instruction.RelationalOperationType.NotEquals;
                break;

            case ">":
                relop = Instruction.RelationalOperationType.Greater;
                break;

            case ">=":
                relop = Instruction.RelationalOperationType.GreaterOrEquals;
                break;

            case "<":
                relop = Instruction.RelationalOperationType.Smaller;
                break;

            case "<=":
                relop = Instruction.RelationalOperationType.SmallerOrEquals;
                break;

            default:
                throw new ParserException("Cannot parse relational operator.");
            }

            // True basic block
            true_bb = inst.parent.getSuccessors.First();
            // False basic block
            false_bb = inst.parent.getSuccessors.Last();
        }
Пример #8
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);
            }
        }
Пример #9
0
            /// <summary>
            /// Sets the jump type of a Cond
            /// </summary>
            /// <param name="generatedconstant">The constant which has been generated by us</param>
            /// <param name="originalconstant">The original constant</param>
            /// <param name="originalrelop">The original relational operator</param>
            private void SetJumpType(int generatedconstant, int originalconstant, Instruction.RelationalOperationType originalrelop)
            {
                if (generatedconstant == originalconstant - 1)
                {
                    switch (originalrelop)
                    {
                    case Instruction.RelationalOperationType.GreaterOrEquals:
                        relop    = Instruction.RelationalOperationType.Greater;
                        JumpType = BlockJumpType.Last;
                        break;

                    case Instruction.RelationalOperationType.Smaller:
                        relop    = Instruction.RelationalOperationType.SmallerOrEquals;
                        JumpType = BlockJumpType.Last;
                        break;

                    case Instruction.RelationalOperationType.Equals:
                        relop    = Instruction.RelationalOperationType.Greater;
                        JumpType = BlockJumpType.Last;
                        break;

                    case Instruction.RelationalOperationType.NotEquals:
                        relop    = Instruction.RelationalOperationType.Smaller;
                        JumpType = BlockJumpType.Last;
                        break;

                    default:
                        LessPattern(originalrelop);
                        break;
                    }
                }
                else if (generatedconstant == originalconstant + 1)
                {
                    switch (originalrelop)
                    {
                    case Instruction.RelationalOperationType.Greater:
                        relop    = Instruction.RelationalOperationType.GreaterOrEquals;
                        JumpType = BlockJumpType.Last;
                        break;

                    case Instruction.RelationalOperationType.SmallerOrEquals:
                        relop    = Instruction.RelationalOperationType.Smaller;
                        JumpType = BlockJumpType.Last;
                        break;

                    case Instruction.RelationalOperationType.Equals:
                        relop    = Instruction.RelationalOperationType.Smaller;
                        JumpType = BlockJumpType.Last;
                        break;

                    case Instruction.RelationalOperationType.NotEquals:
                        relop    = Instruction.RelationalOperationType.Greater;
                        JumpType = BlockJumpType.Last;
                        break;

                    default:
                        GreaterPattern(originalrelop);
                        break;
                    }
                }
                else if (generatedconstant < originalconstant)
                {
                    LessPattern(originalrelop);
                }
                else
                {
                    GreaterPattern(originalrelop);
                }
            }
Пример #10
0
 /// <summary>
 /// Constructor to the condition class
 /// </summary>
 /// <param name="generatedconstant">The generated constant of the condition</param>
 /// <param name="originalrelop">The original relational operator</param>
 /// <param name="originalconstant">The original constant</param>
 public Cond(int generatedconstant, Instruction.RelationalOperationType originalrelop, int originalconstant)
 {
     value = generatedconstant;
     SetJumpType(generatedconstant, originalconstant, originalrelop);
 }
Пример #11
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);
        }