Class: OneGadget::Emulators::Instruction

Inherits:
Object
  • Object
show all
Defined in:
lib/one_gadget/emulators/instruction.rb

Overview

Define instruction name and it's argument count.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(inst, argc) ⇒ Instruction

Instantiate a OneGadget::Emulators::Instruction object.

Parameters:

  • inst (String)

    The instruction name.

  • argc (Range, Integer)

    Count of arguments. Negative integer for doesn't care the number of arguments.



17
18
19
20
21
22
23
24
# 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

Instance Attribute Details

#argcRange (readonly)

Returns Count of arguments.

Returns:

  • (Range)

    Count of arguments.



10
11
12
# File 'lib/one_gadget/emulators/instruction.rb', line 10

def argc
  @argc
end

#instString (readonly)

Returns The instruction name.

Returns:

  • (String)

    The instruction name.



9
10
11
# File 'lib/one_gadget/emulators/instruction.rb', line 9

def inst
  @inst
end

Class Method Details

.handler_name(mnemonic) ⇒ Symbol

The emulator method that runs mnemonic. A mnemonic is not always a method name -- one can carry a suffix spelled with a dot -- so the dots become underscores. Named here, rather than at each dispatch, so an emulator defining a family of handlers at once agrees with the dispatcher about what to call them.

Examples:

Instruction.handler_name('mov')     #=> :inst_mov
Instruction.handler_name('sext.w')  #=> :inst_sext_w

Parameters:

  • mnemonic (String)

Returns:

  • (Symbol)


63
# File 'lib/one_gadget/emulators/instruction.rb', line 63

def handler_name(mnemonic) = :"inst_#{mnemonic.tr('.', '_')}"

Instance Method Details

#fetch_args(cmd) ⇒ Array<String>

Extract arguments from command.

Parameters:

  • cmd (String)

    One line of objdump output containing this instruction.

Returns:

  • (Array<String>)

    The instruction's operands, with size hints and comments stripped.

Raises:



31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/one_gadget/emulators/instruction.rb', line 31

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..])
  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

#handlerSymbol

The emulator method that runs this instruction.

Returns:

  • (Symbol)

See Also:



69
70
71
# File 'lib/one_gadget/emulators/instruction.rb', line 69

def handler
  @handler ||= self.class.handler_name(inst)
end

#match?(cmd) ⇒ Boolean

If the command contains this instruction.

Parameters:

  • cmd (String)

    One line of objdump output.

Returns:

  • (Boolean)

    true if cmd contains this instruction's mnemonic.



48
49
50
# File 'lib/one_gadget/emulators/instruction.rb', line 48

def match?(cmd)
  cmd.match?(/#{Regexp.escape(inst)}\s/)
end