x86 emulator

This commit is contained in:
david942j 2017-02-18 22:30:47 +08:00
parent 08bb6a1a51
commit 65abef7782
4 changed files with 45 additions and 5 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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