Class: Rex::Poly::Machine::Permutation
- Inherits:
-
Object
- Object
- Rex::Poly::Machine::Permutation
- Defined in:
- lib/rex/poly/machine/machine.rb
Overview
A Permutation!
Direct Known Subclasses
Instance Attribute Summary collapse
-
#active ⇒ Object
Returns the value of attribute active.
-
#args ⇒ Object
readonly
Returns the value of attribute args.
-
#length ⇒ Object
readonly
Returns the value of attribute length.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#offset ⇒ Object
Returns the value of attribute offset.
-
#primitive ⇒ Object
readonly
Returns the value of attribute primitive.
Instance Method Summary collapse
-
#add_child(child) ⇒ Object
Add in a child permutation to this one.
-
#has_children? ⇒ Boolean
Does this permutation have children?.
-
#initialize(name, primitive, machine, source, args = nil) ⇒ Permutation
constructor
Create a new permutation object.
-
#is_valid? ⇒ Boolean
Test if this permutation raw buffer is valid in this machine (e.g. against the badchar list).
-
#remove_children ⇒ Object
Remove any existing children.
-
#render ⇒ Object
Actully render this permutation into a raw buffer.
-
#solve ⇒ Object
Try to find a solution within the solution space by performing a depth first search into the permutation tree and backtracking when needed.
Constructor Details
#initialize(name, primitive, machine, source, args = nil) ⇒ Permutation
Create a new permutation object.
32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/rex/poly/machine/machine.rb', line 32 def initialize( name, primitive, machine, source, args=nil ) @name = name @primitive = primitive @machine = machine @source = source @args = args @active = false @valid = true @length = 0 @offset = 0 @children = ::Array.new end |
Instance Attribute Details
#active ⇒ Object
Returns the value of attribute active.
25 26 27 |
# File 'lib/rex/poly/machine/machine.rb', line 25 def active @active end |
#args ⇒ Object (readonly)
Returns the value of attribute args.
27 28 29 |
# File 'lib/rex/poly/machine/machine.rb', line 27 def args @args end |
#length ⇒ Object (readonly)
Returns the value of attribute length.
27 28 29 |
# File 'lib/rex/poly/machine/machine.rb', line 27 def length @length end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
27 28 29 |
# File 'lib/rex/poly/machine/machine.rb', line 27 def name @name end |
#offset ⇒ Object
Returns the value of attribute offset.
25 26 27 |
# File 'lib/rex/poly/machine/machine.rb', line 25 def offset @offset end |
#primitive ⇒ Object (readonly)
Returns the value of attribute primitive.
27 28 29 |
# File 'lib/rex/poly/machine/machine.rb', line 27 def primitive @primitive end |
Instance Method Details
#add_child(child) ⇒ Object
Add in a child permutation to this one. Used to build the permutation tree.
48 49 50 |
# File 'lib/rex/poly/machine/machine.rb', line 48 def add_child( child ) @children << child end |
#has_children? ⇒ Boolean
Does this permutation have children?
55 56 57 |
# File 'lib/rex/poly/machine/machine.rb', line 55 def has_children? not @children.empty? end |
#is_valid? ⇒ Boolean
Test if this permutation raw buffer is valid in this machine (e.g. against the badchar list).
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/rex/poly/machine/machine.rb', line 120 def is_valid? result = false if( @valid ) begin result = @machine.is_valid?( self.render ) rescue UnallowedPermutation # This permutation is unallowed and can never be rendered so just mark it as # not valid to skip it during future attempts. @valid = false rescue UndefinedPermutation # allow an undefined permutation to fail validation but keep it marked # as valid as it may be defined and passed validation later. ensure # Should a temporary variable have been assigned we can release it here. @machine.release_temp_variable end end return result end |
#remove_children ⇒ Object
Remove any existing children. Called by the machines generate function to build a fresh tree in case generate was previously called.
63 64 65 |
# File 'lib/rex/poly/machine/machine.rb', line 63 def remove_children @children.clear end |
#render ⇒ Object
Actully render this permutation into a raw buffer.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/rex/poly/machine/machine.rb', line 70 def render raw = '' # Zero the length as we will be rendering the raw buffer and the length may change. @length = 0 # If this permutation source is a Primitive/Procedure we can call it, otherwise we have a string if( @source.kind_of?( Primitive ) or @source.kind_of?( ::Proc ) ) if( @source.kind_of?( Primitive ) ) raw = @source.call( @name, @machine, *@args ) elsif( @source.kind_of?( ::Proc ) ) raw = @source.call end # If the primitive/procedure returned an array, it is an array of assembly strings which we can assemble. if( raw.kind_of?( ::Array ) ) lines = raw raw = '' # itterate over each line of assembly lines.each do | asm | # parse the asm and substitute in any offset values specified... offsets = asm.scan( /:([\S]+)_offset/ ) offsets.each do | name, | asm = asm.gsub( ":#{name}_offset", @machine.block_offset( name ).to_s ) end # and substitute in and register values for any variables specified... regs = asm.scan( /:([\S]+)_reg([\d]+)/ ) regs.each do | name, size | asm = asm.gsub( ":#{name}_reg#{size}", @machine.variable_value( name, size.to_i ) ) end # assemble it into a raw blob blob = @machine.assemble( asm ) #if( not @machine.is_valid?( blob ) ) # p "#{name}(#{primitive}):#{asm} is invalid" #end raw << blob end end else # the source must just be a static string raw = @source end # Update the length to reflect the new raw buffer @length = raw.to_s.length # As the temp variable is only assigned for the duration of a single permutation we # can now release it if it was used in this permutation. @machine.release_temp_variable return raw.to_s end |
#solve ⇒ Object
Try to find a solution within the solution space by performing a depth first search into the permutation tree and backtracking when needed.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/rex/poly/machine/machine.rb', line 144 def solve # Check to see if this permutation can make part of a valid solution if( self.is_valid? ) # record this permutation as part of the final solution (the current machines register state is also saved here) @machine.solution_push( self ) # If we have no children we are at the end of the tree and have a potential full solution. if( not self.has_children? ) # We have a solution but doing a final pass to update offsets may introduce bad chars # so we test for this and keep searching if this isnt a real solution after all. if( not @machine.solution_is_valid? ) # remove this permutation and keep searching @machine.solution_pop return false end # Return true to unwind the recursive call as we have got a final solution. return true end # Itterate over the children of this permutation (the perutations of the proceeding block). @children.each do | child | # Traverse into this child to keep trying to generate a solution... if( child.solve ) # Keep returning true to unwind as we are done. return true end end # If we get here this permutation, origionally thought to be good for a solution, is not after all, # so remove it from the machines final solution, restoring the register state aswell. @machine.solution_pop end # No children can be made form part of the solution, return failure for this path in the tree. return false end |