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