我正在使用 IDAPython 进行分析。在 IDA v6.95 中,头文件plugins/hexrays_sdk/include/hexrays.hpp
定义了以下内容:
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(); }
对于我的分析,我试图从给定cexpr_t
节点沿着父母走。parent_expr()
和parent_insn()
API给我回直接父,而不是整个产业链,从孩子到AST的根源。
作为替代方案,我尝试在parents
访问给定cexpr_t
节点后遍历向量。
for parent in reversed(self.parents):
print "|==> %s [%d]" % (hex(parent.ea), parent.op)
问题是,parent
这样返回的项目的类型是citem_t
。如果我将它们转换cexpr_t
为如下:
parent.__class__ = cexpr_t
print parent.x
并x
在上面的示例中访问其任何字段(例如),它会引发错误。
如何自下而上遍历 AST 节点,同时保留相应节点的正确类型(cexpr_t
或cinsn_t
)?是否可以查看代码parent_expr()
或parent_insn()
查看这些节点如何从ctree_items_t
类型向量(即parents
)返回正确类型的节点?里面的代码python/ida_hexrays.py
似乎只是 SWIG 存根,实际的实现似乎在其他地方。
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)
实际代码似乎作为共享库分发,位于 python/lib/python2.7/lib-dynload/[ida32|ida64]/_ida_hexrays.so