node/lib/metasm/metasm/disassemble_api.rb
# saves the dasm state to an IO
saves the dasm state to an IO
saves the dasm state to an IO
def save_io(fd)
		fd.puts 'Metasm.dasm'
		if @program.filename and not @program.kind_of?(Shellcode)
			t = @program.filename.to_s
			fd.puts "binarypath #{t.length}", t
		else
			t = "#{@cpu.class.name.sub(/.*::/, '')} #{@cpu.size} #{@cpu.endianness}"
			fd.puts "cpu #{t.length}", t
		end
		@sections.each { |a, e|
			t = "#{Expression[a]} #{e.length}\n" +
				[e.data[0, 2**24].to_str].pack('m*')
			fd.puts "section #{t.length}", t
		}
		t = save_map.join("\n")
		fd.puts "map #{t.length}", t
		t = @decoded.map { |a, d|
			next if not d.kind_of? DecodedInstruction
			"#{Expression[a]},#{d.bin_length} #{d.instruction}#{" ; #{d.comment.join(' ')}" if d.comment}"
		}.compact.sort.join("\n")
		fd.puts "decoded #{t.length}", t
		t = @comment.map { |a, c|
			c.map { |l| l.chomp }.join("\n").split("\n").map { |lc| "#{Expression[a]} #{lc.chomp}" }
		}.join("\n")
		fd.puts "comment #{t.length}", t
		bl = @decoded.values.map { |d|
			d.block if d.kind_of? DecodedInstruction and d.block_head?
		}.compact
		t = bl.map { |b|
			[Expression[b.address],
			 b.list.map { |d| Expression[d.address] }.join(','),
			 b.to_normal.to_a.map { |t_| Expression[t_] }.join(','),
			 b.to_subfuncret.to_a.map { |t_| Expression[t_] }.join(','),
			 b.to_indirect.to_a.map { |t_| Expression[t_] }.join(','),
			 b.from_normal.to_a.map { |t_| Expression[t_] }.join(','),
			 b.from_subfuncret.to_a.map { |t_| Expression[t_] }.join(','),
			 b.from_indirect.to_a.map { |t_| Expression[t_] }.join(','),
			].join(';')
		}.sort.join("\n")
		fd.puts "blocks #{t.length}", t
		t = @function.map { |a, f|
			next if not @decoded[a]
			[a, *f.return_address.to_a].map { |e| Expression[e] }.join(',')
		}.compact.sort.join("\n")
		fd.puts "funcs #{t.length}", t
		t = @xrefs.map { |a, x|
			a = ':default' if a == :default
			a = ':unknown' if a == Expression::Unknown
			case x
			when nil
			when Xref
				[Expression[a], x.type, x.len, (Expression[x.origin] if x.origin)].join(',')
			when Array
				x.map { |x_| [Expression[a], x_.type, x_.len, (Expression[x_.origin] if x_.origin)].join(',') }
			end
		}.compact.join("\n")
		fd.puts "xrefs #{t.length}", t
		t = @c_parser.to_s
		fd.puts "c #{t.length}", t
	end
def save_io ( fd ) fd . puts 'Metasm.dasm' if @program . filename and not @program . kind_of? ( Shellcode ) t = @program . filename . to_s fd . puts "binarypath #{t.length}" , t else t = "#{@cpu.class.name.sub(/.*::/, '')} #{@cpu.size} #{@cpu.endianness}" fd . puts "cpu #{t.length}" , t end @sections . each { | a , e | t = "#{Expression[a]} #{e.length}\n" + [ e . data [ 0 , 2 ** 24 ] . to_str ] . pack ( 'm*' ) fd . puts "section #{t.length}" , t } t = save_map . join ( "\n" ) fd . puts "map #{t.length}" , t t = @decoded . map { | a , d | next if not d . kind_of? DecodedInstruction "#{Expression[a]},#{d.bin_length} #{d.instruction}#{" ; #{d.comment.join(' ')}" if d.comment}" } . compact . sort . join ( "\n" ) fd . puts "decoded #{t.length}" , t t = @comment . map { | a , c | c . map { | l | l . chomp } . join ( "\n" ) . split ( "\n" ) . map { | lc | "#{Expression[a]} #{lc.chomp}" } } . join ( "\n" ) fd . puts "comment #{t.length}" , t bl = @decoded . values . map { | d | d . block if d . kind_of? DecodedInstruction and d . block_head? } . compact t = bl . map { | b | [ Expression [ b . address ] , b . list . map { | d | Expression [ d . address ] } . join ( ',' ) , b . to_normal . to_a . map { | t_ | Expression [ t_ ] } . join ( ',' ) , b . to_subfuncret . to_a . map { | t_ | Expression [ t_ ] } . join ( ',' ) , b . to_indirect . to_a . map { | t_ | Expression [ t_ ] } . join ( ',' ) , b . from_normal . to_a . map { | t_ | Expression [ t_ ] } . join ( ',' ) , b . from_subfuncret . to_a . map { | t_ | Expression [ t_ ] } . join ( ',' ) , b . from_indirect . to_a . map { | t_ | Expression [ t_ ] } . join ( ',' ) , ] . join ( ';' ) } . sort . join ( "\n" ) fd . puts "blocks #{t.length}" , t t = @function . map { | a , f | next if not @decoded [ a ] [ a , * f . return_address . to_a ] . map { | e | Expression [ e ] } . join ( ',' ) } . compact . sort . join ( "\n" ) fd . puts "funcs #{t.length}" , t t = @xrefs . map { | a , x | a = ':default' if a == :default a = ':unknown' if a == Expression :: Unknown case x when nil when Xref [ Expression [ a ] , x . type , x . len , ( Expression [ x . origin ] if x . origin ) ] . join ( ',' ) when Array x . map { | x_ | [ Expression [ a ] , x_ . type , x_ . len , ( Expression [ x_ . origin ] if x_ . origin ) ] . join ( ',' ) } end } . compact . join ( "\n" ) fd . puts "xrefs #{t.length}" , t t = @c_parser . to_s fd . puts "c #{t.length}" , t end
saves the dasm state to an IO
saves the dasm state to an IO
# XXX will be reloaded as a Shellcode with this CPU, but it may be a custom EXE # do not output binarypath, we'll be loaded as a Shellcode, 'section' will suffice # forget edata exports/relocs # dump at most 16Mo per section # TODO binding ? # XXX origin #t = bl.map { |b| b.backtracked_for } #fd.puts "trace #{t.length}" , t
fd