Class: Ronin::Fuzzing::Mutator
- Inherits:
-
Object
- Object
- Ronin::Fuzzing::Mutator
- Defined in:
- lib/ronin/fuzzing/mutator.rb
Overview
Fuzzer class that permutates over every mutation of a String, given mutation rules.
Constant Summary collapse
- PATTERNS =
Support::Text::Patterns
Instance Attribute Summary collapse
-
#rules ⇒ Object
readonly
Mutation rules.
Instance Method Summary collapse
-
#each(string) {|mutant| ... } ⇒ Enumerator
Permutes over every possible mutation of the String.
-
#initialize(rules) ⇒ Mutator
constructor
Initialize the Mutator.
Constructor Details
#initialize(rules) ⇒ Mutator
Initialize the Mutator.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/ronin/fuzzing/mutator.rb', line 56 def initialize(rules) @rules = {} rules.each do |pattern,mutation| pattern = case pattern when Regexp pattern when String Regexp.new(Regexp.escape(pattern)) when Symbol PATTERNS.const_get(pattern.upcase) else raise(TypeError,"cannot convert #{pattern.inspect} to a Regexp") end mutation = case mutation when Enumerable mutation when Symbol Ronin::Fuzzing[mutation] else raise(TypeError,"mutation #{mutation.inspect} must be a Symbol or Enumerable") end @rules[pattern] = mutation end end |
Instance Attribute Details
#rules ⇒ Object (readonly)
Mutation rules
44 45 46 |
# File 'lib/ronin/fuzzing/mutator.rb', line 44 def rules @rules end |
Instance Method Details
#each(string) {|mutant| ... } ⇒ Enumerator
Permutes over every possible mutation of the String.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/ronin/fuzzing/mutator.rb', line 99 def each(string) return enum_for(__method__,string) unless block_given? matches = Set[] @rules.each do |pattern,mutation| scanner = StringScanner.new(string) while scanner.scan_until(pattern) length = scanner.matched_size index = scanner.pos - length original = scanner.matched mutator = Combinatorics::Generator.new do |g| mutation.each do |mutate| g.yield case mutate when Proc mutate.call(original) when Integer mutate.chr else mutate.to_s end end end matches << [index, length, mutator] end end matches.powerset do |submatches| # ignore the empty Set next if submatches.empty? # sort the submatches by index submatches = submatches.sort_by { |index,length,mutator| index } sets = [] prev_index = 0 submatches.each do |index,length,mutator| # add the previous substring to the set of Strings if index > prev_index sets << [string[prev_index,index - prev_index]] end # add the mutator to the set of Strings sets << mutator prev_index = index + length end # add the remaining substring to the set of Strings if prev_index < string.length sets << [string[prev_index..-1]] end sets.comprehension { |strings| yield strings.join } end return nil end |