Module ida_frame

variables and local labels.

The frame is represented as a structure: +------------------------------------------------+ | function arguments | +------------------------------------------------+ | return address (isn't stored in func_t) | +------------------------------------------------+ | saved registers (SI, DI, etc - func_t::frregs) | +------------------------------------------------+ <- typical BP | | | | | | func_t::fpd | | | | | <- real BP | local variables (func_t::frsize) | | | | | +------------------------------------------------+ <- SP

To access the structure of a function frame, use:

  • tinfo_t::get_func_frame(const func_t *pfn) (the preferred way)

  • get_func_frame(tinfo_t *out, const func_t *pfn)

Global Variables

FPC_ARGS

FPC_ARGS = 0

FPC_LVARS

FPC_LVARS = 3

FPC_RETADDR

FPC_RETADDR = 1

FPC_SAVREGS

FPC_SAVREGS = 2

FRAME_UDM_NAME_R

FRAME_UDM_NAME_R = '__return_address'

FRAME_UDM_NAME_S

FRAME_UDM_NAME_S = '__saved_registers'

REGVAR_ERROR_ARG

REGVAR_ERROR_ARG = -1

REGVAR_ERROR_NAME

REGVAR_ERROR_NAME = -3

REGVAR_ERROR_OK

REGVAR_ERROR_OK = 0

REGVAR_ERROR_RANGE

REGVAR_ERROR_RANGE = -2

STKVAR_VALID_SIZE

STKVAR_VALID_SIZE = 1

Functions

add_auto_stkpnt(pfn: func_t *, ea: ea_t, delta: sval_t) ‑> bool

add_auto_stkpnt(pfn, ea, delta) -> bool Add automatic SP register change point.

pfn: (C++: func_t *) pointer to the function. may be nullptr.
ea: (C++: ea_t) linear address where SP changes. usually this is the end of the
          instruction which modifies the stack pointer ( insn_t::ea+
          insn_t::size)
delta: (C++: sval_t) difference between old and new values of SP
return: success

add_frame(pfn: func_t *, frsize: sval_t, frregs: ushort, argsize: asize_t) ‑> bool

add_frame(pfn, frsize, frregs, argsize) -> bool Add function frame.

pfn: (C++: func_t *) pointer to function structure
frsize: (C++: sval_t) size of function local variables
frregs: (C++: ushort) size of saved registers
argsize: (C++: asize_t) size of function arguments range which will be purged upon
               return. this parameter is used for __stdcall and __pascal
               calling conventions. for other calling conventions please pass
               0.
retval 1: ok
retval 0: failed (no function, frame already exists)

add_frame_member(pfn: func_t const *, name: char const *, offset: uval_t, tif: tinfo_t, repr: value_repr_t = None, etf_flags: uint = 0) ‑> bool

add_frame_member(pfn, name, offset, tif, repr=None, etf_flags=0) -> bool Add member to the frame type

pfn: (C++: const func_t *) pointer to function
name: (C++: const char *) variable name, nullptr means autogenerate a name
offset: (C++: uval_t) member offset in the frame structure, in bytes
tif: (C++: const tinfo_t &) variable type
repr: (C++: const struct value_repr_t *) variable representation
etf_flags: (C++: uint)

@see: type changing flags return: success

add_regvar(pfn: func_t *, ea1: ea_t, ea2: ea_t, canon: char const *, user: char const *, cmt: char const *) ‑> int

add_regvar(pfn, ea1, ea2, canon, user, cmt) -> int Define a register variable.

pfn: (C++: func_t *) function in which the definition will be created
ea1: (C++: ea_t) ,ea2: range of addresses within the function where the definition will
               be used
canon: (C++: const char *) name of a general register
canon: (C++: const char *) name of a general register
user: (C++: const char *) user-defined name for the register
cmt: (C++: const char *) comment for the definition
return: Register variable error codes

add_user_stkpnt(ea: ea_t, delta: sval_t) ‑> bool

add_user_stkpnt(ea, delta) -> bool Add user-defined SP register change point.

ea: (C++: ea_t) linear address where SP changes
delta: (C++: sval_t) difference between old and new values of SP
return: success

build_stkvar_name(pfn: func_t const *, v: sval_t) ‑> qstring *

build_stkvar_name(pfn, v) -> str Build automatic stack variable name.

pfn: (C++: const func_t *) pointer to function (can't be nullptr!)
v: (C++: sval_t) value of variable offset
return: length of stack variable name or -1

build_stkvar_xrefs(out: xreflist_t, pfn: func_t *, start_offset: uval_t, end_offset: uval_t) ‑> void

build_stkvar_xrefs(out, pfn, start_offset, end_offset) Fill 'out' with a list of all the xrefs made from function 'pfn' to specified range of the pfn's stack frame.

out: (C++: xreflist_t *) the list of xrefs to fill.
pfn: (C++: func_t *) the function to scan.
start_offset: (C++: uval_t) start frame structure offset, in bytes
end_offset: (C++: uval_t) end frame structure offset, in bytes

calc_frame_offset(pfn: func_t *, off: sval_t, insn: insn_t const * = None, op: op_t const * = None) ‑> sval_t

calc_frame_offset(pfn, off, insn=None, op=None) -> sval_t Calculate the offset of stack variable in the frame.

pfn: (C++: func_t *) pointer to function (cannot be nullptr)
off: (C++: sval_t) the offset relative to stack pointer or frame pointer
insn: (C++: const insn_t *) the instruction
op: (C++: const op_t *) the operand
return: the offset in the frame

calc_stkvar_struc_offset(pfn: func_t *, insn: insn_t const &, n: int) ‑> ea_t

calc_stkvar_struc_offset(pfn, insn, n) -> ea_t Calculate offset of stack variable in the frame structure.

pfn: (C++: func_t *) pointer to function (cannot be nullptr)
insn: (C++: const insn_t &) the instruction
n: (C++: int) 0..UA_MAXOP-1 operand number -1 if error, return BADADDR
return: BADADDR if some error (issue a warning if stack frame is bad)

define_stkvar(pfn: func_t *, name: char const *, off: sval_t, tif: tinfo_t, repr: value_repr_t = None) ‑> bool

define_stkvar(pfn, name, off, tif, repr=None) -> bool Define/redefine a stack variable.

pfn: (C++: func_t *) pointer to function
name: (C++: const char *) variable name, nullptr means autogenerate a name
off: (C++: sval_t) offset of the stack variable in the frame. negative values denote
           local variables, positive - function arguments.
tif: (C++: const tinfo_t &) variable type
repr: (C++: const struct value_repr_t *) variable representation
return: success

del_frame(pfn: func_t *) ‑> bool

del_frame(pfn) -> bool Delete a function frame.

pfn: (C++: func_t *) pointer to function structure
return: success

del_regvar(pfn: func_t *, ea1: ea_t, ea2: ea_t, canon: char const *) ‑> int

del_regvar(pfn, ea1, ea2, canon) -> int Delete a register variable definition.

pfn: (C++: func_t *) function in question
ea1: (C++: ea_t) ,ea2: range of addresses within the function where the definition
               holds
canon: (C++: const char *) name of a general register
canon: (C++: const char *) name of a general register
return: Register variable error codes

del_stkpnt(pfn: func_t *, ea: ea_t) ‑> bool

del_stkpnt(pfn, ea) -> bool Delete SP register change point.

pfn: (C++: func_t *) pointer to the function. may be nullptr.
ea: (C++: ea_t) linear address
return: success

delete_frame_members(pfn: func_t const *, start_offset: uval_t, end_offset: uval_t) ‑> bool

delete_frame_members(pfn, start_offset, end_offset) -> bool Delete frame members

pfn: (C++: const func_t *) pointer to function
start_offset: (C++: uval_t) member offset to start deletion from, in bytes
end_offset: (C++: uval_t) member offset which not included in the deletion, in bytes
return: success

find_regvar(*args) ‑> regvar_t *

find_regvar(pfn, ea1, ea2, canon, user) -> regvar_t Find a register variable definition.

pfn: (C++: func_t *) function in question
ea1: ea_t
canon: (C++: const char *) name of a general register
canon: (C++: const char *) name of a general register
user: char const *

return: nullptr-not found, otherwise ptr to regvar_t

find_regvar(pfn, ea, canon) -> regvar_t

pfn: func_t *
ea: ea_t
canon: char const *

frame_off_args(pfn: func_t const *) ‑> ea_t

frame_off_args(pfn) -> ea_t Get starting address of arguments section.

pfn: (C++: const func_t *) func_t const *

frame_off_lvars(pfn: func_t const *) ‑> ea_t

frame_off_lvars(pfn) -> ea_t Get start address of local variables section.

pfn: (C++: const func_t *) func_t const *

frame_off_retaddr(pfn: func_t const *) ‑> ea_t

frame_off_retaddr(pfn) -> ea_t Get starting address of return address section.

pfn: (C++: const func_t *) func_t const *

frame_off_savregs(pfn: func_t const *) ‑> ea_t

frame_off_savregs(pfn) -> ea_t Get starting address of saved registers section.

pfn: (C++: const func_t *) func_t const *

free_regvar(v: regvar_t) ‑> void

free_regvar(v)

v: regvar_t *

get_effective_spd(pfn: func_t *, ea: ea_t) ‑> sval_t

get_effective_spd(pfn, ea) -> sval_t Get effective difference between the initial and current values of ESP. This function returns the sp-diff used by the instruction. The difference between get_spd() and get_effective_spd() is present only for instructions like "pop [esp+N]": they modify sp and use the modified value.

pfn: (C++: func_t *) pointer to the function. may be nullptr.
ea: (C++: ea_t) linear address
return: 0 or the difference, usually a negative number

get_frame_part(range: range_t, pfn: func_t const *, part: frame_part_t) ‑> void

get_frame_part(range, pfn, part) Get offsets of the frame part in the frame.

range: (C++: range_t *) pointer to the output buffer with the frame part
             start/end(exclusive) offsets, can't be nullptr
pfn: (C++: const func_t *) pointer to function structure, can't be nullptr
part: (C++: frame_part_t) frame part

get_frame_retsize(pfn: func_t const *) ‑> int

get_frame_retsize(pfn) -> int Get size of function return address.

pfn: (C++: const func_t *) pointer to function structure, can't be nullptr

get_frame_size(pfn: func_t const *) ‑> asize_t

get_frame_size(pfn) -> asize_t Get full size of a function frame. This function takes into account size of local variables + size of saved registers + size of return address + number of purged bytes. The purged bytes correspond to the arguments of the functions with __stdcall and __fastcall calling conventions.

pfn: (C++: const func_t *) pointer to function structure, may be nullptr
return: size of frame in bytes or zero

get_func_frame(out: tinfo_t, pfn: func_t const *) ‑> bool

get_func_frame(out, pfn) -> bool

out: tinfo_t *
pfn: func_t const *

get_sp_delta(pfn: func_t *, ea: ea_t) ‑> sval_t

get_sp_delta(pfn, ea) -> sval_t Get modification of SP made at the specified location

pfn: (C++: func_t *) pointer to the function. may be nullptr.
ea: (C++: ea_t) linear address
return: 0 if the specified location doesn't contain a SP change point.
        otherwise return delta of SP modification.

get_spd(pfn: func_t *, ea: ea_t) ‑> sval_t

get_spd(pfn, ea) -> sval_t Get difference between the initial and current values of ESP.

pfn: (C++: func_t *) pointer to the function. may be nullptr.
ea: (C++: ea_t) linear address of the instruction
return: 0 or the difference, usually a negative number. returns the sp-diff
        before executing the instruction.

has_regvar(pfn: func_t *, ea: ea_t) ‑> bool

has_regvar(pfn, ea) -> bool Is there a register variable definition?

pfn: (C++: func_t *) function in question
ea: (C++: ea_t) current address

is_anonymous_member_name(name: char const *) ‑> bool

is_anonymous_member_name(name) -> bool Is member name prefixed with "anonymous"?

name: (C++: const char *) char const *

is_dummy_member_name(name: char const *) ‑> bool

is_dummy_member_name(name) -> bool Is member name an auto-generated name?

name: (C++: const char *) char const *

is_funcarg_off(pfn: func_t const *, frameoff: uval_t) ‑> bool

is_funcarg_off(pfn, frameoff) -> bool

pfn: func_t const *
frameoff: uval_t

is_special_frame_member(tid: tid_t) ‑> bool

is_special_frame_member(tid) -> bool Is stkvar with TID the return address slot or the saved registers slot ?

tid: (C++: tid_t) frame member type id return address or saved registers member?

lvar_off(pfn: func_t const *, frameoff: uval_t) ‑> sval_t

lvar_off(pfn, frameoff) -> sval_t

pfn: func_t const *
frameoff: uval_t

recalc_spd(cur_ea: ea_t) ‑> bool

recalc_spd(cur_ea) -> bool Recalculate SP delta for an instruction that stops execution. The next instruction is not reached from the current instruction. We need to recalculate SP for the next instruction.

This function will create a new automatic SP register change point if necessary. It should be called from the emulator (emu.cpp) when auto_state == AU_USED if the current instruction doesn't pass the execution flow to the next instruction.

cur_ea: (C++: ea_t) linear address of the current instruction
retval 1: new stkpnt is added
retval 0: nothing is changed

recalc_spd_for_basic_block(pfn: func_t *, cur_ea: ea_t) ‑> bool

recalc_spd_for_basic_block(pfn, cur_ea) -> bool Recalculate SP delta for the current instruction. The typical code snippet to calculate SP delta in a proc module is:

if ( may_trace_sp() && pfn != nullptr ) if ( !recalc_spd_for_basic_block(pfn, insn.ea) ) trace_sp(pfn, insn);

where trace_sp() is a typical name for a function that emulates the SP change of an instruction.

pfn: (C++: func_t *) pointer to the function
cur_ea: (C++: ea_t) linear address of the current instruction
retval true: the cumulative SP delta is set
retval false: the instruction at CUR_EA passes flow to the next instruction. SP
              delta must be set as a result of emulating the current
              instruction.

rename_regvar(pfn: func_t *, v: regvar_t, user: char const *) ‑> int

rename_regvar(pfn, v, user) -> int Rename a register variable.

pfn: (C++: func_t *) function in question
v: (C++: regvar_t *) variable to rename
user: (C++: const char *) new user-defined name for the register
return: Register variable error codes

set_auto_spd(pfn: func_t *, ea: ea_t, new_spd: sval_t) ‑> bool

set_auto_spd(pfn, ea, new_spd) -> bool Add such an automatic SP register change point so that at EA the new cumulative SP delta (that is, the difference between the initial and current values of SP) would be equal to NEW_SPD.

pfn: (C++: func_t *) pointer to the function. may be nullptr.
ea: (C++: ea_t) linear address of the instruction
new_spd: (C++: sval_t) new value of the cumulative SP delta
return: success

set_frame_member_type(pfn: func_t const *, offset: uval_t, tif: tinfo_t, repr: value_repr_t = None, etf_flags: uint = 0) ‑> bool

set_frame_member_type(pfn, offset, tif, repr=None, etf_flags=0) -> bool Change type of the frame member

pfn: (C++: const func_t *) pointer to function
offset: (C++: uval_t) member offset in the frame structure, in bytes
tif: (C++: const tinfo_t &) variable type
repr: (C++: const struct value_repr_t *) variable representation
etf_flags: (C++: uint)

@see: type changing flags return: success

set_frame_size(pfn: func_t *, frsize: asize_t, frregs: ushort, argsize: asize_t) ‑> bool

set_frame_size(pfn, frsize, frregs, argsize) -> bool Set size of function frame. Note: The returned size may not include all stack arguments. It does so only for __stdcall and __fastcall calling conventions. To get the entire frame size for all cases use frame.get_func_frame(pfn).get_size()

pfn: (C++: func_t *) pointer to function structure
frsize: (C++: asize_t) size of function local variables
frregs: (C++: ushort) size of saved registers
argsize: (C++: asize_t) size of function arguments that will be purged from the stack
               upon return
return: success

set_purged(ea: ea_t, nbytes: int, override_old_value: bool) ‑> bool

set_purged(ea, nbytes, override_old_value) -> bool Set the number of purged bytes for a function or data item (funcptr). This function will update the database and plan to reanalyze items referencing the specified address. It works only for processors with PR_PURGING bit in 16 and 32 bit modes.

ea: (C++: ea_t) address of the function of item
nbytes: (C++: int) number of purged bytes
override_old_value: (C++: bool) may overwrite old information about purged bytes
return: success

set_regvar_cmt(pfn: func_t *, v: regvar_t, cmt: char const *) ‑> int

set_regvar_cmt(pfn, v, cmt) -> int Set comment for a register variable.

pfn: (C++: func_t *) function in question
v: (C++: regvar_t *) variable to rename
cmt: (C++: const char *) new comment
return: Register variable error codes

soff_to_fpoff(pfn: func_t *, soff: uval_t) ‑> sval_t

soff_to_fpoff(pfn, soff) -> sval_t Convert struct offsets into fp-relative offsets. This function converts the offsets inside the udt_type_data_t object into the frame pointer offsets (for example, EBP-relative).

pfn: (C++: func_t *)
soff: (C++: uval_t)

update_fpd(pfn: func_t *, fpd: asize_t) ‑> bool

update_fpd(pfn, fpd) -> bool Update frame pointer delta.

pfn: (C++: func_t *) pointer to function structure
fpd: (C++: asize_t) new fpd value. cannot be bigger than the local variable range size.
return: success

Classes

regvar_t(*args)

: Proxy of C++ regvar_t class.

__init__(self) -> regvar_t
__init__(self, r) -> regvar_t

 r: regvar_t const &

Ancestors (in MRO)

* ida_range.range_t

Instance variables

  • canon: char * canon


  • cmt: char * cmt


  • user: char * user


Methods

  • swap(self, r: regvar_t) ‑> void swap(self, r)

    r: regvar_t &


stkpnt_t()

: Proxy of C++ stkpnt_t class.

__init__(self) -> stkpnt_t

Instance variables

  • ea: ea_t ea


  • spd: sval_t spd


Methods

  • compare(self, r: stkpnt_t) ‑> int compare(self, r) -> int

    r: stkpnt_t const &


stkpnts_t()

: Proxy of C++ stkpnts_t class.

__init__(self) -> stkpnts_t

Methods

  • compare(self, r: stkpnts_t) ‑> int compare(self, r) -> int

    r: stkpnts_t const &


xreflist_entry_t()

: Proxy of C++ xreflist_entry_t class.

__init__(self) -> xreflist_entry_t

Instance variables

  • ea: ea_t ea


  • opnum: uchar opnum


  • type: uchar type


Methods

  • compare(self, r: xreflist_entry_t) ‑> int compare(self, r) -> int

    r: xreflist_entry_t const &


xreflist_t(*args)

: Proxy of C++ qvector< xreflist_entry_t > class.

__init__(self) -> xreflist_t
__init__(self, x) -> xreflist_t

 x: qvector< xreflist_entry_t > const &

Methods

  • add_unique(self, x: xreflist_entry_t) ‑> bool add_unique(self, x) -> bool

    x: xreflist_entry_t const &


  • at(self, _idx: size_t) ‑> xreflist_entry_t const & at(self, _idx) -> xreflist_entry_t

    _idx: size_t


  • back(self)


  • begin(self, *args) ‑> qvector< xreflist_entry_t >::const_iterator begin(self) -> xreflist_entry_t


  • capacity(self) ‑> size_t capacity(self) -> size_t


  • clear(self) ‑> void clear(self)


  • empty(self) ‑> bool empty(self) -> bool


  • end(self, *args) ‑> qvector< xreflist_entry_t >::const_iterator end(self) -> xreflist_entry_t


  • erase(self, *args) ‑> qvector< xreflist_entry_t >::iterator erase(self, it) -> xreflist_entry_t

    it: qvector< xreflist_entry_t >::iterator

    erase(self, first, last) -> xreflist_entry_t

    first: qvector< xreflist_entry_t >::iterator last: qvector< xreflist_entry_t >::iterator


  • extract(self) ‑> xreflist_entry_t * extract(self) -> xreflist_entry_t


  • find(self, *args) ‑> qvector< xreflist_entry_t >::const_iterator find(self, x) -> xreflist_entry_t

    x: xreflist_entry_t const &


  • front(self)


  • grow(self, *args) ‑> void grow(self, x=xreflist_entry_t())

    x: xreflist_entry_t const &


  • has(self, x: xreflist_entry_t) ‑> bool has(self, x) -> bool

    x: xreflist_entry_t const &


  • inject(self, s: xreflist_entry_t, len: size_t) ‑> void inject(self, s, len)

    s: xreflist_entry_t * len: size_t


  • insert(self, it: xreflist_entry_t, x: xreflist_entry_t) ‑> qvector< xreflist_entry_t >::iterator insert(self, it, x) -> xreflist_entry_t

    it: qvector< xreflist_entry_t >::iterator x: xreflist_entry_t const &


  • pop_back(self) ‑> void pop_back(self)


  • push_back(self, *args) ‑> xreflist_entry_t & push_back(self, x)

    x: xreflist_entry_t const &

    push_back(self) -> xreflist_entry_t


  • qclear(self) ‑> void qclear(self)


  • reserve(self, cnt: size_t) ‑> void reserve(self, cnt)

    cnt: size_t


  • resize(self, *args) ‑> void resize(self, _newsize, x)

    _newsize: size_t x: xreflist_entry_t const &

    resize(self, _newsize)

    _newsize: size_t


  • size(self) ‑> size_t size(self) -> size_t


  • swap(self, r: xreflist_t) ‑> void swap(self, r)

    r: qvector< xreflist_entry_t > &


  • truncate(self) ‑> void truncate(self)


Last updated