samples/disassemble-gui.rb in metasm-1.0.1 vs samples/disassemble-gui.rb in metasm-1.0.2
- old
+ new
@@ -38,19 +38,21 @@
opt.on('-P <plugin>', '--plugin <plugin>', 'load a metasm disassembler/debugger plugin') { |h| (opts[:plugin] ||= []) << h }
opt.on('-e <code>', '--eval <code>', 'eval a ruby code') { |h| (opts[:hookstr] ||= []) << h }
opt.on('--map <mapfile>', 'load a map file (addr <-> name association)') { |f| opts[:map] = f }
opt.on('--fast', 'dasm cli args with disassemble_fast_deep') { opts[:fast] = true }
opt.on('--decompile') { opts[:decompile] = true }
- opt.on('--gui <gtk|win32|qt>') { |g| require 'metasm/gui/' + g }
+ opt.on('--gui <gtk|win32|qt>') { |g| ENV['METASM_GUI'] = g }
opt.on('--cpu <cpu>', 'the CPU class to use for a shellcode (Ia32, X64, ...)') { |c| opts[:sc_cpu] = c }
opt.on('--exe <exe_fmt>', 'the executable file format to use (PE, ELF, ...)') { |c| opts[:exe_fmt] = c }
opt.on('--rebase <addr>', 'rebase the loaded file to <addr>') { |a| opts[:rebase] = Integer(a) }
opt.on('-c <header>', '--c-header <header>', 'read C function prototypes (for external library functions)') { |h| opts[:cheader] = h }
opt.on('-a', '--autoload', 'loads all relevant files with same filename (.h, .map..)') { opts[:autoload] = true }
opt.on('-v', '--verbose') { $VERBOSE = true } # default
opt.on('-q', '--no-verbose') { $VERBOSE = false }
opt.on('-d', '--debug') { $DEBUG = $VERBOSE = true }
+ opt.on('-S <file>', '--session <sessionfile>', 'save user actions in this session file') { |a| opts[:session] = a }
+ opt.on('-N', '--new-session', 'start new session, discard old one') { opts[:newsession] = true }
}.parse!(ARGV)
case exename = ARGV.shift
when /^live:(.*)/
t = $1
@@ -64,38 +66,66 @@
dbg = Metasm::GdbRemoteDebugger.new(exename, opts[:sc_cpu])
w = Metasm::Gui::DbgWindow.new(dbg, "remote - metasm debugger")
else
w = Metasm::Gui::DasmWindow.new("#{exename + ' - ' if exename}metasm disassembler")
if exename
+ opts[:sc_cpu] = eval(opts[:sc_cpu]) if opts[:sc_cpu] =~ /[.(\s:]/
+ opts[:exe_fmt] = eval(opts[:exe_fmt]) if opts[:exe_fmt] =~ /[.(\s:]/
exe = w.loadfile(exename, opts[:sc_cpu], opts[:exe_fmt])
exe.disassembler.rebase(opts[:rebase]) if opts[:rebase]
if opts[:autoload]
basename = exename.sub(/\.\w\w?\w?$/, '')
opts[:map] ||= basename + '.map' if File.exist?(basename + '.map')
opts[:cheader] ||= basename + '.h' if File.exist?(basename + '.h')
(opts[:plugin] ||= []) << (basename + '.rb') if File.exist?(basename + '.rb')
+ opts[:session] ||= basename + '.metasm-session'
end
end
end
ep = ARGV.map { |arg| (?0..?9).include?(arg[0]) ? Integer(arg) : arg }
if exe
- dasm = exe.init_disassembler
+ dasm = exe.disassembler
dasm.load_map opts[:map] if opts[:map]
dasm.parse_c_file opts[:cheader] if opts[:cheader]
dasm.backtrace_maxblocks_data = -1 if opts[:nodatatrace]
dasm.debug_backtrace = true if opts[:debugbacktrace]
- dasm.disassemble_fast_deep(*ep) if opts[:fast]
dasm.callback_finished = lambda { w.dasm_widget.focus_addr w.dasm_widget.curaddr, :decompile ; dasm.decompiler.finalize } if opts[:decompile]
+ dasm.disassemble_fast_deep(*ep) if opts[:fast]
elsif dbg
dbg.load_map opts[:map] if opts[:map]
- opts[:plugin].to_a.each { |p| dbg.load_plugin(p) }
+ dbg.disassembler.parse_c_file opts[:cheader] if opts[:cheader]
+ opts[:plugin].to_a.each { |p|
+ begin
+ dbg.load_plugin(p)
+ rescue ::Exception
+ puts "Error with plugin #{p}: #{$!.class} #{$!}"
+ end
+ }
end
if dasm
w.display(dasm, ep)
- opts[:plugin].to_a.each { |p| dasm.load_plugin(p) }
+ opts[:plugin].to_a.each { |p|
+ begin
+ dasm.load_plugin(p)
+ rescue ::Exception
+ puts "Error with plugin #{p}: #{$!.class} #{$!}"
+ end
+ }
+
+ if opts[:session]
+ if File.exist?(opts[:session])
+ if opts[:newsession]
+ File.unlink(opts[:session])
+ else
+ puts "replaying session #{opts[:session]}"
+ w.widget.replay_session(opts[:session])
+ end
+ end
+ w.widget.save_session opts[:session]
+ end
end
opts[:hookstr].to_a.each { |f| eval f }
Metasm::Gui.main