class OneGadget::Emulators::Instruction

Define instruction name and it’s argument count.

Attributes

argc[R]
inst[R]

Public Class Methods

new(inst, argc) click to toggle source

Instantiate a {Instruction} object. @param [String] inst The instruction name. @param [Range, Integer] argc

Count of arguments.
Negative integer for doesn't care the number of arguments.
# File lib/one_gadget/emulators/instruction.rb, line 17
def initialize(inst, argc)
  @inst = inst
  @argc = case argc
          when -1 then 0..Float::INFINITY
          when Range then argc
          when Integer then argc..argc
          end
end

Public Instance Methods

fetch_args(cmd) click to toggle source

Extract arguments from command. @param [String] cmd @return [Array<String>] Arguments. @raise [OneGadget::Error::InstructionArgumentError]

# File lib/one_gadget/emulators/instruction.rb, line 30
def fetch_args(cmd)
  idx = cmd.index(inst)
  cmd = cmd[0...cmd.rindex('//')] if cmd.rindex('//')
  cmd = cmd[0...cmd.rindex('#')] if cmd.rindex('#')
  args = parse_args(cmd[idx + inst.size..-1])
  unless argc.include?(args.size)
    raise OneGadget::Error::InstructionArgumentError, "Incorrect argument number in #{cmd}, expect: #{argc}"
  end

  args.map do |arg|
    arg.gsub(/XMMWORD|QWORD|DWORD|WORD|BYTE|PTR/, '').strip
  end
end
match?(cmd) click to toggle source

If the command contains this instruction. @param [String] cmd @return [Boolean]

# File lib/one_gadget/emulators/instruction.rb, line 47
def match?(cmd)
  (cmd =~ /#{inst}\s/) != nil
end

Private Instance Methods

parse_args(str) click to toggle source
# File lib/one_gadget/emulators/instruction.rb, line 53
def parse_args(str)
  args = []
  cur = +''
  bkt_cnt = 0
  str.each_char do |c|
    if c == ',' && bkt_cnt.zero?
      args << cur
      cur = +''
      next
    end

    cur << c
    case c
    when '[' then bkt_cnt += 1
    when ']' then bkt_cnt -= 1
    end
  end
  args << cur unless cur.empty?
  args
end