class Metasm::GdbRemoteDebugger
this class implements a high-level API using the gdb-server network debugging protocol
Attributes
check_target_timeout[RW]
gdb[RW]
gdb_bpx[RW]
set to true to use the gdb msg to handle bpx, false to set 0xcc manually ourself
realmode[RW]
reg_val_cache[RW]
Public Class Methods
new(url, cpu='Ia32')
click to toggle source
Calls superclass method
Metasm::Debugger.new
# File metasm/os/gdbremote.rb, line 424 def initialize(url, cpu='Ia32') super() @tid_stuff_list << :reg_val_cache << :regs_dirty @gdb = GdbClient.new(url, cpu) @gdb.logger = self # when checking target, if no message seen since this much seconds, send a 'status' query @check_target_timeout = 1 set_context(28, 28) end
Public Instance Methods
break()
click to toggle source
# File metasm/os/gdbremote.rb, line 557 def break @gdb.break end
check_pid(pid)
click to toggle source
# File metasm/os/gdbremote.rb, line 434 def check_pid(pid) # return nil if pid == nil pid end
check_pre_run(*a)
click to toggle source
Calls superclass method
Metasm::Debugger#check_pre_run
# File metasm/os/gdbremote.rb, line 604 def check_pre_run(*a) if ret = super(*a) sync_regs ret end end
check_tid(tid)
click to toggle source
# File metasm/os/gdbremote.rb, line 438 def check_tid(tid) tid end
detach()
click to toggle source
# File metasm/os/gdbremote.rb, line 567 def detach del_all_breakpoints del_pid end
do_check_target()
click to toggle source
# File metasm/os/gdbremote.rb, line 508 def do_check_target return if @state == :dead # keep-alive on the connexion t = Time.now @last_check_target ||= t if @state == :running and t - @last_check_target > @check_target_timeout @gdb.io.write '$?#' << @gdb.gdb_csum('?') @last_check_target = t end return unless i = @gdb.check_target(0.01) update_state(i) true end
do_continue(*a)
click to toggle source
# File metasm/os/gdbremote.rb, line 545 def do_continue(*a) @state = :running @gdb.continue @last_check_target = Time.now end
do_disable_bp(b)
click to toggle source
# File metasm/os/gdbremote.rb, line 589 def do_disable_bp(b) case b.type when :bpm do_disable_bpm(b) when :bpx if gdb_bpx @gdb.unset_hwbp('s', b.address, 1) else @cpu.dbg_disable_bp(self, b) end when :hwbp @gdb.unset_hwbp(b.internal[:type], b.address, b.internal[:len]) end end
do_enable_bp(b)
click to toggle source
# File metasm/os/gdbremote.rb, line 574 def do_enable_bp(b) case b.type when :bpm do_enable_bpm(b) when :bpx if gdb_bpx @gdb.set_hwbp('s', b.address, 1) else @cpu.dbg_enable_bp(self, b) end when :hwbp @gdb.set_hwbp(b.internal[:type], b.address, b.internal[:len]) end end
do_singlestep(*a)
click to toggle source
# File metasm/os/gdbremote.rb, line 551 def do_singlestep(*a) @state = :running @gdb.singlestep @last_check_target = Time.now end
do_wait_target()
click to toggle source
# File metasm/os/gdbremote.rb, line 524 def do_wait_target return unless i = @gdb.check_target(nil) update_state(i) end
get_reg_value(r)
click to toggle source
# File metasm/os/gdbremote.rb, line 480 def get_reg_value(r) r = r.to_sym return @reg_val_cache[r] || 0 if @state != :stopped sync_regs @reg_val_cache = @gdb.read_regs || {} if @reg_val_cache.empty? if realmode case r when :eip; seg = :cs when :esp; seg = :ss else seg = :ds end # XXX seg override return @reg_val_cache[seg].to_i*16 + @reg_val_cache[r].to_i end @reg_val_cache[r] || 0 end
initialize_cpu()
click to toggle source
# File metasm/os/gdbremote.rb, line 465 def initialize_cpu @cpu = @gdb.cpu @realmode = true if @cpu and @cpu.shortname =~ /^ia32_16/ end
initialize_memory()
click to toggle source
# File metasm/os/gdbremote.rb, line 470 def initialize_memory @memory = GdbRemoteString.new(@gdb) end
initialize_newtid()
click to toggle source
Calls superclass method
Metasm::Debugger#initialize_newtid
# File metasm/os/gdbremote.rb, line 458 def initialize_newtid super() @reg_val_cache = {} @regs_dirty = false end
invalidate()
click to toggle source
Calls superclass method
Metasm::Debugger#invalidate
# File metasm/os/gdbremote.rb, line 474 def invalidate sync_regs @reg_val_cache.clear super() end
kill(sig=nil)
click to toggle source
# File metasm/os/gdbremote.rb, line 561 def kill(sig=nil) # TODO signal nr @state = :dead @gdb.kill end
list_processes()
click to toggle source
# File metasm/os/gdbremote.rb, line 442 def list_processes [@pid].compact end
list_threads()
click to toggle source
# File metasm/os/gdbremote.rb, line 445 def list_threads [@tid].compact end
loadallsyms()
click to toggle source
# File metasm/os/gdbremote.rb, line 611 def loadallsyms puts 'loadallsyms unsupported' end
mappings()
click to toggle source
# File metasm/os/gdbremote.rb, line 449 def mappings [] end
modules()
click to toggle source
# File metasm/os/gdbremote.rb, line 453 def modules [] end
set_reg_value(r, v)
click to toggle source
# File metasm/os/gdbremote.rb, line 496 def set_reg_value(r, v) r = r.to_sym # XXX realmode @reg_val_cache[r] = v @regs_dirty = true end
sync_regs()
click to toggle source
# File metasm/os/gdbremote.rb, line 503 def sync_regs @gdb.send_regs(@reg_val_cache) if @regs_dirty and not @reg_val_cache.empty? @regs_dirty = false end
ui_command_setup(ui)
click to toggle source
# File metasm/os/gdbremote.rb, line 615 def ui_command_setup(ui) ui.new_command('monitor', 'send a remote command to run on the target') { |arg| @gdb.rcmd(arg) } end
update_state(i)
click to toggle source
# File metasm/os/gdbremote.rb, line 529 def update_state(i) @info = (i[:info] if i[:info] !~ /TRAP/) if i[:state] == :stopped and @state != :stopped invalidate @state = i[:state] case @run_method when :singlestep evt_singlestep else evt_bpx # XXX evt_hwbp? end else @state = i[:state] end end