Пример #1
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);
        }