node/lib/metasm/metasm/disassemble_api.rb
def flatten_graph(entry, include_subfunc=true)
		ret = []
		entry = [entry] if not entry.kind_of? Array
		todo = entry.map { |a| normalize(a) }
		done = []
		inv_binding = @prog_binding.invert
		while addr = todo.pop
			next if done.include? addr or not di_at(addr)
			done << addr
			b = @decoded[addr].block

			ret << Label.new(inv_binding[addr]) if inv_binding[addr]
			ret.concat b.list.map { |di| di.instruction }

			b.each_to_otherfunc(self) { |to|
				to = normalize to
				todo.unshift to if include_subfunc
			}
			b.each_to_samefunc(self) { |to|
				to = normalize to
				todo << to
			}

			if not di = b.list[-1-@cpu.delay_slot] or not di.opcode.props[:stopexec] or di.opcode.props[:saveip]
				to = b.list.last.next_addr
				if todo.include? to
					if done.include? to or not di_at(to)
						if not to_l = inv_binding[to]
							to_l = auto_label_at(to, 'loc')
							if done.include? to and idx = ret.index(@decoded[to].block.list.first.instruction)
								ret.insert(idx, Label.new(to_l))
							end
						end
						ret << @cpu.instr_uncond_jump_to(to_l)
					else
						todo << to	# ensure it's next in the listing
					end
				end
			end
		end

		ret
	end
# returns an array of instructions/label that, once parsed and assembled, should
# give something equivalent to the code accessible from the (list of) entrypoints given
# from the @decoded dasm graph
# assume all jump targets have a matching label in @prog_binding
# may add inconditionnal jumps in the listing to preserve the code flow
returns an array of instructions/label that, once parsed and assembled, should
give something equivalent to the code accessible from the (list of) entrypoints given
from the @decoded dasm graph
assume all jump targets have a matching label in @prog_binding
may add inconditionnal jumps in the listing to preserve the code flow
returns an array of instructions / label that once parsed and assembled should give something equivalent to the code accessible from the ( list of ) entrypoints given from the @decoded dasm graph assume all jump targets have a matching label in @prog_binding may add inconditionnal jumps in the listing to preserve the code flow
def flatten_graph(entry, include_subfunc=true)
		ret = []
		entry = [entry] if not entry.kind_of? Array
		todo = entry.map { |a| normalize(a) }
		done = []
		inv_binding = @prog_binding.invert
		while addr = todo.pop
			next if done.include? addr or not di_at(addr)
			done << addr
			b = @decoded[addr].block
			ret << Label.new(inv_binding[addr]) if inv_binding[addr]
			ret.concat b.list.map { |di| di.instruction }
			b.each_to_otherfunc(self) { |to|
				to = normalize to
				todo.unshift to if include_subfunc
			}
			b.each_to_samefunc(self) { |to|
				to = normalize to
				todo << to
			}
			if not di = b.list[-1-@cpu.delay_slot] or not di.opcode.props[:stopexec] or di.opcode.props[:saveip]
				to = b.list.last.next_addr
				if todo.include? to
					if done.include? to or not di_at(to)
						if not to_l = inv_binding[to]
							to_l = auto_label_at(to, 'loc')
							if done.include? to and idx = ret.index(@decoded[to].block.list.first.instruction)
								ret.insert(idx, Label.new(to_l))
							end
						end
						ret << @cpu.instr_uncond_jump_to(to_l)
					else
						todo << to	
					end
				end
			end
		end
		ret
	end
def flatten_graph ( entry , include_subfunc = true ) ret = [ ] entry = [ entry ] if not entry . kind_of? Array todo = entry . map { | a | normalize ( a ) } done = [ ] inv_binding = @prog_binding . invert while addr = todo . pop next if done . include? addr or not di_at ( addr ) done << addr b = @decoded [ addr ] . block ret << Label . new ( inv_binding [ addr ] ) if inv_binding [ addr ] ret . concat b . list . map { | di | di . instruction } b . each_to_otherfunc ( self ) { | to | to = normalize to todo . unshift to if include_subfunc } b . each_to_samefunc ( self ) { | to | to = normalize to todo << to } if not di = b . list [ - 1 - @cpu . delay_slot ] or not di . opcode . props [ :stopexec ] or di . opcode . props [ :saveip ] to = b . list . last . next_addr if todo . include? to if done . include? to or not di_at ( to ) if not to_l = inv_binding [ to ] to_l = auto_label_at ( to , 'loc' ) if done . include? to and idx = ret . index ( @decoded [ to ] . block . list . first . instruction ) ret . insert ( idx , Label . new ( to_l ) ) end end ret << @cpu . instr_uncond_jump_to ( to_l ) else todo << to end end end end ret end
returns an array of instructions/label that, once parsed and assembled, should
give something equivalent to the code accessible from the (list of) entrypoints given
from the @decoded dasm graph
assume all jump targets have a matching label in @prog_binding
may add inconditionnal jumps in the listing to preserve the code flow
returns an array of instructions / label that once parsed and assembled should give something equivalent to the code accessible from the ( list of ) entrypoints given from the @decoded dasm graph assume all jump targets have a matching label in @prog_binding may add inconditionnal jumps in the listing to preserve the code flow
# ensure it's next in the listing
entry
include_subfunc