Module index

# Module `ida_expr`

Functions that deal with C-like expressions and built-in IDC language.

Functions marked THREAD_SAFE may be called from any thread. No simultaneous calls should be made for the same variable. We protect only global structures, individual variables must be protected manually.

## Global variables

`var CPL_DEL_MACROS`

  delete macros at the end of compilation

`var CPL_ONLY_SAFE`

  allow calls of only thread-safe functions

`var CPL_USE_LABELS`

  allow program labels in the script

`var EXTFUN_BASE`

  requires open database.

`var EXTFUN_NORET`

  does not return. the interpreter may clean up its state before calling it.

`var EXTFUN_SAFE`

  thread safe function. may be called from any thread.

`var IDC_LANG_EXT`

  IDC script extension.

`var VARSLICE_SINGLE`

  return single index (i2 is ignored)

`var VREF_COPY`

  copy the result to the input var (v)

`var VREF_LOOP`

  dereference until we get a non VT_REF

`var VREF_ONCE`

  dereference only once, do not loop

`var VT_FLOAT`

  Floating point (see idc_value_t::e)

`var VT_FUNC`

  Function (see idc_value_t::funcidx)

`var VT_INT64`

  i64

`var VT_LONG`

  Integer (see idc_value_t::num)

`var VT_OBJ`

  Object (see idc_value_t::obj)

`var VT_PVOID`

  void *

`var VT_REF`

  Reference.

`var VT_STR`

  String (see qstr() and similar functions)

`var VT_WILD`

  Function with arbitrary number of arguments. The actual number of arguments will be passed in idc_value_t::num. This value should not be used for idc_value_t.

`var eExecThrow`

  See return value of idc_func_t.

## Functions

`def add_idc_class(name: char const *, super: idc_class_t const * = None)`

  add_idc_class(name, super=None) -> idc_class_t Create a new IDC class.

  @param name: (C++: const char ) name of the new class @param super: (C++: const idc_class_t ) the base class for the new class. if the new class is not based on any other class, pass nullptr @return: pointer to the created class. If such a class already exists, a pointer to it will be returned. Pointers to other existing classes may be invalidated by this call.

