node/lib/metasm/metasm/disassemble.rb
def dump_data(addr, edata, off, &b)
		b ||= lambda { |l| puts l }
		if l = edata.inv_export[off] and label_alias[addr]
			l_list = label_alias[addr].sort
			l = l_list.pop || l
			l_list.each { |ll|
				b["#{ll}:"]
			}
			l = (l + ' ').ljust(16)
		else l = ''
		end
		elemlen = 1	# size of each element we dump (db by default)
		dumplen = -off % 16	# number of octets to dump
		dumplen = 16 if dumplen == 0
		cmt = []
		each_xref(addr) { |x|
			dumplen = elemlen = x.len if x.len == 2 or x.len == 4
			cmt << " #{x.type}#{x.len}:#{Expression[x.origin]}"
		}
		cmt = " ; @#{Expression[addr]}" + cmt.sort[0, 6].join
		if r = edata.reloc[off]
			dumplen = elemlen = r.type.to_s[1..-1].to_i/8
		end
		dataspec = { 1 => 'db ', 2 => 'dw ', 4 => 'dd ', 8 => 'dq ' }[elemlen]
		if not dataspec
			dataspec = 'db '
			elemlen = 1
		end
		l << dataspec

		# dup(?)
		if off >= edata.data.length
			dups = edata.virtsize - off
			@prog_binding.each_value { |a|
				tmp = Expression[a, :-, addr].reduce
				dups = tmp if tmp.kind_of? ::Integer and tmp > 0 and tmp < dups
			}
			@xrefs.each_key { |a|
				tmp = Expression[a, :-, addr].reduce
				dups = tmp if tmp.kind_of? ::Integer and tmp > 0 and tmp < dups
			}
			dups /= elemlen
			dups = 1 if dups < 1
			b[(l + "#{dups} dup(?)").ljust(48) << cmt]
			return off + dups*elemlen
		end

		vals = []
		edata.ptr = off
		dups = dumplen/elemlen
		elemsym = "u#{elemlen*8}".to_sym
		while edata.ptr < edata.data.length
			if vals.length > dups and vals.last != vals.first
				# we have a dup(), unread the last element which is different
				vals.pop
				addr = Expression[addr, :-, elemlen].reduce
				edata.ptr -= elemlen
				break
			end
			break if vals.length == dups and vals.uniq.length > 1
			vals << edata.decode_imm(elemsym, @cpu.endianness)
			addr += elemlen
			if i = (1-elemlen..0).find { |i_|
				t = addr + i_
				@xrefs[t] or @decoded[t] or edata.reloc[edata.ptr+i_] or edata.inv_export[edata.ptr+i_]
			}
				# i < 0
				edata.ptr += i
				addr += i
				break
			end
			break if edata.reloc[edata.ptr-elemlen]
		end

		# line of repeated value => dup()
		if vals.length > 8 and vals.uniq.length == 1
			b[(l << "#{vals.length} dup(#{Expression[vals.first]})").ljust(48) << cmt]
			return edata.ptr
		end

		# recognize strings
		vals = vals.inject([]) { |vals_, value|
			if (elemlen == 1 or elemlen == 2)
				case value
				when 0x20..0x7e, 0x0a, 0x0d
					if vals_.last.kind_of? ::String; vals_.last << value ; vals_
					else vals_ << value.chr
					end
				else vals_ << value
				end
			else vals_ << value
			end
		}

		vals.map! { |value|
			if value.kind_of? ::String
				if value.length > 2 # or value == vals.first or value == vals.last # if there is no xref, don't care
					value.inspect
				else
					value.unpack('C*').map { |c| Expression[c] }
				end
			else
				Expression[value]
			end
		}
		vals.flatten!

		b[(l << vals.join(', ')).ljust(48) << cmt]

		edata.ptr
	end
