x86 emulator
This commit is contained in:
parent
08bb6a1a51
commit
65abef7782
|
@ -4,6 +4,12 @@ module OneGadget
|
|||
module Emulators
|
||||
# Emulator of amd64 instruction set.
|
||||
class Amd64 < X86
|
||||
class << self
|
||||
def stack_pointer
|
||||
'rsp'
|
||||
end
|
||||
end
|
||||
|
||||
REGISTERS = %w(rax rbx rcx rdx rdi rsi rbp rsp rip) + 7.upto(15).map { |i| "r#{i}" }
|
||||
|
||||
# Instantiate a {Amd64} object.
|
||||
|
|
|
@ -4,7 +4,6 @@ module OneGadget
|
|||
module Emulators
|
||||
# Emulator of amd64 instruction set.
|
||||
class I386 < X86
|
||||
REGISTERS = %w(eax ebx ecx edx edi esi ebp esp eip).freeze
|
||||
class << self
|
||||
def bits
|
||||
32
|
||||
|
@ -15,6 +14,7 @@ module OneGadget
|
|||
end
|
||||
end
|
||||
|
||||
REGISTERS = %w(eax ebx ecx edx edi esi ebp esp eip).freeze
|
||||
# Instantiate a {I386} object.
|
||||
def initialize
|
||||
super(REGISTERS)
|
||||
|
|
|
@ -50,9 +50,22 @@ module OneGadget
|
|||
|
||||
private
|
||||
|
||||
def register?(reg)
|
||||
@registers.include?(reg)
|
||||
end
|
||||
|
||||
def inst_mov(tar, src)
|
||||
src = OneGadget::Emulators::Lambda.parse(src, predefined: @registers)
|
||||
@registers[tar] = src
|
||||
if register?(tar)
|
||||
@registers[tar] = src
|
||||
else
|
||||
# Just ignore strange case...
|
||||
return unless tar.include?(self.class.stack_pointer)
|
||||
tar = OneGadget::Emulators::Lambda.parse(tar, predefined: @registers)
|
||||
return if tar.deref_count != 1 # should not happened
|
||||
tar.ref!
|
||||
@stack[tar.evaluate(eval_dict)] = src
|
||||
end
|
||||
end
|
||||
|
||||
def inst_lea(tar, src)
|
||||
|
@ -64,9 +77,7 @@ module OneGadget
|
|||
def inst_push(val)
|
||||
val = OneGadget::Emulators::Lambda.parse(val, predefined: @registers)
|
||||
@registers[self.class.stack_pointer] -= bytes
|
||||
dict = {}
|
||||
dict[self.class.stack_pointer] = 0
|
||||
cur_top = @registers[self.class.stack_pointer].evaluate(dict)
|
||||
cur_top = @registers[self.class.stack_pointer].evaluate(eval_dict)
|
||||
raise ArgumentError, "Corrupted stack pointer: #{cur_top}" unless cur_top.is_a?(Integer)
|
||||
@stack[cur_top] = val
|
||||
end
|
||||
|
@ -84,6 +95,12 @@ module OneGadget
|
|||
def bytes
|
||||
self.class.bits / 8
|
||||
end
|
||||
|
||||
def eval_dict
|
||||
dict = {}
|
||||
dict[self.class.stack_pointer] = 0
|
||||
dict
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,6 +24,7 @@ describe OneGadget::Emulators::I386 do
|
|||
expect(@processor.stack[0].to_s).to eq 'esi-0x55f61'
|
||||
expect(@processor.stack[4].to_s).to eq 'esp+0x34'
|
||||
expect(@processor.stack[8].to_s).to eq '[[esi-0xb8]]'
|
||||
# The defualt value of stack is a lambda
|
||||
expect(@processor.stack[3].to_s).to eq '[esp+0x3]'
|
||||
end
|
||||
|
||||
|
@ -57,5 +58,21 @@ describe OneGadget::Emulators::I386 do
|
|||
expect(@processor.stack[-0x3c].to_s).to eq '1337'
|
||||
expect(@processor.stack[-0x4].to_s).to eq '1'
|
||||
end
|
||||
|
||||
it 'libc-2.19' do
|
||||
gadget = <<-'EOS'
|
||||
64c60: mov DWORD PTR [esp+0x8],eax
|
||||
64c64: lea eax,[ebx-0x4956f]
|
||||
64c6a: mov DWORD PTR [esp+0x4],eax
|
||||
64c6e: lea eax,[ebx-0x49574]
|
||||
64c74: mov DWORD PTR [esp],eax
|
||||
64c77: call b5170 <execl@@GLIBC_2.0>
|
||||
EOS
|
||||
gadget.lines.each { |s| @processor.process(s) }
|
||||
expect(@processor.registers['esp'].to_s).to eq 'esp'
|
||||
expect(@processor.stack[0].to_s).to eq 'ebx-0x49574'
|
||||
expect(@processor.stack[4].to_s).to eq 'ebx-0x4956f'
|
||||
expect(@processor.stack[8].to_s).to eq 'eax'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue