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.



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

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

Instance Attribute Details

#offsetObject (readonly)

Returns the value of attribute offset.



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

def offset
  @offset
end

Instance Method Details

#bufferObject

Render the final buffer.



309
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
# File 'lib/rex/poly/machine/machine.rb', line 309

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.



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

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



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

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.



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

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