node/lib/metasm/metasm/disassemble.rb
# creates xrefs, updates addrs_todo, updates instr args
creates xrefs, updates addrs_todo, updates instr args
creates xrefs updates addrs_todo updates instr args
def backtrace_found_result(expr, di, type, origin, len, detached)
		n = normalize(expr)
		fallthrough = true if type == :x and o = di_at(origin) and not o.opcode.props[:stopexec] and n == o.block.list.last.next_addr	
		add_xref(n, Xref.new(type, origin, len)) if origin != :default and origin != Expression::Unknown and not fallthrough
		unk = true if n == Expression::Unknown
		add_xref(n, Xref.new(:addr, di.address)) if di and di.address != origin and not unk
		base = { nil => 'loc', 1 => 'byte', 2 => 'word', 4 => 'dword', 8 => 'qword' }[len] || 'xref'
		base = 'sub' if @function[n]
		n = Expression[auto_label_at(n, base, 'xref') || n] if not fallthrough
		n = Expression[n]
		if di and not unk and expr != n 
			@cpu.replace_instr_arg_immediate(di.instruction, expr, n)
		end
		if @decoded[origin] and not unk
			 @cpu.backtrace_found_result(self, @decoded[origin], expr, type, len)
		end
		if type and @decoded[origin] 
			@decoded[origin].add_comment "#{type}#{len}:#{n}" if not fallthrough
		end
		if di and type == :r and (len == 1 or len == 2) and s = get_section_at(n)
			l = s[0].inv_export[s[0].ptr]
			case len
			when 1; str = s[0].read(32).unpack('C*')
			when 2; str = s[0].read(64).unpack('v*')
			end
			str = str.inject('') { |str_, c|
				case c
				when 0x20..0x7e, ?\n, ?\r, ?\t; str_ << c
				else break str_
				end
			}
			if str.length >= 4
				di.add_comment "#{'L' if len == 2}#{str.inspect}"
				str = 'a_' + str.downcase.delete('^a-z0-9')[0, 12]
				if str.length >= 8 and l[0, 5] == 'byte_'
					rename_label(l, @program.new_label(str))
				end
			end
		end
		if type == :x and origin
			if detached
				o = @decoded[origin] ? origin : di ? di.address : nil	
				origin = nil
				@decoded[o].block.add_to_indirect(normalize(n)) if @decoded[o] and not unk
			else
				@decoded[origin].block.add_to_normal(normalize(n)) if @decoded[origin] and not unk
			end
			@addrs_todo << [n, origin]
		end
	end
def backtrace_found_result ( expr , di , type , origin , len , detached ) n = normalize ( expr ) fallthrough = true if type == :x and o = di_at ( origin ) and not o . opcode . props [ :stopexec ] and n == o . block . list . last . next_addr add_xref ( n , Xref . new ( type , origin , len ) ) if origin != :default and origin != Expression :: Unknown and not fallthrough unk = true if n == Expression :: Unknown add_xref ( n , Xref . new ( :addr , di . address ) ) if di and di . address != origin and not unk base = { nil => 'loc' , 1 => 'byte' , 2 => 'word' , 4 => 'dword' , 8 => 'qword' } [ len ] || 'xref' base = 'sub' if @function [ n ] n = Expression [ auto_label_at ( n , base , 'xref' ) || n ] if not fallthrough n = Expression [ n ] if di and not unk and expr != n @cpu . replace_instr_arg_immediate ( di . instruction , expr , n ) end if @decoded [ origin ] and not unk @cpu . backtrace_found_result ( self , @decoded [ origin ] , expr , type , len ) end if type and @decoded [ origin ] @decoded [ origin ] . add_comment "#{type}#{len}:#{n}" if not fallthrough end if di and type == :r and ( len == 1 or len == 2 ) and s = get_section_at ( n ) l = s [ 0 ] . inv_export [ s [ 0 ] . ptr ] case len when 1 ; str = s [ 0 ] . read ( 32 ) . unpack ( 'C*' ) when 2 ; str = s [ 0 ] . read ( 64 ) . unpack ( 'v*' ) end str = str . inject ( '' ) { | str_ , c | case c when 0x20 .. 0x7e , ?\n , ?\r , ?\t ; str_ << c else break str_ end } if str . length >= 4 di . add_comment "#{'L' if len == 2}#{str.inspect}" str = 'a_' + str . downcase . delete ( '^a-z0-9' ) [ 0 , 12 ] if str . length >= 8 and l [ 0 , 5 ] == 'byte_' rename_label ( l , @program . new_label ( str ) ) end end end if type == :x and origin if detached o = @decoded [ origin ] ? origin : di ? di . address : nil origin = nil @decoded [ o ] . block . add_to_indirect ( normalize ( n ) ) if @decoded [ o ] and not unk else @decoded [ origin ] . block . add_to_normal ( normalize ( n ) ) if @decoded [ origin ] and not unk end @addrs_todo << [ n , origin ] end end
creates xrefs, updates addrs_todo, updates instr args
creates xrefs updates addrs_todo updates instr args
# delay_slot # update instr args # TODO trace expression evolution to allow handling of #  mov eax, 28 ; add eax, 4 ; jmp eax #  => mov eax, (loc_xx-4) # and di.address == origin # add comment # and not @decoded[origin].instruction.args.include? n # check if target is a string # XXX all this should be done in  backtrace() { <here> } # lib function callback have origin == libfuncname, so we must find a block somewhere else
expr
di
type
origin
len
detached