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