# dumps data/labels, honours @xrefs.len if exists
# dumps one line only
# stops on end of edata/@decoded/@xref
# returns the next offset to display
# TODO array-style data access
dumps data/labels, honours @xrefs.len if exists
dumps one line only
stops on end of edata/@decoded/@xref
returns the next offset to display
TODO array-style data access
dumps data / labels honours @xrefs . len if exists dumps one line only stops on end of edata / @decoded / @xref returns the next offset to display TODO array - style data access
def dump_data(addr, edata, off, &b)
		b ||= lambda { |l| puts l }
		if l = edata.inv_export[off] and label_alias[addr]
			l_list = label_alias[addr].sort
			l = l_list.pop || l
			l_list.each { |ll|
				b["#{ll}:"]
			}
			l = (l + ' ').ljust(16)
		else l = ''
		end
		elemlen = 1	
		dumplen = -off % 16	
		dumplen = 16 if dumplen == 0
		cmt = []
		each_xref(addr) { |x|
			dumplen = elemlen = x.len if x.len == 2 or x.len == 4
			cmt << " #{x.type}#{x.len}:#{Expression[x.origin]}"
		}
		cmt = " ; @#{Expression[addr]}" + cmt.sort[0, 6].join
		if r = edata.reloc[off]
			dumplen = elemlen = r.type.to_s[1..-1].to_i/8
		end
		dataspec = { 1 => 'db ', 2 => 'dw ', 4 => 'dd ', 8 => 'dq ' }[elemlen]
		if not dataspec
			dataspec = 'db '
			elemlen = 1
		end
		l << dataspec
		if off >= edata.data.length
			dups = edata.virtsize - off
			@prog_binding.each_value { |a|
				tmp = Expression[a, :-, addr].reduce
				dups = tmp if tmp.kind_of? ::Integer and tmp > 0 and tmp < dups
			}
			@xrefs.each_key { |a|
				tmp = Expression[a, :-, addr].reduce
				dups = tmp if tmp.kind_of? ::Integer and tmp > 0 and tmp < dups
			}
			dups /= elemlen
			dups = 1 if dups < 1
			b[(l + "#{dups} dup(?)").ljust(48) << cmt]
			return off + dups*elemlen
		end
		vals = []
		edata.ptr = off
		dups = dumplen/elemlen
		elemsym = "u#{elemlen*8}".to_sym
		while edata.ptr < edata.data.length
			if vals.length > dups and vals.last != vals.first
				vals.pop
				addr = Expression[addr, :-, elemlen].reduce
				edata.ptr -= elemlen
				break
			end
			break if vals.length == dups and vals.uniq.length > 1
			vals << edata.decode_imm(elemsym, @cpu.endianness)
			addr += elemlen
			if i = (1-elemlen..0).find { |i_|
				t = addr + i_
				@xrefs[t] or @decoded[t] or edata.reloc[edata.ptr+i_] or edata.inv_export[edata.ptr+i_]
			}
				edata.ptr += i
				addr += i
				break
			end
			break if edata.reloc[edata.ptr-elemlen]
		end
		if vals.length > 8 and vals.uniq.length == 1
			b[(l << "#{vals.length} dup(#{Expression[vals.first]})").ljust(48) << cmt]
			return edata.ptr
		end
		vals = vals.inject([]) { |vals_, value|
			if (elemlen == 1 or elemlen == 2)
				case value
				when 0x20..0x7e, 0x0a, 0x0d
					if vals_.last.kind_of? ::String; vals_.last << value ; vals_
					else vals_ << value.chr
					end
				else vals_ << value
				end
			else vals_ << value
			end
		}
		vals.map! { |value|
			if value.kind_of? ::String
				if value.length > 2 
					value.inspect
				else
					value.unpack('C*').map { |c| Expression[c] }
				end
			else
				Expression[value]
			end
		}
		vals.flatten!
		b[(l << vals.join(', ')).ljust(48) << cmt]
		edata.ptr
	end
