如何使用 IDAPython 反编译器 API 沿着 AST 前进?

逆向工程 艾达 蟒蛇 六线谱
2021-06-28 23:40:36

我正在使用 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_tcinsn_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

1个回答

我可以解决你的部分问题。使用 'to_specific_type' 属性将引用项转换为 cexpr:

if citem.is_expr():
    cexpr = citem.to_specific_type