Class: Rex::Poly::Machine::Solution

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/poly/machine/machine.rb

Overview

A class to hold a solution for a Rex::Poly::Machine problem.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSolution

Returns a new instance of Solution.



265
266
267
268
269
# File 'lib/rex/poly/machine/machine.rb', line 265

def initialize
  @permutations = ::Array.new
  @reg_state    = ::Array.new
  @offset       = 0
end

Instance Attribute Details

#offsetObject (readonly)

Returns the value of attribute offset.



263
264
265
# File 'lib/rex/poly/machine/machine.rb', line 263

def offset
  @offset
end

Instance Method Details

#bufferObject

Render the final buffer.



310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/rex/poly/machine/machine.rb', line 310

def buffer
  previous_offset = nil
  count           = 0
  # perform an N-pass fixup for offsets...
  while( true ) do
    # If we cant get the offsets fixed within a fixed ammount of tries we return
    # nil to indicate failure and keep searching for a solution that will work.
    if( count > 64 )
      return nil
    end
    # Reset the solution offset so as to update it for this pass
    @offset = 0
    # perform a single pass to ensure we are using the correct offset values
    @permutations.each do | permutation |
      permutation.offset = @offset
      # Note: calling render() can throw both UndefinedPermutation and UnallowedPermutation exceptions,
      # however as we assume we only ever return the buffer once a final solution has been generated
      # we should never have either of those exceptions thrown.
      permutation.render
      @offset += permutation.length
    end
    # If we have generated two consecutive passes which are the same length we can stop fixing up the offsets.
    if( not previous_offset.nil? and @offset == previous_offset )
      break
    end
    count +=1
    previous_offset = @offset
  end
  # now a final pass to render the solution into the raw buffer
  raw = ''
  @permutations.each do | permutation |
    #$stderr.puts "#{permutation.name} - #{ "0x%08X (%d)" % [ permutation.offset, permutation.length] } "
    raw << permutation.render
  end
  return raw
end

#popObject

Pop off the last permutaion and register/variables state from this solution.



298
299
300
301
302
303
304
305
# File 'lib/rex/poly/machine/machine.rb', line 298

def pop
  reg_available, reg_consumed, variables = @reg_state.pop
  permutation = @permutations.pop
  permutation.active = false
  permutation.offset = 0
  @offset -= permutation.length
  return permutation, reg_available, reg_consumed, variables
end

#push(permutation, reg_available, reg_consumed, variables) ⇒ Object

Push a new permutation onto this solutions permutations list and save the associated register/variables state



287
288
289
290
291
292
293
# File 'lib/rex/poly/machine/machine.rb', line 287

def push( permutation, reg_available, reg_consumed, variables )
  permutation.active = true
  permutation.offset = @offset
  @offset += permutation.length
  @permutations.push( permutation )
  @reg_state.push( [ [].concat(reg_available), [].concat(reg_consumed), {}.merge(variables) ] )
end

#resetObject

Reset this solution to an empty state.



274
275
276
277
278
279
280
281
282
# File 'lib/rex/poly/machine/machine.rb', line 274

def reset
  @offset = 0
  @permutations.each do | permutation |
    permutation.active = false
    permutation.offset = 0
  end
  @permutations.clear
  @reg_state.clear
end