class Metasm::EmuDebugger
this class implements a virtual debugger over an emulated cpu (based on cpu#get_backtrace_binding)
Attributes
callback_emulate_di[RW]
lambda called everytime we emulate a di receives the di as parameter if it returns nil, the di is emulated as usual, if it returns true no further processing is done for this di dont forget to handle reg_pc !
callback_unknown_pc[RW]
lambda called everytime we cannot find an instruction at the current PC return true if the context was fixed
ctx[RW]
Public Class Methods
new(disassembler)
click to toggle source
# File metasm/os/emulator.rb, line 58 def initialize(disassembler) @pid = @tid = 0 attach(disassembler) end
Public Instance Methods
attach(disassembler)
click to toggle source
# File metasm/os/emulator.rb, line 65 def attach(disassembler) @memory = VirtualMemoryDasm.new(disassembler) @cpu = disassembler.cpu @disassembler = disassembler @ctx = {} @state = :stopped @symbols = disassembler.prog_binding.invert @symbols_len = @symbols.keys.inject({}) { |h, s| h.update s => 1 } @modulemap = {} @breakpoint = {} @breakpoint_memory = {} @breakpoint_thread = {} end
detach()
click to toggle source
# File metasm/os/emulator.rb, line 79 def detach end
do_check_target()
click to toggle source
# File metasm/os/emulator.rb, line 113 def do_check_target true end
do_continue()
click to toggle source
# File metasm/os/emulator.rb, line 121 def do_continue while not @breakpoint[pc] and do_singlestep # TODO check bp#enabled end end
do_disable_bp(b)
click to toggle source
# File metasm/os/emulator.rb, line 129 def do_disable_bp(b) end
do_enable_bp(b)
click to toggle source
# File metasm/os/emulator.rb, line 126 def do_enable_bp(b) # no need to actually patch code in memory end
do_singlestep()
click to toggle source
# File metasm/os/emulator.rb, line 132 def do_singlestep di = @disassembler.di_at(pc) if not di @disassembler.disassemble_fast(pc) di = @disassembler.di_at(pc) end if not di if callback_unknown_pc and callback_unknown_pc.call() return true end return end if callback_emulate_di ret = callback_emulate_di.call(di) return true if ret end return if di.opcode.props[:stopexec] and not di.opcode.props[:setip] # 2-pass to respect binding atomicity fbd = @disassembler.get_fwdemu_binding(di, register_pc, self) fbd.map { |k, v| if k.kind_of?(Indirection) k = Indirection.new(resolve(k.pointer), k.len, k.origin) end [k, resolve(v)] }.each { |k, v| case k when Indirection v = v & ((1 << (k.len*8)) - 1) memory_write_int(k.pointer, v, k.len) when Symbol set_reg_value(k, v) when /^dummy_metasm_/ else puts "singlestep: badkey #{k.inspect} = #{v}" end } true end
do_wait_target()
click to toggle source
# File metasm/os/emulator.rb, line 117 def do_wait_target true end
get_reg_value(r)
click to toggle source
# File metasm/os/emulator.rb, line 95 def get_reg_value(r) if r.to_s =~ /flags?_(.+)/i f = $1.downcase.to_sym get_flag_value(f) else @ctx[r] || 0 end end
initialize_cpu()
click to toggle source
# File metasm/os/emulator.rb, line 84 def initialize_cpu end
initialize_disassembler()
click to toggle source
# File metasm/os/emulator.rb, line 82 def initialize_disassembler end
initialize_memory()
click to toggle source
# File metasm/os/emulator.rb, line 86 def initialize_memory end
invalidate()
click to toggle source
# File metasm/os/emulator.rb, line 88 def invalidate end
memory_get_page(addr, len)
click to toggle source
# File metasm/os/emulator.rb, line 91 def memory_get_page(addr, len) @memory[addr, len] end
set_reg_value(r, v)
click to toggle source
# File metasm/os/emulator.rb, line 104 def set_reg_value(r, v) if r.to_s =~ /flags?_(.+)/i f = $1.downcase.to_sym set_flag_value(f, v) else @ctx[r] = v end end
shortname()
click to toggle source
# File metasm/os/emulator.rb, line 63 def shortname; 'emudbg'; end