| IDA SDK

Classes | Functions | Macros | Typedefs | Enumerations
frame.hpp File Reference

## Detailed Description

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:

- tinfo_t::get_func_frame(const func_t *pfn) (the preferred way)
- get_func_frame(tinfo_t *out, const func_t *pfn)

## Classes
struct | stkpnt_t
struct | stkpnts_t
struct | regvar_t
| A register variable allows the user to rename a general processor register to a meaningful name. More...
struct | xreflist_entry_t
| An xref to an argument or variable located in a function's stack frame. More...

## Functions
idaman bool ida_export | add_frame (func_t *pfn, sval_t frsize, ushort frregs, asize_t argsize)
| Add function frame. More...
idaman bool ida_export | del_frame (func_t *pfn)
| Delete a function frame. More...
idaman bool ida_export | set_frame_size (func_t *pfn, asize_t frsize, ushort frregs, asize_t argsize)
| Set size of function frame. More...
idaman asize_t ida_export | get_frame_size (const func_t *pfn)
| Get full size of a function frame. More...
idaman int ida_export | get_frame_retsize (const func_t *pfn)
| Get size of function return address. More...
idaman void ida_export | get_frame_part (range_t *range, const func_t *pfn, frame_part_t part)
| Get offsets of the frame part in the frame. More...
ea_t | frame_off_args (const func_t *pfn)
| Get starting address of arguments section.
ea_t | frame_off_retaddr (const func_t *pfn)
| Get starting address of return address section.
ea_t | frame_off_savregs (const func_t *pfn)
| Get starting address of saved registers section.
ea_t | frame_off_lvars (const func_t *pfn)
| Get start address of local variables section.
idaman bool ida_export | get_func_frame (tinfo_t *out, const func_t *pfn)
| Get type of function frame. More...
bool | get_func_frame (tinfo_t *tif, ea_t ea)
sval_t | soff_to_fpoff (func_t *pfn, uval_t soff)
| Convert struct offsets into fp-relative offsets. More...
idaman bool ida_export | update_fpd (func_t *pfn, asize_t fpd)
| Update frame pointer delta. More...
idaman bool ida_export | set_purged (ea_t ea, int nbytes, bool override_old_value)
| Set the number of purged bytes for a function or data item (funcptr). More...
idaman bool ida_export | add_stkvar (const insn_t &insn, const op_t &x, sval_t v, int flags)
| Automatically add stack variable if doesn't exist. More...
idaman bool ida_export | define_stkvar (func_t *pfn, const char *name, sval_t off, const tinfo_t &tif, const struct value_repr_t *repr=nullptr)
| Define/redefine a stack variable. More...
idaman bool ida_export | add_frame_member (const func_t *pfn, const char *name, uval_t offset, const tinfo_t &tif, const struct value_repr_t *repr=nullptr, uint etf_flags=0)
| Add member to the frame type. More...
THREAD_SAFE bool | is_anonymous_member_name (const char *name)
| Is member name prefixed with "anonymous"?
THREAD_SAFE bool | is_dummy_member_name (const char *name)
| Is member name an auto-generated name?
idaman bool ida_export | is_special_frame_member (tid_t tid)
| Is stkvar with TID the return address slot or the saved registers slot ? More...
idaman bool ida_export | set_frame_member_type (const func_t *pfn, uval_t offset, const tinfo_t &tif, const struct value_repr_t *repr=nullptr, uint etf_flags=0)
| Change type of the frame member. More...
idaman bool ida_export | delete_frame_members (const func_t *pfn, uval_t start_offset, uval_t end_offset)
| Delete frame members. More...
idaman ssize_t ida_export | build_stkvar_name (qstring *buf, const func_t *pfn, sval_t v)
| Build automatic stack variable name. More...
idaman ea_t ida_export | calc_stkvar_struc_offset (func_t *pfn, const insn_t &insn, int n)
| Calculate offset of stack variable in the frame structure. More...
idaman sval_t ida_export | calc_frame_offset (func_t *pfn, sval_t off, const insn_t *insn=nullptr, const op_t *op=nullptr)
| Calculate the offset of stack variable in the frame. More...
idaman int ida_export | delete_wrong_frame_info (func_t *pfn, bool idaapi should_reanalyze(const insn_t &insn))
| Find and delete wrong frame info. More...
idaman void ida_export | free_regvar (struct regvar_t *v)
idaman int ida_export | add_regvar (func_t *pfn, ea_t ea1, ea_t ea2, const char *canon, const char *user, const char *cmt)
| Define a register variable. More...
idaman regvar_t *ida_export | find_regvar (func_t *pfn, ea_t ea1, ea_t ea2, const char *canon, const char *user)
| Find a register variable definition (powerful version). More...
regvar_t * | find_regvar (func_t *pfn, ea_t ea, const char *canon)
| Find a register variable definition. More...
bool | has_regvar (func_t *pfn, ea_t ea)
| Is there a register variable definition? More...
idaman int ida_export | rename_regvar (func_t *pfn, regvar_t *v, const char *user)
| Rename a register variable. More...
idaman int ida_export | set_regvar_cmt (func_t *pfn, regvar_t *v, const char *cmt)
| Set comment for a register variable. More...
idaman int ida_export | del_regvar (func_t *pfn, ea_t ea1, ea_t ea2, const char *canon)
| Delete a register variable definition. More...
idaman bool ida_export | add_auto_stkpnt (func_t *pfn, ea_t ea, sval_t delta)
| Add automatic SP register change point. More...
idaman bool ida_export | add_user_stkpnt (ea_t ea, sval_t delta)
| Add user-defined SP register change point. More...
idaman bool ida_export | del_stkpnt (func_t *pfn, ea_t ea)
| Delete SP register change point. More...
idaman sval_t ida_export | get_spd (func_t *pfn, ea_t ea)
| Get difference between the initial and current values of ESP. More...
idaman sval_t ida_export | get_effective_spd (func_t *pfn, ea_t ea)
| Get effective difference between the initial and current values of ESP. More...
idaman sval_t ida_export | get_sp_delta (func_t *pfn, ea_t ea)
| Get modification of SP made at the specified location. More...
idaman bool ida_export | set_auto_spd (func_t *pfn, ea_t ea, sval_t new_spd)
| 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. More...
idaman bool ida_export | recalc_spd (ea_t cur_ea)
| Recalculate SP delta for an instruction that stops execution. More...
idaman bool ida_export | recalc_spd_for_basic_block (func_t *pfn, ea_t cur_ea)
| Recalculate SP delta for the current instruction. More...
idaman void ida_export | build_stkvar_xrefs (xreflist_t *out, func_t *pfn, uval_t start_offset, uval_t end_offset)
| Fill 'out' with a list of all the xrefs made from function 'pfn' to specified range of the pfn's stack frame. More...

