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