node/lib/metasm/metasm/cpu/x86_64/decode.rb
def decode_c_function_prototype(cp, sym, orig=nil)
		sym = cp.toplevel.symbol[sym] if sym.kind_of?(::String)
		df = DecodedFunction.new
		orig ||= Expression[sym.name]

		new_bt = lambda { |expr, rlen|
			df.backtracked_for << BacktraceTrace.new(expr, orig, expr, rlen ? :r : :x, rlen)
		}

		# return instr emulation
		if sym.has_attribute 'noreturn' or sym.has_attribute '__noreturn__'
			df.noreturn = true
		else
			new_bt[Indirection[:rsp, @size/8, orig], nil]
		end

		# register dirty (MS standard ABI)
		[:rax, :rcx, :rdx, :r8, :r9, :r10, :r11].each { |r|
			df.backtrace_binding.update r => Expression::Unknown
		}

		if cp.lexer.definition['__MS_X86_64_ABI__']
			reg_args = [:rcx, :rdx, :r8, :r9]
		else
			reg_args = [:rdi, :rsi, :rdx, :rcx, :r8, :r9]
		end

		al = cp.typesize[:ptr]
		df.backtrace_binding[:rsp] = Expression[:rsp, :+, al]

		# scan args for function pointers
		# TODO walk structs/unions..
		stackoff = al
		sym.type.args.to_a.zip(reg_args).each { |a, r|
			if not r
				r = Indirection[[:rsp, :+, stackoff], al, orig]
				stackoff += (cp.sizeof(a) + al - 1) / al * al
			end
			if a.type.untypedef.kind_of? C::Pointer
				pt = a.type.untypedef.type.untypedef
				if pt.kind_of? C::Function
					new_bt[r, nil]
					df.backtracked_for.last.detached = true
				elsif pt.kind_of? C::Struct
					new_bt[r, al]
				else
					new_bt[r, cp.sizeof(nil, pt)]
				end
			end
		}

		df
	end
# returns a DecodedFunction from a parsed C function prototype
returns a DecodedFunction from a parsed C function prototype
returns a DecodedFunction from a parsed C function prototype
def decode_c_function_prototype(cp, sym, orig=nil)
		sym = cp.toplevel.symbol[sym] if sym.kind_of?(::String)
		df = DecodedFunction.new
		orig ||= Expression[sym.name]
		new_bt = lambda { |expr, rlen|
			df.backtracked_for << BacktraceTrace.new(expr, orig, expr, rlen ? :r : :x, rlen)
		}
		if sym.has_attribute 'noreturn' or sym.has_attribute '__noreturn__'
			df.noreturn = true
		else
			new_bt[Indirection[:rsp, @size/8, orig], nil]
		end
		[:rax, :rcx, :rdx, :r8, :r9, :r10, :r11].each { |r|
			df.backtrace_binding.update r => Expression::Unknown
		}
		if cp.lexer.definition['__MS_X86_64_ABI__']
			reg_args = [:rcx, :rdx, :r8, :r9]
		else
			reg_args = [:rdi, :rsi, :rdx, :rcx, :r8, :r9]
		end
		al = cp.typesize[:ptr]
		df.backtrace_binding[:rsp] = Expression[:rsp, :+, al]
		stackoff = al
		sym.type.args.to_a.zip(reg_args).each { |a, r|
			if not r
				r = Indirection[[:rsp, :+, stackoff], al, orig]
				stackoff += (cp.sizeof(a) + al - 1) / al * al
			end
			if a.type.untypedef.kind_of? C::Pointer
				pt = a.type.untypedef.type.untypedef
				if pt.kind_of? C::Function
					new_bt[r, nil]
					df.backtracked_for.last.detached = true
				elsif pt.kind_of? C::Struct
					new_bt[r, al]
				else
					new_bt[r, cp.sizeof(nil, pt)]
				end
			end
		}
		df
	end
def decode_c_function_prototype ( cp , sym , orig = nil ) sym = cp . toplevel . symbol [ sym ] if sym . kind_of? ( :: String ) df = DecodedFunction . new orig ||= Expression [ sym . name ] new_bt = lambda { | expr , rlen | df . backtracked_for << BacktraceTrace . new ( expr , orig , expr , rlen ? :r : :x , rlen ) } if sym . has_attribute 'noreturn' or sym . has_attribute '__noreturn__' df . noreturn = true else new_bt [ Indirection [ :rsp , @size / 8 , orig ] , nil ] end [ :rax , :rcx , :rdx , :r8 , :r9 , :r10 , :r11 ] . each { | r | df . backtrace_binding . update r => Expression :: Unknown } if cp . lexer . definition [ '__MS_X86_64_ABI__' ] reg_args = [ :rcx , :rdx , :r8 , :r9 ] else reg_args = [ :rdi , :rsi , :rdx , :rcx , :r8 , :r9 ] end al = cp . typesize [ :ptr ] df . backtrace_binding [ :rsp ] = Expression [ :rsp , :+ , al ] stackoff = al sym . type . args . to_a . zip ( reg_args ) . each { | a , r | if not r r = Indirection [ [ :rsp , :+ , stackoff ] , al , orig ] stackoff += ( cp . sizeof ( a ) + al - 1 ) / al * al end if a . type . untypedef . kind_of? C :: Pointer pt = a . type . untypedef . type . untypedef if pt . kind_of? C :: Function new_bt [ r , nil ] df . backtracked_for . last . detached = true elsif pt . kind_of? C :: Struct new_bt [ r , al ] else new_bt [ r , cp . sizeof ( nil , pt ) ] end end } df end
returns a DecodedFunction from a parsed C function prototype
returns a DecodedFunction from a parsed C function prototype
# return instr emulation # register dirty (MS standard ABI) # scan args for function pointers # TODO walk structs/unions..
cp
sym
orig