Class: OneGadget::Emulators::Mips
- Defined in:
- lib/one_gadget/emulators/mips.rb
Overview
Emulator of MIPS (32-bit, o32).
Constant Summary collapse
- COND =
This arch compares and branches in one instruction -- there is no flag register -- so each mnemonic names the relation its operands must stand in for the branch to be taken. The spellings against zero name one operand;
zerois the other, and reads as the0x0it holds. { 'beq' => :eq, 'bne' => :ne, 'beqz' => :eq, 'bnez' => :ne, 'blez' => :sle, 'bgtz' => :sgt, 'bltz' => :slt, 'bgez' => :sge }.freeze
Constants inherited from Processor
Constants included from Constraints
Constraints::ADDRESS_TYPES, Constraints::CLOBBERED, Constraints::NULLABLE_REQUIREMENTS, Constraints::POINTER_REQUIREMENTS
Constants included from Conditional
Conditional::COMPARE_OPS, Conditional::NEGATE, Conditional::RELATION, Conditional::ZERO
Instance Attribute Summary
Attributes inherited from Processor
#bp, #pc, #refused_line, #registers, #sp
Class Method Summary collapse
-
.bits ⇒ Integer
o32 is 32-bit.
Instance Method Summary collapse
-
#argument(idx) ⇒ Lambda, Integer
The value of a call's +idx+-th argument.
-
#initialize ⇒ Mips
constructor
Instantiate a Mips object.
-
#instructions ⇒ Array<Instruction>
Supported instruction set.
-
#process!(cmd) ⇒ Boolean
Emulate one instruction, holding back any transfer of control.
Methods inherited from Processor
instruction_table, line_memo, #parse, #process, #reach_terminal_call, #terminal_call?
Methods included from TrackedMemory
#bp_based_stack, #get_corresponding_stack, #resolve_address, #setup_frame_pointer, #sp_based_stack, #writes_through
Methods included from Constraints
#address_deref0?, #closed_fds, #constraint_key, #constraints, #drop_implied_nonzero, #drop_restated_null, #render_constraint
Methods included from Conditional
#branch_on_bit, #branch_on_compare, #branch_on_zero, #comparisons_on, #handle_compare, #mnemonic, #operand_str, #record_compare, #resolve_pending_branch, #satisfiable?, #value_str
Constructor Details
#initialize ⇒ Mips
Instantiate a OneGadget::Emulators::Mips object.
12 13 14 15 16 |
# File 'lib/one_gadget/emulators/mips.rb', line 12 def initialize super(OneGadget::ABI.mips, 'sp') @registers['zero'] = 0 # hardwired @pc = 'pc' end |
Class Method Details
.bits ⇒ Integer
o32 is 32-bit.
283 284 285 |
# File 'lib/one_gadget/emulators/mips.rb', line 283 def bits 32 end |
Instance Method Details
#argument(idx) ⇒ Lambda, Integer
The value of a call's +idx+-th argument. o32 states the first four in registers, and reserves a stack slot for every argument including those -- so an argument's slot is its index however it is passed, and the ones past the registers are read from there.
74 75 76 77 78 79 |
# File 'lib/one_gadget/emulators/mips.rb', line 74 def argument(idx) return registers["a#{idx}"] if idx < ARG_REGISTERS top = registers['sp'].evaluate('sp' => 0) sp_based_stack[top + (idx * size_t)] end |
#instructions ⇒ Array<Instruction>
Supported instruction set. Anything not listed aborts the candidate.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/one_gadget/emulators/mips.rb', line 52 def instructions [ Instruction.new('addiu', 3), Instruction.new('addu', 3), Instruction.new('bal', 1), Instruction.new('jal', 1), Instruction.new('jalr', 1..2), Instruction.new('li', 2), Instruction.new('lui', 2), Instruction.new('move', 2), Instruction.new('nop', 0), Instruction.new('subu', 3) ] + (LOADS.keys + STORES.keys).map { |mnem| Instruction.new(mnem, 2) } + DATA_OPS.keys.map { |mnem| Instruction.new(mnem, 3) } end |
#process!(cmd) ⇒ Boolean
Emulate one instruction, holding back any transfer of control.
This arch delays every transfer by one instruction: whatever follows a branch or a call runs before it takes effect. So a transfer is held back here and applied once that instruction has run, which is the order they really happen in -- and it leaves both addresses of the pair meaning what they say, since entering at the transfer runs both, while entering at the instruction after it runs only that one.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/one_gadget/emulators/mips.rb', line 92 def process!(cmd) resolve_pending_branch(cmd) @cur_addr = cmd[/\A\s*([0-9a-f]+):/, 1]&.to_i(16) @got_value = cmd[GOT_VALUE, 1]&.to_i(16) mnem = mnemonic(cmd) if transfer?(mnem) @delayed = [mnem, cmd] return true end dispatch(cmd) && apply_delayed end |