Module index

Module ida_frame

Routines to manipulate function stack frames, stack variables, register 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:
  • get_struc() (use func_t::frame as structure ID)
  • get_frame(const func_t *pfn)
  • get_frame(ea_t ea)

Global variables

var FPC_ARGS
FPC_ARGS = 0
var FPC_LVARS
FPC_LVARS = 3
var FPC_RETADDR
FPC_RETADDR = 1
var FPC_SAVREGS
FPC_SAVREGS = 2
var REGVAR_ERROR_ARG
function arguments are bad
var REGVAR_ERROR_NAME
the provided name(s) can't be accepted
var REGVAR_ERROR_OK
all ok
var REGVAR_ERROR_RANGE
the definition range is bad
var STKVAR_VALID_SIZE
x.dtyp contains correct variable type (for insns like 'lea' this bit must be off). In general, dr_O references do not allow to determine the variable size

Functions

def add_auto_stkpnt(*args) ‑> 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
def add_frame(*args) ‑> 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)
def add_regvar(*args) ‑> 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
def add_user_stkpnt(*args) ‑> 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
def build_stkvar_name(*args) ‑> 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
def build_stkvar_xrefs(*args) ‑> void
build_stkvar_xrefs(out, pfn, mptr)
Fill 'out' with a list of all the xrefs made from function 'pfn', to the argument or variable 'mptr' in 'pfn's stack frame.
out: (C++: xreflist_t *) the list of xrefs to fill.
pfn: (C++: func_t *) the function to scan.
mptr: (C++: const member_t *) the argument/variable in pfn's stack frame.
def calc_stkvar_struc_offset(*args) ‑> 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 (can't 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)
def define_stkvar(*args) ‑> bool
define_stkvar(pfn, name, off, flags, ti, nbytes) -> 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.
flags: (C++: flags64_t) variable type flags (byte_flag() for a byte variable, for example)
ti: (C++: const opinfo_t *) additional type information (like offsets, structs, etc)
nbytes: (C++: asize_t) number of bytes occupied by the variable
return: success
def del_frame(*args) ‑> bool
del_frame(pfn) -> bool
Delete a function frame.
pfn: (C++: func_t *) pointer to function structure
return: success
def del_regvar(*args) ‑> 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
def del_stkpnt(*args) ‑> 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
def delete_unreferenced_stkvars(*args) ‑> int
delete_unreferenced_stkvars(pfn) -> int
pfn: func_t *
def delete_wrong_stkvar_ops(*args) ‑> int
delete_wrong_stkvar_ops(pfn) -> int
pfn: func_t *
def 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 *
def frame_off_args(*args) ‑> ea_t
frame_off_args(pfn) -> ea_t
Get starting address of arguments section.
pfn: (C++: const func_t *) func_t const *
def frame_off_lvars(*args) ‑> ea_t
frame_off_lvars(pfn) -> ea_t
Get start address of local variables section.
pfn: (C++: const func_t *) func_t const *
def frame_off_retaddr(*args) ‑> ea_t
frame_off_retaddr(pfn) -> ea_t
Get starting address of return address section.
pfn: (C++: const func_t *) func_t const *
def frame_off_savregs(*args) ‑> ea_t
frame_off_savregs(pfn) -> ea_t
Get starting address of saved registers section.
pfn: (C++: const func_t *) func_t const *
def free_regvar(*args) ‑> void
free_regvar(v)
v: regvar_t *
def get_effective_spd(*args) ‑> 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
def get_frame(*args) ‑> struc_t *
get_frame(pfn) -> struc_t *
Get pointer to function frame.
pfn: func_t const *
def get_frame_member_by_id(*args) ‑> member_t *
get_frame_member_by_id(out_mname, out_fptr, mid) -> member_t *
Check if the specified member id points to a frame member.
out_mname: (C++: qstring *)
out_fptr: (C++: struc_t **)
mid: (C++: tid_t)
def get_frame_part(*args) ‑> 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
def get_frame_retsize(*args) ‑> 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
def get_frame_size(*args) ‑> 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
def get_func_by_frame(*args) ‑> ea_t
get_func_by_frame(frame_id) -> ea_t
Get function by its frame id.
warning: this function works only with databases created by IDA > 5.6
frame_id: (C++: tid_t) id of the function frame
return: start address of the function or BADADDR
def get_min_spd_ea(*args) ‑> ea_t
get_min_spd_ea(pfn) -> ea_t
pfn: func_t *
def get_sp_delta(*args) ‑> 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.
def get_spd(*args) ‑> 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.
def get_stkvar(*args) ‑> PyObject *
get_stkvar(insn, op, v) -> (member_t, int) or None
Get pointer to stack variable
insn: an ida_ua.insn_t, or an address (C++: const insn_t &)
op: reference to instruction operand
v: immediate value in the operand (usually op.addr)
return: - None on failure
  • tuple(member_t, actval)
    where actval: actual value used to fetch stack variable
def has_regvar(*args) ‑> 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
def is_funcarg_off(*args) ‑> bool
is_funcarg_off(pfn, frameoff) -> bool
pfn: func_t const *
frameoff: uval_t
def lvar_off(*args) ‑> sval_t
lvar_off(pfn, frameoff) -> sval_t
pfn: func_t const *
frameoff: uval_t
def recalc_spd(*args) ‑> 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
def recalc_spd_for_basic_block(*args) ‑> 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.
def rename_regvar(*args) ‑> 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
def set_auto_spd(*args) ‑> 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
def set_frame_size(*args) ‑> 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 get_struc_size(get_frame(pfn)).
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
def set_purged(*args) ‑> 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
def set_regvar_cmt(*args) ‑> 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
def soff_to_fpoff(*args) ‑> sval_t
soff_to_fpoff(pfn, soff) -> sval_t
Convert struct offsets into fp-relative offsets. This function converts the offsets inside the struc_t object into the frame pointer offsets (for example, EBP-relative).
pfn: (C++: func_t *)
soff: (C++: uval_t)
def update_fpd(*args) ‑> 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

class regvar_t (*args)
Proxy of C++ regvar_t class.
__init__(self) -> regvar_t
__init__(self, r) -> regvar_t
r: regvar_t const &

Ancestors

Instance variables

var canon
canonical register name (case-insensitive)
var cmt
comment to appear near definition
var user
user-defined register name

Methods

def swap(self, *args) ‑> void
swap(self, r)
r: regvar_t &

Inherited members

class stkpnt_t (*args)
Proxy of C++ stkpnt_t class.
__init__(self) -> stkpnt_t

Instance variables

var ea
ea
var spd
spd

Methods

def compare(self, *args) ‑> int
compare(self, r) -> int
r: stkpnt_t const &
class stkpnts_t (*args)
Proxy of C++ stkpnts_t class.
__init__(self) -> stkpnts_t

Methods

def compare(self, *args) ‑> int
compare(self, r) -> int
r: stkpnts_t const &
class xreflist_entry_t (*args)
Proxy of C++ xreflist_entry_t class.
__init__(self) -> xreflist_entry_t

Instance variables

var ea
Location of the insn referencing the stack frame member.
var opnum
Number of the operand of that instruction.
var type
The type of xref (cref_t & dref_t)

Methods

def compare(self, *args) ‑> int
compare(self, r) -> int
r: xreflist_entry_t const &
class 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

def add_unique(self, *args) ‑> bool
add_unique(self, x) -> bool
x: xreflist_entry_t const &
def at(self, *args) ‑> xreflist_entry_t const &
at(self, _idx) -> xreflist_entry_t
_idx: size_t
def back(self)
def begin(self, *args) ‑> qvector< xreflist_entry_t >::const_iterator
begin(self) -> xreflist_entry_t
def capacity(self, *args) ‑> size_t
capacity(self) -> size_t
def clear(self, *args) ‑> void
clear(self)
def empty(self, *args) ‑> bool
empty(self) -> bool
def end(self, *args) ‑> qvector< xreflist_entry_t >::const_iterator
end(self) -> xreflist_entry_t
def 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
def extract(self, *args) ‑> xreflist_entry_t *
extract(self) -> xreflist_entry_t
def find(self, *args) ‑> qvector< xreflist_entry_t >::const_iterator
find(self, x) -> xreflist_entry_t
x: xreflist_entry_t const &
def front(self)
def grow(self, *args) ‑> void
grow(self, x=xreflist_entry_t())
x: xreflist_entry_t const &
def has(self, *args) ‑> bool
has(self, x) -> bool
x: xreflist_entry_t const &
def inject(self, *args) ‑> void
inject(self, s, len)
s: xreflist_entry_t *
len: size_t
def insert(self, *args) ‑> qvector< xreflist_entry_t >::iterator
insert(self, it, x) -> xreflist_entry_t
it: qvector< xreflist_entry_t >::iterator
x: xreflist_entry_t const &
def pop_back(self, *args) ‑> void
pop_back(self)
def push_back(self, *args) ‑> xreflist_entry_t &
push_back(self, x)
x: xreflist_entry_t const &
push_back(self) -> xreflist_entry_t
def qclear(self, *args) ‑> void
qclear(self)
def reserve(self, *args) ‑> void
reserve(self, cnt)
cnt: size_t
def resize(self, *args) ‑> void
resize(self, _newsize, x)
_newsize: size_t
x: xreflist_entry_t const &
resize(self, _newsize)
_newsize: size_t
def size(self, *args) ‑> size_t
size(self) -> size_t
def swap(self, *args) ‑> void
swap(self, r)
r: qvector< xreflist_entry_t > &
def truncate(self, *args) ‑> void
truncate(self)