Class: Rex::Nop::Opty2
- Inherits:
-
Object
- Object
- Rex::Nop::Opty2
- Defined in:
- lib/rex/nop/opty2.rb
Overview
This class provides an interface to generating multi-byte NOP sleds for x86. Optyx and spoonm get the creds!
Constant Summary collapse
- Table =
Rex::Nop::Opty2Tables::StateTable
Instance Attribute Summary collapse
-
#badchars ⇒ Object
:nodoc:.
-
#save_registers ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#generate_sled(length) ⇒ Object
Generates the Opty2 multi-byte NOP sled.
-
#initialize(badchars = '', save_registers = nil) ⇒ Opty2
constructor
A new instance of Opty2.
Constructor Details
#initialize(badchars = '', save_registers = nil) ⇒ Opty2
Returns a new instance of Opty2.
18 19 20 21 |
# File 'lib/rex/nop/opty2.rb', line 18 def initialize(badchars = '', save_registers = nil) self.badchars = badchars self.save_registers = (save_registers || []) | [ 'esp', 'ebp'] end |
Instance Attribute Details
#badchars ⇒ Object
:nodoc:
105 106 107 |
# File 'lib/rex/nop/opty2.rb', line 105 def badchars @badchars end |
#save_registers ⇒ Object
:nodoc:
105 106 107 |
# File 'lib/rex/nop/opty2.rb', line 105 def save_registers @save_registers end |
Instance Method Details
#generate_sled(length) ⇒ Object
Generates the Opty2 multi-byte NOP sled.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/rex/nop/opty2.rb', line 26 def generate_sled(length) return '' if (length <= 0) # Initialize the sled buffer, the previous state, and the current stream # length. sled = '' prev = 256 slen = 0 # Initialize the byte count array counts = [] 256.times { |idx| counts[idx] = 0 } # Initialize the bad register mask mask = 0 save_registers.each { |reg| mask |= 1 << (Rex::Arch::X86.reg_number(reg)) } mask = mask << 16 # Initialize the bad byte lookup table bad_bytes = [] (badchars || '').each_byte { |byte| bad_bytes[byte] = 1 } # Build the sled while (length > 0) low = -1 lows = [] Table[prev].each { |nt| nt.each { |e| # Skip it if it's masked off or too large next if ((e & mask) != 0) next if (((e >> 8) & 0xff) > slen) byte = e & 0xff # Skip it if it's a bad byte next if (bad_bytes[byte] == 1) # Use it if it's a better value if ((low == -1) or (low > counts[byte])) low = counts[byte] lows = [byte] # Otherwise, if it's just as good.. elsif (low == counts[byte]) lows << byte end } } # If we didn't find at least one byte possibility, then we're stuck. # Abort. if (low == -1) raise RuntimeError, "Failed to find a valid byte." end # Pick a random character for the possiblities prev = lows[rand(lows.length)] # Increment its used count counts[prev] += 1 # Prepend the byte to the sled sled = prev.chr + sled # Increment the sled length slen += 1 length -= 1 end # Return the sled sled end |