`def add_idc_func(name, fp, args, defvals=(), flags=0)`

  Extends the IDC language by exposing a new IDC function that is backed up by a Python function

  Add an IDC function. This function does not modify the predefined kernel functions. Example: static error_t idaapi myfunc5(idc_value_t argv, idc_value_t res) { msg("myfunc is called with arg0=%a and arg1=%s\n", argv[0].num, argv[1].str); res->num = 5; // let's return 5 return eOk; } static const char myfunc5_args[] = { VT_LONG, VT_STR, 0 }; static const ext_idcfunc_t myfunc_desc = { "MyFunc5", myfunc5, myfunc5_args, nullptr, 0, EXTFUN_BASE }; // after this: add_idc_func(myfunc_desc); // there is a new IDC function which can be called like this: MyFunc5(0x123, "test");

  @note: If the function already exists, it will be replaced by the new function @return: success

`def add_idc_gvar(name: char const *)`

  add_idc_gvar(name) -> idc_value_t Add global IDC variable.

  @param name: (C++: const char *) name of the global variable @return: pointer to the created variable or existing variable. NB: the returned pointer is valid until a new global var is added.

`def compile_idc_file(nonnul_line: char const *)`

  compile_idc_file(nonnul_line) -> str

  @param nonnul_line: char const *

`def compile_idc_snippet(func: char const *, text: char const *, resolver: idc_resolver_t * = None, only_safe_funcs: bool = False)`

  compile_idc_snippet(func, text, resolver=None, only_safe_funcs=False) -> bool Compile text with IDC statements.

  @param func: (C++: const char ) name of the function to create out of the snippet @param text: (C++: const char ) text to compile @param resolver: (C++: idc_resolver_t *) callback object to get values of undefined variables This object will be called if IDC function contains references to undefined variables. May be nullptr. @param only_safe_funcs: (C++: bool) if true, any calls to functions without EXTFUN_SAFE flag will lead to a compilation error. @retval true: ok @retval false: error, see errbuf

`def compile_idc_text(nonnul_line: char const *)`

  compile_idc_text(nonnul_line) -> str

  @param nonnul_line: char const *

`def copy_idcv(dst: idc_value_t, src: idc_value_t)`

  copy_idcv(dst, src) -> error_t Copy 'src' to 'dst'. For idc objects only a reference is copied.

  @param dst: (C++: idc_value_t *) @param src: (C++: const idc_value_t &) idc_value_t const &

`def create_idcv_ref(ref: idc_value_t, v: idc_value_t) ‑> bool`

  create_idcv_ref(ref, v) -> bool Create a variable reference. Currently only references to global variables can be created.

  @param ref: (C++: idc_value_t ) ptr to the result @param v: (C++: const idc_value_t ) variable to reference @return: success

`def deep_copy_idcv(dst: idc_value_t, src: idc_value_t)`

  deep_copy_idcv(dst, src) -> error_t Deep copy an IDC object. This function performs deep copy of idc objects. If 'src' is not an object, copy_idcv() will be called

  @param dst: (C++: idc_value_t *) @param src: (C++: const idc_value_t &) idc_value_t const &

`def del_idc_func(name)`

  Unregisters the specified IDC function

  Delete an IDC function

`def del_idcv_attr(obj: idc_value_t, attr: char const *)`

  del_idcv_attr(obj, attr) -> error_t Delete an object attribute.

  @param obj: (C++: idc_value_t ) variable that holds an object reference @param attr: (C++: const char ) attribute name @return: error code, eOk on success

`def deref_idcv(v: idc_value_t, vref_flags: int)`

  deref_idcv(v, vref_flags) -> idc_value_t Dereference a VT_REF variable.

  @param v: (C++: idc_value_t *) variable to dereference @param vref_flags: (C++: int) Dereference IDC variable flags @return: pointer to the dereference result or nullptr. If returns nullptr, qerrno is set to eExecBadRef "Illegal variable reference"

`def eval_expr(rv: idc_value_t, where: ea_t, line: char const *)`

  eval_expr(rv, where, line) -> str Compile and calculate an expression.

  @param rv: (C++: idc_value_t ) pointer to the result @param where: (C++: ea_t) the current linear address in the addressing space of the program being disassembled. If will be used to resolve names of local variables etc. if not applicable, then should be BADADDR. @param line: (C++: const char ) the expression to evaluate @retval true: ok @retval false: error, see errbuf

`def eval_idc_expr(rv: idc_value_t, where: ea_t, line: char const *)`

  eval_idc_expr(rv, where, line) -> str Same as eval_expr(), but will always use the IDC interpreter regardless of the currently installed extlang.

  @param rv: (C++: idc_value_t *) @param where: (C++: ea_t) @param line: char const *

`def exec_idc_script(result: idc_value_t, path: char const *, func: char const *, args: idc_value_t, argsnum: size_t)`

  exec_idc_script(result, path, func, args, argsnum) -> str Compile and execute IDC function(s) from file.

  @param result: (C++: idc_value_t ) ptr to idc_value_t to hold result of the function. If execution fails, this variable will contain the exception information. You may pass nullptr if you are not interested in the returned value. @param path: (C++: const char ) text file containing text of IDC functions @param func: (C++: const char *) function name to execute @param args: (C++: const idc_value_t) array of parameters @param argsnum: (C++: size_t) number of parameters to pass to 'fname' This number should be equal to number of parameters the function expects. @retval true: ok @retval false: error, see errbuf

`def exec_system_script(file: char const *, complain_if_no_file: bool = True)`

  exec_system_script(file, complain_if_no_file=True) -> bool Compile and execute "main" function from system file.

  @param file: (C++: const char *) file name with IDC function(s). The file will be searched using get_idc_filename(). @param complain_if_no_file: (C++: bool) * 1: display warning if the file is not found * 0: don't complain if file doesn't exist @retval 1: ok, file is compiled and executed @retval 0: failure, compilation or execution error, warning is displayed

`def find_idc_class(name: char const *)`

  find_idc_class(name) -> idc_class_t * Find an existing IDC class by its name.

  @param name: (C++: const char *) name of the class @return: pointer to the class or nullptr. The returned pointer is valid until a new call to add_idc_class()

`def find_idc_func(prefix: char const *, n: int = 0)`

  find_idc_func(prefix, n=0) -> bool

  @param prefix: char const * @param n: int

`def find_idc_gvar(name: char const *)`

  find_idc_gvar(name) -> idc_value_t Find an existing global IDC variable by its name.

  @param name: (C++: const char *) name of the global variable @return: pointer to the variable or nullptr. NB: the returned pointer is valid until a new global var is added. FIXME: it is difficult to use this function in a thread safe manner

`def first_idcv_attr(obj: idc_value_t)`

  first_idcv_attr(obj) -> char const *

  @param obj: idc_value_t const *

`def free_idcv(v: idc_value_t)`

  free_idcv(v) Free storage used by VT_STR/VT_OBJ IDC variables. After this call the variable has a numeric value 0

  @param v: (C++: idc_value_t *)

`def get_idc_filename(file: char const *)`

  get_idc_filename(file) -> str Get full name of IDC file name. Search for file in list of include directories, IDCPATH directory and system directories.

  @param file: (C++: const char *) file name without full path @return: nullptr is file not found. otherwise returns pointer to buf

`def get_idcv_attr(res: idc_value_t, obj: idc_value_t, attr: char const *, may_use_getattr: bool = False)`

  get_idcv_attr(res, obj, attr, may_use_getattr=False) -> error_t Get an object attribute.

  @param res: (C++: idc_value_t ) buffer for the attribute value @param obj: (C++: const idc_value_t ) variable that holds an object reference. if obj is nullptr it searches global variables, then user functions @param attr: (C++: const char *) attribute name @param may_use_getattr: (C++: bool) may call getattr functions to calculate the attribute if it does not exist @return: error code, eOk on success

`def get_idcv_class_name(obj: idc_value_t)`

  get_idcv_class_name(obj) -> str Retrieves the IDC object class name.

  @param obj: (C++: const idc_value_t *) class instance variable @return: error code, eOk on success

`def get_idcv_slice(res: idc_value_t, v: idc_value_t, i1: uval_t, i2: uval_t, flags: int = 0)`

  get_idcv_slice(res, v, i1, i2, flags=0) -> error_t Get slice.

  @param res: (C++: idc_value_t ) output variable that will contain the slice @param v: (C++: const idc_value_t ) input variable (string or object) @param i1: (C++: uval_t) slice start index @param i2: (C++: uval_t) slice end index (excluded) @param flags: (C++: int) IDC variable slice flags or 0 @return: eOk if success

`def idcv_float(v: idc_value_t)`

  idcv_float(v) -> error_t Convert IDC variable to a floating point.

  @param v: (C++: idc_value_t *)

`def idcv_int64(v: idc_value_t)`

  idcv_int64(v) -> error_t Convert IDC variable to a 64bit number.

  @param v: (C++: idc_value_t *) @return: v = 0 if impossible to convert to int64

`def idcv_long(v: idc_value_t)`

  idcv_long(v) -> error_t Convert IDC variable to a long (32/64bit) number.

  @param v: (C++: idc_value_t *) @return: v = 0 if impossible to convert to long

`def idcv_num(v: idc_value_t)`

  idcv_num(v) -> error_t Convert IDC variable to a long number.

  @param v: (C++: idc_value_t *) @return: * v = 0 if IDC variable = "false" string * v = 1 if IDC variable = "true" string * v = number if IDC variable is number or string containing a number * eTypeConflict if IDC variable = empty string

`def idcv_object(v: idc_value_t, icls: idc_class_t const * = None)`

  idcv_object(v, icls=None) -> error_t Create an IDC object. The original value of 'v' is discarded (freed).

  @param v: (C++: idc_value_t ) variable to hold the object. any previous value will be cleaned @param icls: (C++: const idc_class_t ) ptr to the desired class. nullptr means "object" class this ptr must be returned by add_idc_class() or find_idc_class() @return: always eOk

`def idcv_string(v: idc_value_t)`

  idcv_string(v) -> error_t Convert IDC variable to a text string.

  @param v: (C++: idc_value_t *)

`def last_idcv_attr(obj: idc_value_t)`

  last_idcv_attr(obj) -> char const *

  @param obj: idc_value_t const *

`def move_idcv(dst: idc_value_t, src: idc_value_t)`

  move_idcv(dst, src) -> error_t Move 'src' to 'dst'. This function is more effective than copy_idcv since it never copies big amounts of data.

  @param dst: (C++: idc_value_t ) @param src: (C++: idc_value_t )

`def next_idcv_attr(obj: idc_value_t, attr: char const *)`

  next_idcv_attr(obj, attr) -> char const *

  @param obj: idc_value_t const * @param attr: char const *

`def prev_idcv_attr(obj: idc_value_t, attr: char const *)`

  prev_idcv_attr(obj, attr) -> char const *

  @param obj: idc_value_t const * @param attr: char const *

`def print_idcv(v: idc_value_t, name: char const * = None, indent: int = 0)`

  print_idcv(v, name=None, indent=0) -> bool Get text representation of idc_value_t.

  @param v: (C++: const idc_value_t &) idc_value_t const & @param name: (C++: const char *) char const * @param indent: (C++: int)

`def py_add_idc_func(name: char const *, fp_ptr: size_t, args: char const *, defvals: idc_values_t, flags: int)`

  py_add_idc_func(name, fp_ptr, args, defvals, flags) -> bool

  @param name: char const * @param fp_ptr: size_t @param args: char const * @param defvals: idc_values_t const & @param flags: int

`def py_get_call_idc_func()`

  py_get_call_idc_func() -> size_t

`def pyw_convert_defvals(out: idc_values_t, py_seq: PyObject *)`

  pyw_convert_defvals(out, py_seq) -> bool

  @param out: idc_values_t * @param py_seq: PyObject *

`def pyw_register_idc_func(name: char const *, args: char const *, py_fp: PyObject *)`

  pyw_register_idc_func(name, args, py_fp) -> size_t

  @param name: char const * @param args: char const * @param py_fp: PyObject *

`def pyw_unregister_idc_func(ctxptr: size_t)`

  pyw_unregister_idc_func(ctxptr) -> bool

  @param ctxptr: size_t

`def set_header_path(path: char const *, add: bool)`

  set_header_path(path, add) -> bool Set or append a header path. IDA looks for the include files in the appended header paths, then in the ida executable directory.

  @param path: (C++: const char *) list of directories to add (separated by ';') may be nullptr, in this case nothing is added @param add: (C++: bool) true: append. false: remove old paths. @retval true: success @retval false: no memory

`def set_idcv_attr(obj: idc_value_t, attr: char const *, value: idc_value_t, may_use_setattr: bool = False)`

  set_idcv_attr(obj, attr, value, may_use_setattr=False) -> error_t Set an object attribute.

  @param obj: (C++: idc_value_t ) variable that holds an object reference. if obj is nullptr then it tries to modify a global variable with the attribute name @param attr: (C++: const char ) attribute name @param value: (C++: const idc_value_t &) new attribute value @param may_use_setattr: (C++: bool) may call setattr functions for the class @return: error code, eOk on success

`def set_idcv_slice(v: idc_value_t, i1: uval_t, i2: uval_t, _in: idc_value_t, flags: int = 0)`

  set_idcv_slice(v, i1, i2, _in, flags=0) -> error_t Set slice.

  @param v: (C++: idc_value_t *) variable to modify (string or object) @param i1: (C++: uval_t) slice start index @param i2: (C++: uval_t) slice end index (excluded) @param in: (C++: const idc_value_t &) new value for the slice @param flags: (C++: int) IDC variable slice flags or 0 @return: eOk on success

`def swap_idcvs(v1: idc_value_t, v2: idc_value_t)`

  swap_idcvs(v1, v2) Swap 2 variables.

  @param v1: (C++: idc_value_t ) @param v2: (C++: idc_value_t )

`def throw_idc_exception(r: idc_value_t, desc: char const *)`

  throw_idc_exception(r, desc) -> error_t Create an idc execution exception object. This helper function can be used to return an exception from C++ code to IDC. In other words this function can be called from idc_func_t() callbacks. Sample usage: if ( !ok ) return throw_idc_exception(r, "detailed error msg");

  @param r: (C++: idc_value_t ) object to hold the exception object @param desc: (C++: const char ) exception description @return: eExecThrow

## Classes

`class highlighter_cbs_t`

  Proxy of C++ highlighter_cbs_t class.

  init(self) -> highlighter_cbs_t

  @param self: PyObject *

  ### Instance variables

  `var thisown`

    The membership flag

  ### Methods

  `def cur_block_state(self)`

    cur_block_state(self) -> int32

  `def prev_block_state(self)`

    prev_block_state(self) -> int32

  `def set_block_state(self, arg0: int32)`

    set_block_state(self, arg0)

    @param arg0: int32

  `def set_style(self, arg0: int32, arg1: int32, arg2: syntax_highlight_style)`

    set_style(self, arg0, arg1, arg2)

    @param arg0: int32 @param arg1: int32 @param arg2: enum syntax_highlight_style

`class idc_global_t (*args)`

  Proxy of C++ idc_global_t class.

  init(self) -> idc_global_t init(self, n) -> idc_global_t

  @param n: char const *

  ### Instance variables

  `var name : qstring`

    name

  `var thisown`

    The membership flag

  `var value : idc_value_t`

    value

`class idc_value_t (*args)`

  Proxy of C++ idc_value_t class.

  init(self, n=0) -> idc_value_t

  @param n: sval_t

  init(self, r) -> idc_value_t

  @param r: idc_value_t const &

  init(self, _str) -> idc_value_t

  @param _str: char const *

  ### Instance variables

  `var e : fpvalue_t`

    VT_FLOAT

  `var funcidx : int`

    VT_FUNC

  `var i64 : int64`

    VT_INT64

  `var num : sval_t`

    VT_LONG

  `var obj : idc_object_t *`

    obj

  `var pvoid : void *`

    VT_PVOID

  `var reserve : uchar [sizeof(qstring)]`

    VT_STR.

  `var str`
  `var thisown`

    The membership flag

  `var vtype : char`

    IDC value types

  ### Methods

  `def c_str(self)`

    c_str(self) -> char const * VT_STR

  `def clear(self)`

    clear(self) See free_idcv()

  `def create_empty_string(self)`

    create_empty_string(self)

  `def is_convertible(self) ‑> bool`

    is_convertible(self) -> bool Convertible types are VT_LONG, VT_FLOAT, VT_INT64, and VT_STR.

  `def is_integral(self) ‑> bool`

    is_integral(self) -> bool Does value represent a whole number?

  `def is_zero(self) ‑> bool`

    is_zero(self) -> bool Does value represent the integer 0?

  `def qstr(self, *args)`

    qstr(self) -> qstring VT_STR qstr(self) -> qstring const &

  `def set_float(self, f: fpvalue_t const &)`

    set_float(self, f)

    @param f: fpvalue_t const &

  `def set_int64(self, v: int64)`

    set_int64(self, v)

    @param v: int64

  `def set_long(self, v: sval_t)`

    set_long(self, v)

    @param v: sval_t

  `def set_pvoid(self, p: void *)`

    set_pvoid(self, p)

    @param p: void *

  `def set_string(self, *args)`

    set_string(self, _str, len)

    @param _str: char const * @param len: size_t

    set_string(self, _str)

    @param _str: char const *

  `def swap(self, v: idc_value_t)`

    swap(self, v) Set this = r and v = this.

    @param v: (C++: idc_value_t &)

  `def u_str(self)`

    u_str(self) -> uchar const * VT_STR

`class idc_values_t (*args)`

  Proxy of C++ qvector< idc_value_t > class.

  init(self) -> idc_values_t init(self, x) -> idc_values_t

  @param x: qvector< idc_value_t > const &

  ### Instance variables

  `var thisown`

    The membership flag

  ### Methods

  `def at(self, _idx: size_t)`

    at(self, _idx) -> idc_value_t

    @param _idx: size_t

  `def back(self)`
  `def begin(self, *args)`

    begin(self) -> idc_value_t

  `def capacity(self)`

    capacity(self) -> size_t

  `def clear(self)`

    clear(self)

  `def empty(self) ‑> bool`

    empty(self) -> bool

  `def end(self, *args)`

    end(self) -> idc_value_t

  `def erase(self, *args)`

    erase(self, it) -> idc_value_t

    @param it: qvector< idc_value_t >::iterator

    erase(self, first, last) -> idc_value_t

    @param first: qvector< idc_value_t >::iterator @param last: qvector< idc_value_t >::iterator

  `def extract(self)`

    extract(self) -> idc_value_t

  `def front(self)`
  `def grow(self, *args)`

    grow(self, x=idc_value_t())

    @param x: idc_value_t const &

  `def inject(self, s: idc_value_t, len: size_t)`

    inject(self, s, len)

    @param s: idc_value_t * @param len: size_t

  `def insert(self, it: idc_value_t, x: idc_value_t)`

    insert(self, it, x) -> idc_value_t

    @param it: qvector< idc_value_t >::iterator @param x: idc_value_t const &

  `def pop_back(self)`

    pop_back(self)

  `def push_back(self, *args)`

    push_back(self, x)

    @param x: idc_value_t const &

    push_back(self) -> idc_value_t

  `def qclear(self)`

    qclear(self)

  `def reserve(self, cnt: size_t)`

    reserve(self, cnt)

    @param cnt: size_t

  `def resize(self, *args)`

    resize(self, _newsize, x)

    @param _newsize: size_t @param x: idc_value_t const &

    resize(self, _newsize)

    @param _newsize: size_t

  `def size(self)`

    size(self) -> size_t

  `def swap(self, r: idc_values_t)`

    swap(self, r)

    @param r: qvector< idc_value_t > &

  `def truncate(self)`

    truncate(self)