## Macros
#define | FRAME_UDM_NAME_R "__return_address"
#define | FRAME_UDM_NAME_S "__saved_registers"
#define | STKVAR_VALID_SIZE 0x0001
| x.dtyp contains correct variable type (for insns like 'lea' this bit must be off). More...
#define | REGVAR_ERROR_OK 0
| all ok
#define | REGVAR_ERROR_ARG (-1)
| function arguments are bad
#define | REGVAR_ERROR_RANGE (-2)
| the definition range is bad
#define | REGVAR_ERROR_NAME (-3)
| the provided name(s) can't be accepted

## Typedefs
typedef qvector< xreflist_entry_t > | xreflist_t
| vector of xrefs to variables in a function's stack frame

## Enumerations
enum | frame_part_t { FPC_ARGS , FPC_RETADDR , FPC_SAVREGS , FPC_LVARS }
| Parts of a frame.

## Function Documentation

## ◆ add_frame()

idaman bool ida_export add_frame | ( | func_t * | pfn,
|  | sval_t | frsize,
|  | ushort | frregs,
|  | asize_t | argsize
| ) |  |

Add function frame.

Parameters

  pfn | pointer to function structure
  frsize | size of function local variables
  frregs | size of saved registers
  argsize | 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.

Return values

  1 | ok
  0 | failed (no function, frame already exists)

## ◆ del_frame()

idaman bool ida_export del_frame | ( | func_t * | pfn | ) |

Delete a function frame.

Parameters

  pfn | pointer to function structure

Returns
  success

## ◆ set_frame_size()

idaman bool ida_export set_frame_size | ( | func_t * | pfn,
|  | asize_t | frsize,
|  | ushort | frregs,
|  | asize_t | argsize
| ) |  |

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()

Parameters

  pfn | pointer to function structure
  frsize | size of function local variables
  frregs | size of saved registers
  argsize | size of function arguments that will be purged from the stack upon return

Returns
  success

## ◆ get_frame_size()

idaman asize_t ida_export get_frame_size | ( | const func_t * | pfn | ) |

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.

Parameters

  pfn | pointer to function structure, may be nullptr

Returns
  size of frame in bytes or zero

## ◆ get_frame_retsize()

idaman int ida_export get_frame_retsize | ( | const func_t * | pfn | ) |

Get size of function return address.

Parameters

  pfn | pointer to function structure, can't be nullptr

## ◆ get_frame_part()

idaman void ida_export get_frame_part | ( | range_t * | range,
|  | const func_t * | pfn,
|  | frame_part_t | part
| ) |  |

Get offsets of the frame part in the frame.

