山西
400-650-7353
首页 > 计算机二级 > 【备考】C++语言考试技巧:识别类及其构造函数

【备考】C++语言考试技巧:识别类及其构造函数

2018-08-16 17:09:20 来源:互联网 荐:IT资料豪华升级版,点击加群领取

C++语言考试技巧:识别类及其构造函数

1.引言和必要性

对于逆向工程分析人员来说,能从一个二进制可执行文件中识别出 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++可执行文件.

2.手工方法

这一节, 主要讨论手工分析 C++可执行文件的方法。主要讨论如何识别类及 其成员(变量,函数以及构造函数和析构函数) 以及类与类之间的关系。

A. 识别类及其构造函数

要识别出类的成员及类与类之间的关系,我们首先要把各个类给识别出来,所以我们先来识别类及其构造函数。我们可以通过下列特征从一个可执行文件中 把类和它的构造函数识别出来:

1) 大量的使用 ECX 寄存器(作为 this 指针)。我们应该首先注意到的是在反汇编代码中会大量出现使用 ECX 寄存器(用来传递 this 指针)的情况。如下图,我们看到在给 ECX 寄存器赋值之后,马上调用了一个函数。

另外,我们在函数中可能会经常看到 ECX 寄存器还没有初始化就直接被使用的情况(如下图),这时我们基本上就可以猜出来:这个函数应该就是某个类的成员函数。

2)调用约定。这一点与 1)有关,类的成员函数在被调用时基本上是把函数的参数压入栈中,而使用 ECX 传递 this 指针。如下面这个例子,在为类新建了一个对象之后,new 返回的指针(该指针指向分配给对象的地址)EAX 的值马上被传给了 ECX,然后就调用了构造函数。

另外,我们有时还会遇到一些间接函数调用,这很可能是调用类的虚函数,当然,在静态分析的情况下(即不是在调试器中进行动态分析)如果不是事先明确的知道这个虚函数是哪个类的,要深入跟踪这个虚函数还是很困难的。我们考虑下面这个例子:

在这个例子里,我们首先要知道 ClassA 的虚函数表(virtual function table)在哪里,然后才能根据虚函数表来确定虚函数的代码所在的位置。

3)STL(标准模版库 Standard Template Library)中的代码和可执行文件导入的 DLL。另外,如果我们在检查二进制可执行文件时发现这个可执行文件使用了 STL 中的代码,这一点可以通过分析可执行文件要求导入的函数或者通过 IDA 的 FLIRT 之类的库签名识别方法来做到:

下面是调用 STL 中的代码的情况:

类的实例

在我们进一步深入讨论之前,逆向工程分析人员还应该熟悉对象(或者说一个类的实例)在内存中是个什么样子,说的文绉绉一点就是类在内存中的布局情况。我们先来看一个简单的类:

这个类在内存中是这个样子的:

最后一个类的成员变量后面有 3 个字节的填充,这是因为要求 4 字节对齐。 在 Visual C++中,类的成员变量是按照其声明的大小依次排列在内存中的。 看 PPT 里的更清楚一点:

那么怎么才能得到上面这张图呢? 我们可以使用-d1reportAllClassLayout 这个编译开关,它可以让 MSVC 编译器(译注:至少是 MSVC 6.0 以上的版本)生成一个.layout 文件,在该文件中包含有大量的极具价值的类的布局信息,包括基类在派生类中的位置,虚函数表,虚基类表(virtual base class table 我们下面会深入讨论),类的成员变量等信息(实际上我们这些图表都是从.layout文件中取出的)。

编辑推荐IT学习交流群:点击加群 571960479

加群备注:网站(限时赠送500G海量IT学习资料)

关注微信:山西优就业(ID:ujiuyesx)

回复:简历模板,即可领取

【各类行业的简历模板】

回复:安装包的名称,例:AI,即可领取

AI、DW、PS、AX、C4D等破解版软件

【小U将毕生绝学传授于你,打倒HR,轻松搞定CEO】

相关推荐:暑期IT镀金之行

【备考】常见C++笔试题目整理(含答案)

更多分享交流,礼品领取,海量干货,请扫描下方内部资料领取二维码,一不小心就爱上IT,成为了大佬!

免责声明:本文来源于网络,由网友提供或网络搜集,仅供个人交流学习参考使用,不涉及商业盈利目的。如有版权问题,请联系本站管理员予以更改或删除。谢谢合作!

热门标签: C++ 识别类 构造函数

猜你喜欢

推荐阅读