没有合适的资源?快使用搜索试试~ 我知道了~
首页逆向C++(中文版).pdf
这些年来,逆向工程分析人员一直是凭借着汇编和C的知识对大多数软件进行逆向工程的,但是,现在随着越来越多的应用程序和恶意软件转而使用C++语言进行开发,深入理解C++面向对象方式开发的软件的反汇编技术就显得越发的必要。本文试图通过分析在反汇编时如何手工识别C++对象,进而讨论如何自动完成这一分析过程最终介绍我们自己开发的自动化工具,一步一步的帮助读者掌握逆向C++程序的一些方法。
资源详情
资源评论
资源推荐

逆向 C++
这些年来,逆向工程分析人员一直是凭借着汇编和 C 的知识对大多数软件进行逆向工程的,
但是,现在随着越来越多的应用程序和恶意软件转而使用 C++语言进行开发,深入理解 C++
面向对象方式开发的软件的反汇编技术就显得越发的必要。本文试图通过分析在反汇编时如
何手工识别 C++对象,进而讨论如何自动完成这一分析过程最终介绍我们自己开发的自动化
工具,一步一步的帮助读者掌握逆向 C++程序的一些方法。
作者:Paul Vincent Sabanal
Mark Vincent Yason
译者:Hannibal509@gmail.com
Team509

逆向C++.............................................................................................................................................1
I.引言和必要性 ..............................................................................................................................3
II.手工方法 ....................................................................................................................................3
A. 识别类及其构造函数...................................................................................................3
B. 识别类.........................................................................................................................10
1) 识别构造函数和析构函数.................................................................................10
2) 利用RTTI识别多态类.........................................................................................12
C. 判别类与类之间的关系.............................................................................................18
1.通过分析构造函数来分析类与类之间的关系.......................................................18
2.通过RTTI分析类与类之间的关系...........................................................................19
D.辨别类的成员...................................................................................................................21
III.自动化 ..................................................................................................................................21
A. OOP_RE.........................................................................................................................21
B. 为什么选择静态分析的方式?.................................................................................22
C. 自动化分析的策略.....................................................................................................22
通用算法.........................................................................................................................22
1. 利用RTTI识别多态类.........................................................................................23
2.利用虚函数表识别多态类(不使用RTTI)...........................................................24
3.通过搜索构造/析构函数来识别类.........................................................................25
4.识别类与类之间的继承关系...................................................................................28
5.类的成员的识别.......................................................................................................29
D.显示结果...........................................................................................................................29
1.注释各种结构体.......................................................................................................29
2.改进过的调用图表...................................................................................................30
E.分析结果可视化:UML图.................................................................................................30
IV.小结 ........................................................................................................................................32
Team509

I.引言和必要性
对于逆向工程分析人员来说,能从一个二进制可执行文件中识别出 C++程序
的结构,并且能标识出各个主要的类,以及这些类之间的关系(继承、派生等)
是非常重要的。为了能做到这一点,逆向工程分析人员就必须要(1)能识别出
这些类(2)能识别出这些类之间的关系(3)识别出类中的各个成员。本文就是
要教大家能做到上述三点。首先我们先来讨论如何手工的分析一个 C++程序编译
的二进制可执行文件,从中提取出有关的类的信息。然后我们再来讨论如何自动
化这一手工分析的过程。
当然,要做到这一点需要你花上不少的功夫学习很多技巧,但是为什么我们
要学习并掌握这些东西呢?我认为有下面这三点理由要求我们这么做:
1)用 C++开发的恶意软件越来越多了
跟据我们分析恶意软件的经验,现在我们要分析的恶意软件中使用 C++开发
的恶意软件越来越多了。你知道,把这些恶意软件扔到 IDA 里去进行静态分析的
难度会比较大,因为相对于 C 中的直接函数调用而言,静态分析 C++中的虚函数
调用就比较困难,因为 C++中的调用虚函数是采用间接调用的方式,有时你甚至
都能难确定某个函数是否被调用过。比如臭名昭著的 Agobot 病毒就是用 C++写
的,另外我自己的蜜罐里最近也捕获了一些新的 C++写的恶意软件。
2)用 C++开发的现代的应用程序也越来越多了。
随着操作系统和应用程序的规模和复杂度的与日俱增,C++越来越受软件开
发人员的青睐。这也导致了在漏洞发掘等逆向工程任务中面对 C++语言编写的软
件的可能性也就越来越大。所以逆向分析人员必须要掌握 C++相关的逆向工程技
术
3)关于 C++的逆向工程资料极少
我们相信把 C++的逆向工程资料整理成册,提供给逆向工程分析人员是一件
功德无量的好事,因为这一方面的资料是在是太少了。(译注:在《黑客反汇编
揭密》一书中有部分讨论)
注意:本文中讨论的 C++可执行文件仅限于使用 Microsoft Visual C++编译器编
译出的 C++可执行文件。
II.手工方法
这一节,主要讨论手工分析 C++可执行文件的方法。主要讨论如何识别类及
其成员(变量,函数以及构造函数和析构函数)以及类与类之间的关系。
A. 识别类及其构造函数
要识别出类的成员及类与类之间的关系,我们首先要把各个类给识别出来,
所以我们先来识别类及其构造函数。我们可以通过下列特征从一个可执行文件中
把类和它的构造函数识别出来:
1)大量的使用 ECX 寄存器(作为 this 指针)。我们应该首先注意到的是在
反汇编代码中会大量出现使用 ECX 寄存器(用来传递 this 指针)的情况。如下
图,我们看到在给 ECX 寄存器赋值之后,马上调用了一个函数。
Team509

另外,我们在函数中可能会经常看到 ECX 寄存器还没有初始化就直接被使用
的情况(如下图),这时我们基本上就可以猜出来:这个函数应该就是某个类的
成员函数。
2)调用约定。这一点与 1)有关,类的成员函数在被调用时基本上是把函
数的参数压入栈中,而使用 ECX 传递 this 指针。如下面这个例子,在为类新建
了一个对象之后,new 返回的指针(该指针指向分配给对象的地址)EAX 的值马
上被传给了 ECX,然后就调用了构造函数。
另外,我们有时还会遇到一些间接函数调用,这很可能是调用类的虚函数,
当然,在静态分析的情况下(即不是在调试器中进行动态分析)如果不是事先明
确的知道这个虚函数是哪个类的,要深入跟踪这个虚函数还是很困难的。我们考
虑下面这个例子:
在这个例子里,我们首先要知道 ClassA 的虚函数表(virtual function
table)在哪里,然后才能根据虚函数表来确定虚函数的代码所在的位置。
3)STL(标准模版库 Standard Template Library)中的代码和可执行文件
导入的 DLL。另外,如果我们在检查二进制可执行文件时发现这个可执行文件使
用了 STL 中的代码,这一点可以通过分析可执行文件要求导入的函数或者通过
IDA 的 FLIRT 之类的库签名识别方法来做到:
Team509

下面是调用 STL 中的代码的情况:
类的实例
在我们进一步深入讨论之前,逆向工程分析人员还应该熟悉对象(或者说一
个类的实例)在内存中是个什么样子,说的文绉绉一点就是类在内存中的布局情
况。我们先来看一个简单的类:
这个类在内存中是这个样子的:
最后一个类的成员变量后面有 3 个字节的填充,这是因为要求 4 字节对齐。
在 Visual C++中,类的成员变量是按照其声明的大小依次排列在内存中的。
看 PPT 里的更清楚一点:
Team509
剩余31页未读,继续阅读


















安全验证
文档复制为VIP权益,开通VIP直接复制

评论0