Parameters

  range | pointer to the output buffer with the frame part start/end(exclusive) offsets, can't be nullptr
  pfn | pointer to function structure, can't be nullptr
  part | frame part

## ◆ get_func_frame()

idaman bool ida_export get_func_frame | ( | tinfo_t * | out,
|  | const func_t * | pfn
| ) |  |

Get type of function frame.

Parameters

  [out] | out | type info
  | pfn | pointer to function structure

Returns
  success

## ◆ soff_to_fpoff()

sval_t soff_to_fpoff | ( | func_t * | pfn,
|  | uval_t | soff
| ) |  |
| inline

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).

## ◆ update_fpd()

idaman bool ida_export update_fpd | ( | func_t * | pfn,
|  | asize_t | fpd
| ) |  |

Update frame pointer delta.

Parameters

  pfn | pointer to function structure
  fpd | new fpd value. cannot be bigger than the local variable range size.

Returns
  success

## ◆ set_purged()

idaman bool ida_export set_purged | ( | ea_t | ea,
|  | int | nbytes,
|  | bool | override_old_value
| ) |  |

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.

Parameters

  ea | address of the function of item
  nbytes | number of purged bytes
  override_old_value | may overwrite old information about purged bytes

Returns
  success

## ◆ add_stkvar()

idaman bool ida_export add_stkvar | ( | const insn_t & | insn,
|  | const op_t & | x,
|  | sval_t | v,
|  | int | flags
| ) |  |

Automatically add stack variable if doesn't exist.

Processor modules should use insn_t::create_stkvar().

Parameters

  insn | the instruction
  x | reference to instruction operand
  v | immediate value in the operand (usually x.addr)
  flags | Add stkvar flags

Returns
  success

## ◆ define_stkvar()

idaman bool ida_export define_stkvar | ( | func_t * | pfn,
|  | const char * | name,
|  | sval_t | off,
|  | const tinfo_t & | tif,
|  | const struct value_repr_t * | repr = `nullptr`
| ) |  |

Define/redefine a stack variable.

Parameters

  pfn | pointer to function
  name | variable name, nullptr means autogenerate a name
  off | offset of the stack variable in the frame. negative values denote local variables, positive - function arguments.
  tif | variable type
  repr | variable representation

Returns
  success

## ◆ add_frame_member()

idaman bool ida_export add_frame_member | ( | const func_t * | pfn,
|  | const char * | name,
|  | uval_t | offset,
|  | const tinfo_t & | tif,
|  | const struct value_repr_t * | repr = `nullptr`,
|  | uint | etf_flags = `0`
| ) |  |

Add member to the frame type.

Parameters

  pfn | pointer to function
  name | variable name, nullptr means autogenerate a name
  offset | member offset in the frame structure, in bytes
  tif | variable type
  repr | variable representation
  etf_flags |

See also
  type changing flags

Returns
  success

## ◆ is_special_frame_member()

idaman bool ida_export is_special_frame_member | ( | tid_t | tid | ) |

Is stkvar with TID the return address slot or the saved registers slot ?

Parameters

  tid | frame member type id return address or saved registers member?

## ◆ set_frame_member_type()

idaman bool ida_export set_frame_member_type | ( | const func_t * | pfn,
|  | uval_t | offset,
|  | const tinfo_t & | tif,
|  | const struct value_repr_t * | repr = `nullptr`,
|  | uint | etf_flags = `0`
| ) |  |

Change type of the frame member.

Parameters

  pfn | pointer to function
  offset | member offset in the frame structure, in bytes
  tif | variable type
  repr | variable representation
  etf_flags |

See also
  type changing flags

Returns
  success

## ◆ delete_frame_members()

idaman bool ida_export delete_frame_members | ( | const func_t * | pfn,
|  | uval_t | start_offset,
|  | uval_t | end_offset
| ) |  |

Delete frame members.

Parameters

  pfn | pointer to function
  start_offset | member offset to start deletion from, in bytes
  end_offset | member offset which not included in the deletion, in bytes

Returns
  success

## ◆ build_stkvar_name()

idaman ssize_t ida_export build_stkvar_name | ( | qstring * | buf,
|  | const func_t * | pfn,
|  | sval_t | v
| ) |  |

Build automatic stack variable name.

