metasploit-framework/lib/metasm/samples/hotfix_gtk_dbg.rb

60 lines
1.9 KiB
Ruby

# This file is part of Metasm, the Ruby assembly manipulation suite
# Copyright (C) 2006-2009 Yoann GUILLOT
#
# Licence is LGPL, see LICENCE in the top-level directory
#
# this sample script fixes a bug in some GTK libs (eg debian) where at some point
# when you close a window an invalid memory dereference is done, which crashes the
# whole metasm GUI
#
# bug backtrace:
# 0f79e6173h libgobject-2.0.so.0!g_type_check_instance+23
# 0f79e3e38h libgobject-2.0.so.0!g_signal_handlers_disconnect_matched+28
# 0f70004c3h libgtk-x11-2.0.so.0!gtk_accel_label_set_accel_closure+c3
# 0f70006d3h libgtk-x11-2.0.so.0!gtk_accel_label_set_accel_widget+b3
# ...
#
require 'metasm'
include Metasm
if not pr = OS.current.find_process(ARGV.first)
abort "cant find target"
end
dbg = pr.debugger
dbg.continue
puts "monitoring.." if $VERBOSE
dbg.wait_target
while dbg.state == :stopped
puts "target #{dbg.state} #{dbg.info}" if $VERBOSE
if di = dbg.di_at(dbg.pc) and di.to_s =~ /\[(...)\]/ and reg = $1.downcase.to_sym and regval = dbg.get_reg_value(reg) and regval > 0 and regval < 4096
bt = dbg.stacktrace(2)
calladdr = bt[1][0]-5
dbg.disassembler.disassemble_fast(calladdr)
call = dbg.di_at(calladdr)
dbg.disassembler.disassemble_fast(call.instruction.args.first.reduce) rescue nil
if di = dbg.disassembler.decoded[dbg.pc] and from = dbg.disassembler.decoded[di.block.from_normal.first] and from.block.list[-2].to_s =~ /test #{reg}, #{reg}/
puts "fix almost null deref #{di} (#{reg}=#{regval})" if $VERBOSE
dbg.set_reg_value(reg, 0)
dbg.set_reg_value(:eip, from.block.list[-2].address)
else
dbg.kill # dont infinite loop ( TODO just dont handle the exception)
end
elsif dbg.info =~ /SEGV/
puts "unhandled segfault #{di}..." if $VERBOSE
# yep, this actually works
dbg.set_reg_value(:eip, di.next_addr)
end
dbg.continue
puts "target running" if $VERBOSE
dbg.wait_target
end
puts "target terminated" if $VERBOSE