class OneGadget::Emulators::Processor

Base class of a processor.

Attributes

pc[R]
registers[R]
sp[R]
stack[R]

Public Class Methods

new(registers, sp) click to toggle source

Instantiate a {Processor} object. @param [Array<String>] registers

Registers that supported in the architecture.

@param [String] sp

The stack register.
# File lib/one_gadget/emulators/processor.rb, line 21
def initialize(registers, sp)
  @registers = registers.map { |reg| [reg, to_lambda(reg)] }.to_h
  @sp = sp
  @constraints = []
  @stack = Hash.new do |h, k|
    h[k] = OneGadget::Emulators::Lambda.new(sp).tap do |lmda|
      lmda.immi = k
      lmda.deref!
    end
  end
end

Private Class Methods

bits() click to toggle source

32 or 64. @return [Integer] 32 or 64.

# File lib/one_gadget/emulators/processor.rb, line 145
def bits; raise NotImplementedError
end

Public Instance Methods

argument(_idx) click to toggle source

To be inherited.

@param [Integer] _idx

The idx-th argument.

@return [Lambda, Integer]

Return value can be a {Lambda} or an +Integer+.
# File lib/one_gadget/emulators/processor.rb, line 78
def argument(_idx); raise NotImplementedError
end
constraints() click to toggle source

@return [Array<String>]

Extra constraints found during execution.
# File lib/one_gadget/emulators/processor.rb, line 83
def constraints
  return [] if @constraints.empty?

  # we have these types:
  # * :writable
  # * :raw
  cons = @constraints.uniq do |type, obj|
    next obj unless type == :writable

    obj.deref_count.zero? ? obj.obj.to_s : obj.to_s
  end
  cons.map { |type, obj| type == :writable ? "writable: #{obj}" : obj }.sort
end
instructions() click to toggle source

Method need to be implemented in inheritors. @return [Array<Instruction>] The support instructions.

# File lib/one_gadget/emulators/processor.rb, line 68
def instructions; raise NotImplementedError
end
parse(cmd) click to toggle source

Parse one command into instruction and arguments. @param [String] cmd One line of result of objdump. @return [(Instruction, Array<String>)]

The parsing result.
# File lib/one_gadget/emulators/processor.rb, line 37
def parse(cmd)
  inst = instructions.find { |i| i.match?(cmd) }
  raise Error::UnsupportedInstructionError, "Not implemented instruction in #{cmd}" if inst.nil?

  [inst, inst.fetch_args(cmd)]
end
process(cmd) click to toggle source

Process one command, without raising any exceptions. @param [String] cmd

See {#process!} for more information.

@return [Boolean]

# File lib/one_gadget/emulators/processor.rb, line 48
def process(cmd)
  process!(cmd)
# rescue OneGadget::Error::UnsupportedError => e; p e # for debugging
rescue OneGadget::Error::Error
  false
end
process!(_cmd) click to toggle source

Method need to be implemented in inheritors.

Process one command. Will raise exceptions when encounter unhandled instruction. @param [String] _cmd

One line from result of objdump.

@return [Boolean]

If successfully processed.
# File lib/one_gadget/emulators/processor.rb, line 63
def process!(_cmd); raise NotImplementedError
end

Private Instance Methods

arg_to_lambda(arg) click to toggle source

Fetch the corresponding lambda value of instruction arguments from the current register sets.

@param [String] arg The instruction argument passed to inst_* functions. @return [Lambda]

# File lib/one_gadget/emulators/processor.rb, line 122
def arg_to_lambda(arg)
  OneGadget::Emulators::Lambda.parse(arg, predefined: registers)
end
check_argument(idx, expect) click to toggle source
# File lib/one_gadget/emulators/processor.rb, line 103
def check_argument(idx, expect)
  case expect
  when :global_var? then global_var?(argument(idx))
  when :zero? then argument(idx).is_a?(Integer) && argument(idx).zero?
  end
end
check_register!(reg) click to toggle source
# File lib/one_gadget/emulators/processor.rb, line 99
def check_register!(reg)
  raise Error::InstructionArgumentError, "#{reg.inspect} is not a valid register" unless register?(reg)
end
eval_dict() click to toggle source
# File lib/one_gadget/emulators/processor.rb, line 130
def eval_dict
  { sp => 0 }
end
global_var?(obj) click to toggle source
# File lib/one_gadget/emulators/processor.rb, line 138
def global_var?(obj)
  obj.to_s.include?(pc)
end
raise_unsupported(inst, *args) click to toggle source
# File lib/one_gadget/emulators/processor.rb, line 126
def raise_unsupported(inst, *args)
  raise OneGadget::Error::UnsupportedInstructionArgumentError, "#{inst} #{args.join(', ')}"
end
register?(reg) click to toggle source
# File lib/one_gadget/emulators/processor.rb, line 110
def register?(reg)
  registers.include?(reg)
end
size_t() click to toggle source
# File lib/one_gadget/emulators/processor.rb, line 134
def size_t
  self.class.bits / 8
end
to_lambda(reg) click to toggle source
# File lib/one_gadget/emulators/processor.rb, line 114
def to_lambda(reg)
  OneGadget::Emulators::Lambda.new(reg)
end