class Metasm::DecodedFunction

a factorized subfunction as seen by the disassembler

Attributes

backtrace_binding[RW]

when backtracking an instruction that calls us, use this binding and then the instruction's the binding is lazily filled up for non-external functions, register by register, when a backtraced expression depends on it

backtracked_for[RW]

same as InstructionBlock#backtracked_for includes the expression responsible of the function return (eg [esp] on ia32)

btbind_callback[RW]

a lambda called for dynamic backtrace_binding generation

btfor_callback[RW]

a lambda called for dynamic backtracked_for

decompdata[RW]
finalized[RW]

bool, if false the function is actually being disassembled

localvars[RW]

hash stackoff => varname varname is a single String object shared by all ExpressionStrings (to allow renames)

localvars_xrefs[RW]

hash stack offset => di address

noreturn[RW]

bool, if true the function does not return (eg exit() or ExitProcess())

return_address[RW]

addresses of instruction causing the function to return

Public Class Methods

new() click to toggle source
# File metasm/disassemble.rb, line 272
def initialize
        @backtracked_for = []
        @backtrace_binding = {}
end

Public Instance Methods

get_backtrace_binding(dasm, funcaddr, calladdr, expr, origin, maxdepth) click to toggle source

if btbind_callback is defined, calls it with args [dasm, binding, funcaddr, calladdr, expr, origin, maxdepth] else update lazily the binding from expr.externals, and return backtrace_binding

# File metasm/disassemble.rb, line 248
def get_backtrace_binding(dasm, funcaddr, calladdr, expr, origin, maxdepth)
        if btbind_callback
                @btbind_callback[dasm, @backtrace_binding, funcaddr, calladdr, expr, origin, maxdepth]
        elsif backtrace_binding and dest = @backtrace_binding[:thunk] and target = dasm.function[dest]
                target.get_backtrace_binding(dasm, funcaddr, calladdr, expr, origin, maxdepth)
        else
                unk_regs = expr.externals.grep(Symbol).uniq - @backtrace_binding.keys - [:unknown]
                dasm.cpu.backtrace_update_function_binding(dasm, funcaddr, self, return_address, *unk_regs) if not unk_regs.empty?
                @backtrace_binding
        end
end
get_backtracked_for(dasm, funcaddr, calladdr) click to toggle source

if btfor_callback is defined, calls it with args [dasm, bt_for, funcaddr, calladdr] else return backtracked_for

# File metasm/disassemble.rb, line 262
def get_backtracked_for(dasm, funcaddr, calladdr)
        if btfor_callback
                @btfor_callback[dasm, @backtracked_for, funcaddr, calladdr]
        elsif backtrace_binding and dest = @backtrace_binding[:thunk] and target = dasm.function[dest]
                target.get_backtracked_for(dasm, funcaddr, calladdr)
        else
                @backtracked_for
        end
end
get_localvar_stackoff(off, di=nil, str=nil) click to toggle source
# File metasm/disassemble.rb, line 277
def get_localvar_stackoff(off, di=nil, str=nil)
        if di
                @localvars_xrefs ||= {}
                @localvars_xrefs[off] ||= []
                @localvars_xrefs[off] |= [di.address]
        end
        @localvars ||= {}
        @localvars[off] ||= (str || (off > 0 ? 'arg_%X' % off : 'var_%X' % -off))
end