node/lib/metasm/metasm/decompile.rb
def listblocks_func(entry)
		@autofuncs ||= []
		blocks = []
		entry = dasm.normalize entry
		todo = [entry]
		while a = todo.pop
			next if blocks.find { |aa, at| aa == a }
			next if not di = @dasm.di_at(a)
			blocks << [a, []]
			di.block.each_to { |ta, type|
				next if type == :indirect
				ta = dasm.normalize ta
				if type != :subfuncret and not @dasm.function[ta] and
						(not @dasm.function[entry] or @autofuncs.include? entry) and
						di.block.list.last.opcode.props[:saveip]
					# possible noreturn function
					# XXX call $+5; pop eax
					@autofuncs << ta
					@dasm.function[ta] = DecodedFunction.new
					puts "autofunc #{Expression[ta]}" if $VERBOSE
				end

				if @dasm.function[ta] and type != :subfuncret
					f = dasm.auto_label_at(ta, 'func')
					ta = dasm.normalize($1) if f =~ /^thunk_(.*)/
					ret = decompile_func_rec(ta) if (ta != entry or di.block.to_subfuncret)
					throw :restart, :restart if ret == :restart
				else
					@dasm.auto_label_at(ta, 'label') if blocks.find { |aa, at| aa == ta }
					blocks.last[1] |= [ta]
					todo << ta
				end
			}
		end
		blocks
	end
# return an array of [address of block start, list of block to]]
# decompile subfunctions
return an array of [address of block start, list of block to]]
decompile subfunctions
return an array of [ address of block start list of block to ]] decompile subfunctions
def listblocks_func(entry)
		@autofuncs ||= []
		blocks = []
		entry = dasm.normalize entry
		todo = [entry]
		while a = todo.pop
			next if blocks.find { |aa, at| aa == a }
			next if not di = @dasm.di_at(a)
			blocks << [a, []]
			di.block.each_to { |ta, type|
				next if type == :indirect
				ta = dasm.normalize ta
				if type != :subfuncret and not @dasm.function[ta] and
						(not @dasm.function[entry] or @autofuncs.include? entry) and
						di.block.list.last.opcode.props[:saveip]
					@autofuncs << ta
					@dasm.function[ta] = DecodedFunction.new
					puts "autofunc #{Expression[ta]}" if $VERBOSE
				end
				if @dasm.function[ta] and type != :subfuncret
					f = dasm.auto_label_at(ta, 'func')
					ta = dasm.normalize($1) if f =~ /^thunk_(.*)/
					ret = decompile_func_rec(ta) if (ta != entry or di.block.to_subfuncret)
					throw :restart, :restart if ret == :restart
				else
					@dasm.auto_label_at(ta, 'label') if blocks.find { |aa, at| aa == ta }
					blocks.last[1] |= [ta]
					todo << ta
				end
			}
		end
		blocks
	end
def listblocks_func ( entry ) @autofuncs ||= [ ] blocks = [ ] entry = dasm . normalize entry todo = [ entry ] while a = todo . pop next if blocks . find { | aa , at | aa == a } next if not di = @dasm . di_at ( a ) blocks << [ a , [ ] ] di . block . each_to { | ta , type | next if type == :indirect ta = dasm . normalize ta if type != :subfuncret and not @dasm . function [ ta ] and ( not @dasm . function [ entry ] or @autofuncs . include? entry ) and di . block . list . last . opcode . props [ :saveip ] @autofuncs << ta @dasm . function [ ta ] = DecodedFunction . new puts "autofunc #{Expression[ta]}" if $VERBOSE end if @dasm . function [ ta ] and type != :subfuncret f = dasm . auto_label_at ( ta , 'func' ) ta = dasm . normalize ( $1 ) if f =~ / ^thunk_(.*) / ret = decompile_func_rec ( ta ) if ( ta != entry or di . block . to_subfuncret ) throw :restart , :restart if ret == :restart else @dasm . auto_label_at ( ta , 'label' ) if blocks . find { | aa , at | aa == ta } blocks . last [ 1 ] |= [ ta ] todo << ta end } end blocks end
return an array of [address of block start, list of block to]]
decompile subfunctions
return an array of [ address of block start list of block to ]] decompile subfunctions
# possible noreturn function # XXX call $+5; pop eax
entry