/// <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); }
private static void Obfuscation(Routine routine) { Logging.WriteComplexityMetrics(routine, "Original"); //Checking whether the functions have either "division" or "modulo" operations //If they do, fake instructions with original variables should be inserted only before the return //to avoid problems with the these operations foreach (Function func in routine.Functions) { func.CheckDivisionModulo(); } //Creating fake input parameters in all functions FakeParameters.CreateFakeParameters(routine); //Checking for Multiple Obfuscation for (int i = 0; i < Convert.ToInt32(ConfigurationManager.AppSettings["MultipleRuns"]); i++) { //Creating fake variables foreach (Function func in routine.Functions) { for (int j = 0; j < (Common.PercentageFakeVars * func.LocalVariables.FindAll(x => !x.fake).Count) / 100; j++) { func.LocalVariables.Add(new Variable(Variable.Kind.Local, Variable.Purpose.Fake, Objects.Common.MemoryRegionSize.Integer)); } } if (ConfigurationManager.AppSettings["ConstCoverAlgInMultipleRuns"].Split('-')[i].Equals("1")) { Console.Write("Step 1: Constants coverage"); ConstCoverage.CoverConstants(routine); routine.Validate(); PrintSuccess(); Logging.WriteReadableTAC(routine, "CONST"); Logging.DrawCFG(routine, "CONST"); } if (ConfigurationManager.AppSettings["UncMeshingAlgInMultipleRuns"].Split('-')[i].Equals("1")) { Console.Write("Step 2: Meshing unconditional jumps"); Meshing.MeshUnconditionals(routine); routine.Validate(); PrintSuccess(); Logging.WriteReadableTAC(routine, "MeshingUNC"); Logging.DrawCFG(routine, "MeshingUNC"); } if (ConfigurationManager.AppSettings["CondMeshingAlgInMultipleRuns"].Split('-')[i].Equals("1")) { Console.Write("Step 3: Meshing conditional jumps"); Meshing.MeshConditionals(routine); routine.Validate(); PrintSuccess(); Logging.WriteReadableTAC(routine, "MeshingCOND"); Logging.DrawCFG(routine, "MeshingCOND"); } Console.Write("Step 4: Generation of fake NOP instructions"); foreach (Function func in routine.Functions) { FakeCode.GenerateNoOperations(func); } routine.Validate(); PrintSuccess(); Logging.WriteRoutine(routine, "NoOpersGeneration"); Logging.WriteReadableTAC(routine, "FakeNOPs"); Console.Write("Step 5: Partial data analysis"); DataAnalysis.GatherBasicBlockInfo(routine); PrintSuccess(); if (ConfigurationManager.AppSettings["FakeJumpsAlgInMultipleRuns"].Split('-')[i].Equals("1")) { Console.Write("Step 6: Generation of fake conditional jumps from NOPs"); foreach (Function func in routine.Functions) { FakeCode.GenerateConditionalJumps(func); } Logging.WriteRoutine(routine, "CondJumps"); foreach (Function func in routine.Functions) { FakeCode.GenerateNoOperations(func); } routine.Validate(); PrintSuccess(); } Console.Write("Step 7: Complete data analysis"); foreach (Function func in routine.Functions) { DataAnalysis.DeadVarsAlgortihm(func); } DataAnalysis.GatherBasicBlockInfo(routine); PrintSuccess(); Console.Write("Step 8: Generation of fake instructions from NOPs"); foreach (Function func in routine.Functions) { FakeCode.GenerateFakeInstructions(func); } Logging.WriteRoutine(routine, "FakeIns"); Logging.DrawCFG(routine, "CondJumps"); Logging.WriteComplexityMetrics(routine, "Final"); FakeCode.CheckForProblems(routine); routine.Validate(); PrintSuccess(); Logging.WriteReadableTAC(routine, "FakeInstrFromNOPs"); } }