Parameters

  buf | pointer to buffer
  pfn | pointer to function (can't be nullptr!)
  v | value of variable offset

Returns
  length of stack variable name or -1

## ◆ calc_stkvar_struc_offset()

idaman ea_t ida_export calc_stkvar_struc_offset | ( | func_t * | pfn,
|  | const insn_t & | insn,
|  | int | n
| ) |  |

Calculate offset of stack variable in the frame structure.

Parameters

  pfn | pointer to function (cannot be nullptr)
  insn | the instruction
  n | 0..UA_MAXOP-1 operand number -1 if error, return BADADDR

Returns
  BADADDR if some error (issue a warning if stack frame is bad)

## ◆ calc_frame_offset()

idaman sval_t ida_export calc_frame_offset | ( | func_t * | pfn,
|  | sval_t | off,
|  | const insn_t * | insn = `nullptr`,
|  | const op_t * | op = `nullptr`
| ) |  |

Calculate the offset of stack variable in the frame.

Parameters

  pfn | pointer to function (cannot be nullptr)
  off | the offset relative to stack pointer or frame pointer
  insn | the instruction
  op | the operand

Returns
  the offset in the frame

## ◆ delete_wrong_frame_info()

idaman int ida_export delete_wrong_frame_info | ( | func_t * | pfn,
|  | bool idaapi | should_reanalyzeconst insn_t &insn
| ) |  |

Find and delete wrong frame info.

Namely, we delete:

- unreferenced stack variable definitions
- references to dead stack variables (i.e. operands displayed in red) these operands will be untyped and most likely displayed in hex. We also plan to reanalyze instruction with the stack frame references
  Parameters

    pfn | pointer to the function
    should_reanalyze | callback to determine which instructions to reanalyze

  Returns
    number of deleted definitions

## ◆ add_auto_stkpnt()

idaman bool ida_export add_auto_stkpnt | ( | func_t * | pfn,
|  | ea_t | ea,
|  | sval_t | delta
| ) |  |

Add automatic SP register change point.

Parameters

  pfn | pointer to the function. may be nullptr.
  ea | 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 | difference between old and new values of SP

Returns
  success

## ◆ add_user_stkpnt()

idaman bool ida_export add_user_stkpnt | ( | ea_t | ea,
|  | sval_t | delta
| ) |  |

Add user-defined SP register change point.

Parameters

  ea | linear address where SP changes
  delta | difference between old and new values of SP

Returns
  success

## ◆ del_stkpnt()

idaman bool ida_export del_stkpnt | ( | func_t * | pfn,
|  | ea_t | ea
| ) |  |

Delete SP register change point.

Parameters

  pfn | pointer to the function. may be nullptr.
  ea | linear address

Returns
  success

## ◆ get_spd()

idaman sval_t ida_export get_spd | ( | func_t * | pfn,
|  | ea_t | ea
| ) |  |

Get difference between the initial and current values of ESP.

Parameters

  pfn | pointer to the function. may be nullptr.
  ea | linear address of the instruction

Returns
  0 or the difference, usually a negative number. returns the sp-diff before executing the instruction.

## ◆ get_effective_spd()

idaman sval_t ida_export get_effective_spd | ( | func_t * | pfn,
|  | ea_t | ea
| ) |  |

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.

Parameters

  pfn | pointer to the function. may be nullptr.
  ea | linear address

Returns
  0 or the difference, usually a negative number

## ◆ get_sp_delta()

idaman sval_t ida_export get_sp_delta | ( | func_t * | pfn,
|  | ea_t | ea
| ) |  |

Get modification of SP made at the specified location.

Parameters

  pfn | pointer to the function. may be nullptr.
  ea | linear address

Returns
  0 if the specified location doesn't contain a SP change point. otherwise return delta of SP modification.

## ◆ set_auto_spd()

idaman bool ida_export set_auto_spd | ( | func_t * | pfn,
|  | ea_t | ea,
|  | sval_t | new_spd
| ) |  |

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.

Parameters

  pfn | pointer to the function. may be nullptr.
  ea | linear address of the instruction
  new_spd | new value of the cumulative SP delta

Returns
  success

## ◆ recalc_spd()

idaman bool ida_export recalc_spd | ( | ea_t | cur_ea | ) |

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.

Parameters

  cur_ea | linear address of the current instruction

Return values

  1 | new stkpnt is added
  0 | nothing is changed

## ◆ recalc_spd_for_basic_block()

idaman bool ida_export recalc_spd_for_basic_block | ( | func_t * | pfn,
|  | ea_t | cur_ea
| ) |  |

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.

Parameters

  pfn | pointer to the function
  cur_ea | linear address of the current instruction

Return values

  true | the cumulative SP delta is set
  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.

## ◆ build_stkvar_xrefs()

idaman void ida_export build_stkvar_xrefs | ( | xreflist_t * | out,
|  | func_t * | pfn,
|  | uval_t | start_offset,
|  | uval_t | end_offset
| ) |  |

Fill 'out' with a list of all the xrefs made from function 'pfn' to specified range of the pfn's stack frame.

Parameters

  out | the list of xrefs to fill.
  pfn | the function to scan.
  start_offset | start frame structure offset, in bytes
  end_offset | end frame structure offset, in bytes