I am using IDAPython for my analysis. In IDA v6.95, the header file plugins/hexrays_sdk/include/hexrays.hpp
defines the following:
typedef ctree_items_t parents_t;
parents_t parents; ///< Vector of parents of the current item
/// Get parent of the current item as an expression
cexpr_t *parent_expr(void) { return (cexpr_t *)parents.back(); }
// Get parent of the current item as a statement
cinsn_t *parent_insn(void) { return (cinsn_t *)parents.back(); }
For my analysis, I am trying to walk up along the parents from a given cexpr_t
node. parent_expr()
and parent_insn()
API gives me back the immediate parent, not the entire chain from the child to root of the AST.
As an alternative, I tried to traverse the parents
vector once I visit the given cexpr_t
node.
for parent in reversed(self.parents):
print "|==> %s [%d]" % (hex(parent.ea), parent.op)
The problem is, the parent
item thus returned is of type citem_t
. If I cast those to cexpr_t
as follows:
parent.__class__ = cexpr_t
print parent.x
and access any of its fields (e.g. x
) in the example above, it throws error.
How can I traverse the AST nodes bottom-up yet retaining the correct types (cexpr_t
or cinsn_t
) of respective nodes? Is it possible to look into the code of parent_expr()
or parent_insn()
to see if how do those return correctly typed nodes from an ctree_items_t
type vector (i.e. parents
)? The code inside python/ida_hexrays.py
seems to be mere SWIG stub, the actual implementation seems to lie somewhere else.
def parent_expr(self, *args):
"""
parent_expr(self) -> cexpr_t
"""
return _ida_hexrays.ctree_visitor_t_parent_expr(self, *args)
def parent_insn(self, *args):
"""
parent_insn(self) -> cinsn_t
"""
return _ida_hexrays.ctree_visitor_t_parent_insn(self, *args)
The actual code seems to be distributed as a shared library located at python/lib/python2.7/lib-dynload/[ida32|ida64]/_ida_hexrays.so