class OneGadget::Emulators::Processor
Base class of a processor.
Attributes
Public Class Methods
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
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
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
@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
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 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 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
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
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
# 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
# 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
# File lib/one_gadget/emulators/processor.rb, line 130 def eval_dict { sp => 0 } end
# File lib/one_gadget/emulators/processor.rb, line 138 def global_var?(obj) obj.to_s.include?(pc) end
# File lib/one_gadget/emulators/processor.rb, line 126 def raise_unsupported(inst, *args) raise OneGadget::Error::UnsupportedInstructionArgumentError, "#{inst} #{args.join(', ')}" end
# File lib/one_gadget/emulators/processor.rb, line 110 def register?(reg) registers.include?(reg) end
# File lib/one_gadget/emulators/processor.rb, line 134 def size_t self.class.bits / 8 end
# File lib/one_gadget/emulators/processor.rb, line 114 def to_lambda(reg) OneGadget::Emulators::Lambda.new(reg) end