def dump_data ( addr , edata , off , & b ) b ||= lambda { | l | puts l } if l = edata . inv_export [ off ] and label_alias [ addr ] l_list = label_alias [ addr ] . sort l = l_list . pop || l l_list . each { | ll | b [ "#{ll}:" ] } l = ( l + ' ' ) . ljust ( 16 ) else l = '' end elemlen = 1 dumplen = - off % 16 dumplen = 16 if dumplen == 0 cmt = [ ] each_xref ( addr ) { | x | dumplen = elemlen = x . len if x . len == 2 or x . len == 4 cmt << " #{x.type}#{x.len}:#{Expression[x.origin]}" } cmt = " ; @#{Expression[addr]}" + cmt . sort [ 0 , 6 ] . join if r = edata . reloc [ off ] dumplen = elemlen = r . type . to_s [ 1 .. - 1 ] . to_i / 8 end dataspec = { 1 => 'db ' , 2 => 'dw ' , 4 => 'dd ' , 8 => 'dq ' } [ elemlen ] if not dataspec dataspec = 'db ' elemlen = 1 end l << dataspec if off >= edata . data . length dups = edata . virtsize - off @prog_binding . each_value { | a | tmp = Expression [ a , :- , addr ] . reduce dups = tmp if tmp . kind_of? :: Integer and tmp > 0 and tmp < dups } @xrefs . each_key { | a | tmp = Expression [ a , :- , addr ] . reduce dups = tmp if tmp . kind_of? :: Integer and tmp > 0 and tmp < dups } dups /= elemlen dups = 1 if dups < 1 b [ ( l + "#{dups} dup(?)" ) . ljust ( 48 ) << cmt ] return off + dups * elemlen end vals = [ ] edata . ptr = off dups = dumplen / elemlen elemsym = "u#{elemlen*8}" . to_sym while edata . ptr < edata . data . length if vals . length > dups and vals . last != vals . first vals . pop addr = Expression [ addr , :- , elemlen ] . reduce edata . ptr -= elemlen break end break if vals . length == dups and vals . uniq . length > 1 vals << edata . decode_imm ( elemsym , @cpu . endianness ) addr += elemlen if i = ( 1 - elemlen .. 0 ) . find { | i_ | t = addr + i_ @xrefs [ t ] or @decoded [ t ] or edata . reloc [ edata . ptr + i_ ] or edata . inv_export [ edata . ptr + i_ ] } edata . ptr += i addr += i break end break if edata . reloc [ edata . ptr - elemlen ] end if vals . length > 8 and vals . uniq . length == 1 b [ ( l << "#{vals.length} dup(#{Expression[vals.first]})" ) . ljust ( 48 ) << cmt ] return edata . ptr end vals = vals . inject ( [ ] ) { | vals_ , value | if ( elemlen == 1 or elemlen == 2 ) case value when 0x20 .. 0x7e , 0x0a , 0x0d if vals_ . last . kind_of? :: String ; vals_ . last << value ; vals_ else vals_ << value . chr end else vals_ << value end else vals_ << value end } vals . map! { | value | if value . kind_of? :: String if value . length > 2 value . inspect else value . unpack ( 'C*' ) . map { | c | Expression [ c ] } end else Expression [ value ] end } vals . flatten! b [ ( l << vals . join ( ', ' ) ) . ljust ( 48 ) << cmt ] edata . ptr end
dumps data/labels, honours @xrefs.len if exists
dumps one line only
stops on end of edata/@decoded/@xref
returns the next offset to display
TODO array-style data access
dumps data / labels honours @xrefs . len if exists dumps one line only stops on end of edata / @decoded / @xref returns the next offset to display TODO array - style data access
# size of each element we dump (db by default) # number of octets to dump # dup(?) # we have a dup(), unread the last element which is different # i < 0 # line of repeated value => dup() # recognize strings # or value == vals.first or value == vals.last # if there is no xref, don't care
addr
edata
off
b