/// <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); }
/// <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); }
/// <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); }
/// <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; } }
/// <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); }
/// <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); }
/// <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(); }
/// <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); } }
/// <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); } }
/// <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); }
/// <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); }