Hex-Rays 反编译插件编写简介
前段时间对Hex-Rays 反编译插件编写进行了简要了解,在此发帖总结一下自己学习所得和大家一起分享。
由于本人水平有限,难免会有错误,希望大家批评指正。
偶然间接触到了Hex-Rays SDK,引起了我的兴趣,网上google之,发现关于反编译插件编写的文档实在是不多,于是只能从SDK下手了。
正式开始之前先说些废话。众所周知,Hex-Rasy Decompiler是使用IDA Pro SDK编写的。它以插件的形式存在于IDA中,可以将IDA反汇编代码逆向成为相应的类C语言伪代码(IDA 中的F5),提高程序的易读性,为理解程序功能提供了很多方便。Hex-Rays反汇编结果相对来说是目前所能得到的最好的,我们能不能将其结果拿来,来实现自己的某些功能呢?
一:Hex-Rays SDK特性简介。
所用IDA版本为6.1,Hex-Rays SDK版本为1.5,据其SDK描述文档介绍,它有以下特性:
1.包含用于反编译编程的API函数,目前只能访问反编译结果和用户接口;
2.可以对函数进行反编译,获取ctree结构(关于ctree结构下面会简要介绍),它是一个用于存储反编译结果的结构体;
3.可以随意对ctree结构进行修改,可以对语句重排、优化表达式、增加或移除变量等;
4.可以在反编译界面中增加新的菜单项,对用户行为作出(点击键盘、鼠标等)回应;
5.在运行过程中对反编译事件进行挂钩,修改反编译结果。
二:如何编写基于Hex-Rays SDK的插件
1.需要最新的IDA SDK 和反编译SDK(新的SDK可能不兼容旧的SDK,具体没做验证)。
2.Hex-Rays SDK只包含一个头文件hexrays.hpp,编程是只须将其复制到IDA SDK的include目录下即可。
3.反编译插件的编写方式及工程配置方式与IDA插件类似,在此不再多说。
注意:所有的反编译插件名必须以“hexrays_”作为前缀,这么做的目的是保证反编译插件在hexrays之后加载。否则在加载时会提示“未找到反编译插件,立即终止”。
三:相关结构体简介
1.ctree:顾名思义,这是一个类似于树的数据结构。顶层存在一个cfun_t类,用于构建ctree。cfun_t类用于描述函数,并提供对函数属性访问的接口,具体可以查看hexrays.hpp。ctree的构建并不是一步完成的,它开始于一个空ctree,然后构建一个粗略的函数体,之后经过多步修改才得到稳定的ctree,因此可以对构建过程挂钩,修改ctree。ctree的结点要么是cinst_t(语句)类,要么是cexpr_t(表达式)类。它们都是citem_t的派生类,citem_t类是一个抽象类。citem_t中的一个比较重要的字段是op,它是ctype_t类型的,ctype_t是一个enum,用于识别结点的类型。Hex-Rays定义了两种类型:cot_xxxx和cit_xxxx,前者表示表达式项,后者表示语句项。
2.cexpr_t:结合hexrays.hpp,注意到其中包含一个union,其包含信息依据op字段指定。例如,如果cexpr.op == cot_num,那么我们可以访问cexpr.n字段来获取cnumber_t对象,提取常量值。
如果表达式有两个操作数(比如cot_add、cot_sub、cot_bor等),此时有两个子表达式:cexpr.x表示左边的操作数,cexpr.y表示右边的操作数。
在函数调用的情况下(用op == cot_call表示),通过访问cexpr.x.obj_ea 字段来获取被调用的函数地址,其参数保存在a(carglist_t对象)中。
3.cinsn_t:与cexpr_t类似,可以根据语句类型不同提取相应的信息,在此不再赘述。
4:cfunc_t:若使用Hex-Rays对函数进行反汇编,其返回一个cfunc_t对象,可参考SDK中的例一。cfunc_t中对我们来说最重要的就是body属性,它指向ctree的根节点,可以用来遍历tree结构,Hex-Rays SDK提供了通用的访问类,使得遍历ctree结构变得简单。
今天就写这么多吧,文采不好,写的可能有点乱,大家若遇到什么问题可以提出来一起讨论,共同提高。
