Syncing with trunk

git-svn-id: file:///home/svn/framework3/trunk@5718 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2008-10-05 15:09:47 +00:00
parent a87cbe1c5e
commit 6ca97f33f4
3 changed files with 24 additions and 13 deletions

View File

@ -13,8 +13,10 @@ module Metasm
class DecodedInstruction class DecodedInstruction
# the instance of InstructionBlock this di is into # the instance of InstructionBlock this di is into
attr_accessor :block attr_accessor :block
# our offset (in bytes) from the start of the block # our offset (in bytes) from the start of the block, used only for hexdump
attr_accessor :block_offset attr_accessor :block_offset
# the address of the instruction's first byte in memory
attr_accessor :address
# the disassembled data # the disassembled data
attr_accessor :instruction, :opcode attr_accessor :instruction, :opcode
# our, length in bytes # our, length in bytes
@ -29,14 +31,14 @@ class DecodedInstruction
@bin_length = 0 @bin_length = 0
end end
def address
@block.address + @block_offset
end
def next_addr def next_addr
address + @bin_length address + @bin_length
end end
def block_head?
self == @block.list.first
end
def show def show
if block if block
bin = @block.edata.data[@block.edata_ptr+@block_offset, @bin_length].unpack('C*').map { |c| '%02x' % c }.join bin = @block.edata.data[@block.edata_ptr+@block_offset, @bin_length].unpack('C*').map { |c| '%02x' % c }.join
@ -151,6 +153,10 @@ class InstructionBlock
@backtracked_for = [] @backtracked_for = []
end end
def bin_length
(di = @list.last) ? di.block_offset + di.bin_length : 0
end
# splits the current block into a new one with all di from address addr to end # splits the current block into a new one with all di from address addr to end
# caller is responsible for rebacktracing new.bt_for to regenerate correct old.btt/new.btt # caller is responsible for rebacktracing new.bt_for to regenerate correct old.btt/new.btt
def split(addr) def split(addr)
@ -174,7 +180,8 @@ class InstructionBlock
# adds a decodedinstruction to the block list, updates di.block and di.block_offset # adds a decodedinstruction to the block list, updates di.block and di.block_offset
def add_di(di) def add_di(di)
di.block = self di.block = self
di.block_offset = (@list.empty? ? 0 : (@list.last.block_offset + @list.last.bin_length)) di.block_offset = bin_length
di.address ||= @address + di.block_offset
@list << di @list << di
end end
@ -855,7 +862,7 @@ puts " finalize subfunc #{Expression[subfunc]}" if debug_backtrace
if di = @decoded[addr] if di = @decoded[addr]
if di.kind_of? DecodedInstruction if di.kind_of? DecodedInstruction
split_block(di.block, di.address) if di.block_offset != 0 # this updates di.block split_block(di.block, di.address) if not di.block_head? # this updates di.block
di.block.add_from(from, from_subfuncret ? :subfuncret : :normal) if from and from != :default di.block.add_from(from, from_subfuncret ? :subfuncret : :normal) if from and from != :default
bf = di.block bf = di.block
end end
@ -1741,7 +1748,7 @@ puts " backtrace_indirection for #{ind.target} failed: #{ev}" if debug_backtra
def dump(dump_data=true, &b) def dump(dump_data=true, &b)
b ||= proc { |l| puts l } b ||= proc { |l| puts l }
@sections.sort.each { |addr, edata| @sections.sort.each { |addr, edata|
blockoffs = @decoded.values.map { |di| Expression[di.block.address, :-, addr].reduce if di.kind_of? DecodedInstruction and di.block_offset == 0 }.grep(::Integer).sort.reject { |o| o < 0 or o >= edata.length } blockoffs = @decoded.values.map { |di| Expression[di.block.address, :-, addr].reduce if di.kind_of? DecodedInstruction and di.block_head? }.grep(::Integer).sort.reject { |o| o < 0 or o >= edata.length }
b[@program.dump_section_header(addr, edata)] b[@program.dump_section_header(addr, edata)]
if not dump_data and edata.length > 16*1024 and blockoffs.empty? if not dump_data and edata.length > 16*1024 and blockoffs.empty?
b["// [#{edata.length} data bytes]"] b["// [#{edata.length} data bytes]"]
@ -1750,15 +1757,14 @@ puts " backtrace_indirection for #{ind.target} failed: #{ev}" if debug_backtra
unk_off = 0 unk_off = 0
# blocks.sort_by { |b| b.addr }.each { |b| # blocks.sort_by { |b| b.addr }.each { |b|
edata.length.times { |i| edata.length.times { |i|
if di = @decoded[addr+i] and di.kind_of? DecodedInstruction and di.block_offset == 0 if di = @decoded[addr+i] and di.kind_of? DecodedInstruction and di.block_head?
if unk_off != di.block.edata_ptr if unk_off != di.block.edata_ptr
b["\n// ------ overlap (#{unk_off-di.block.edata_ptr}) ------"] b["\n// ------ overlap (#{unk_off-di.block.edata_ptr}) ------"]
elsif di.block.from_normal.kind_of? ::Array elsif di.block.from_normal.kind_of? ::Array
b["\n"] b["\n"]
end end
dump_block(di.block, &b) dump_block(di.block, &b)
di = di.block.list.last unk_off = i + di.block.bin_length
unk_off = i + di.block_offset + di.bin_length
elsif i >= unk_off elsif i >= unk_off
next_off = blockoffs.find { |bo| bo > i } || edata.length next_off = blockoffs.find { |bo| bo > i } || edata.length
if dump_data or next_off - i < 16 if dump_data or next_off - i < 16

View File

@ -401,7 +401,7 @@ class GraphViewWidget < Gtk::HBox
else else
@selected_boxes = [] @selected_boxes = []
@caret_box = nil @caret_box = nil
@hl_word = nil #@hl_word = nil
end end
redraw redraw
end end
@ -413,6 +413,7 @@ class GraphViewWidget < Gtk::HBox
def doubleclick(ev) def doubleclick(ev)
if b = find_box_xy(ev.x, ev.y) if b = find_box_xy(ev.x, ev.y)
@mousemove_origin = nil
if @hl_word and @zoom >= 0.90 and @zoom <= 1.1 if @hl_word and @zoom >= 0.90 and @zoom <= 1.1
@parent_widget.focus_addr(@hl_word) @parent_widget.focus_addr(@hl_word)
else else
@ -978,6 +979,10 @@ class GraphViewWidget < Gtk::HBox
@curcontext = Graph.new 'testic' @curcontext = Graph.new 'testic'
@curcontext.root_addrs = dasm_find_roots(addr) @curcontext.root_addrs = dasm_find_roots(addr)
gui_update gui_update
# find an address that can be shown if addr is not
if not @curcontext.box.find { |b| b[:line_address].index(addr) }
addr = @curcontext.box.first[:line_address].values.first
end
return focus_addr(addr, false) return focus_addr(addr, false)
else else
return return

View File

@ -630,7 +630,7 @@ class Ia32
# emulate ret <n> # emulate ret <n>
al = cp.typesize[:ptr] al = cp.typesize[:ptr]
if sym.attributes.to_a.include? 'stdcall' if sym.attributes.to_a.include? 'stdcall'
argsz = sym.type.args.inject(al) { |sum, a| sum += (cp.sizeof(a) + al - 1) / al * al } argsz = sym.type.args.to_a.inject(al) { |sum, a| sum += (cp.sizeof(a) + al - 1) / al * al }
df.backtrace_binding[:esp] = Expression[:esp, :+, argsz] df.backtrace_binding[:esp] = Expression[:esp, :+, argsz]
else else
df.backtrace_binding[:esp] = Expression[:esp, :+, al] df.backtrace_binding[:esp] = Expression[:esp, :+, al]