西拉免费代理IP

你当前的位置:西拉免费代理IP   >   新闻中心   >   逆向 | 指针、数组、结构体与对象

逆向 | 指针、数组、结构体与对象

来源: 西拉IP   作者: 张祁无   2018年12月20日 16:14

一、指针与数组的渊源

从逆向的角度去理解数组与指针,并学习怎样识别它们,从而能以多个角度去理解C语言中较为复杂的指针问题。

我们先看一段分别以数组下标和指针方式访问数据的代码,如代码清单1所示。

西拉IP代理,免费代理IP,代理IP地址,IP代理服务器

由以上代码可知,前两组printf()函数是以指针方式访问数组nArray中的数据的,而后两组printf()函数则是使用数组下标的式访问数组nArray中的数据的。

从执行结果我们可以发现,用指针访问数组与用下标访问数组的结果是一样的,那么其反汇编代码是否也一样呢?请看代码清单2。

西拉IP代理,免费代理IP,代理IP地址,IP代理服务器

相对来说,数组与指针的反汇编指令还是很容易理解的,相信通过注释您已经能理解以上反汇编代码的意思了。下面我们再看看代码清单3。

西拉IP代理,免费代理IP,代理IP地址,IP代理服务器

代码清单3  指针与数组的Release版反汇编代码

由代码清单3可知,使用指针取数据与数组取数据的反汇编代码是完全相同的。由此我们完全有理由以数组来解释复杂的指针问题,从而令指针问题变得清晰明了。

二、数组的不同表达方式

数组在反汇编中的表达方式一般分为一维数组、多维数组与循环遍历数组这3种,其中一维数组与多维数组较难区分。以nArray[2][3]这种多维数组的访问方式为例,根据编译器的不同,有可能生成以下反汇编代码:

38.jpg

其实对于以上反汇编指令,我们既可以认为这是一个类似于nArray[11]的访问数组方式,又可以认为这是一个类似于nArray[2][3]的访问数组方式。因为无论采用的是哪种方式,其指向的数据成员都是同样的。因此在实际的逆向工作中,我们很难区分这两种情况。当然,在绝大多数情况下也不需要我们对此进行区分。如果我们出于工作需要必须要对其作出区分,那么唯一能入手的地方就是查看访问这个数组其他数据成员的代码,从代码结构与逻辑着手,进而分析出这是一个几维的数组。

除此之外,当数组遇到需要循环遍历的时候,那么它就会以一种比较有特点的形式出现。

39.jpg

以上语句根据编译器的不同,可能会生成以下反汇编代码:

西拉IP代理,免费代理IP,代理IP地址,IP代理服务器

我们可以发现,在数组面对循环访问的情况下,负责控制访问数组成员偏移的功能由一个寄存器作为选择子来代替,这样做更有利于高效地访问数组中的各个数据。

总体而言,数组的访问总是遵循以下公式:

41.jpg

因此每当我们发现能套用以上公式的访问或地址计算时,就要先考虑这是否是一个数组。

我们简单描述了指针与数组的关系,以及数组的寻址方式。我们发现当从逆向的角度上来研究它们时,数组、多维数组与指针大同小异,这些特性只不过是在C语言层面才被细分成不同的概念。

我们将要接触的结构体、对象的概念与数组也是同根同源的,在逆向时同样很难分辨清楚它们之间的异同。作为逆向来讲,最为关键的就是能还原出目标程序的算法与逻辑,而这些细微的差别并不足以影响我们的逆向结果,但是为了不时之需,我们仍然有必要掌握区分它们的方法与技巧。

三、数组与结构体

数组与结构体存放数据的原则是一样的,它们都是在一段连续的空间中存放若干数据,唯一的不同之处在于数组存放的数据都是同一类型的,而结构体则有可能存放多种类型的数据。我们要怎样才能区分它们呢?请先看代码清单4。

西拉IP代理,免费代理IP,代理IP地址,IP代理服务器

代码清单4  结构体示例

上面的代码十分简单,就是用一个函数打印自定义结构体_TEST里的元素内容。以下是截取的Release版部分反汇编代码:

西拉IP代理,免费代理IP,代理IP地址,IP代理服务器

在分析以上的反汇编代码时应该注意以下问题:

在逆向以上代码时大脑里一定要想象一个堆栈,并随之变化,以免被其迷惑。

这虽然是一段IDA的反汇编代码,但看起来反而没有OllyDbg的反汇编代码简单明了,主要是因为IDA为了表明某些变量是属于一个结构内的,对其作了拆分命名处理,但是却并未能对其进行准确命名,因此将IDA生成的变量名替换成了偏移。由此便导致了一个问题,即IDA本想做好一件事,反而帮了倒忙,例如其中的fstp[esp+4Ch-4Ch]其实就是fstp[esp],很明显IDA画蛇添足了。

除去IDA此次生成反汇编代码本身的混乱不谈,我们注意一下其对于结构体stcTEST的操作,似乎根本看不出它是在操作一个结构体,这段代码看似在操作3个临时变量。而且从程序对结构体的初始化赋值上也完全找不到原本的赋值顺序。当我们试图在堆栈中重组这个结构体时,发现其在堆栈中的存储同样与我们结构体声明的顺序不一样,仿佛一切都乱了。

如果我们事前不知道这是一个结构体的话,那么如何才能通过逆向工程来分辨它呢?答案是几乎不可能,因为编译器在遇到结构体时首先会对其进行拆分,并按照其喜欢的顺序来保存或初始化它,除非我们能得到这个结构体的指针,否则我们基本不可能确定哪些是结构体,哪些是变量。

到此我们已经找到数组与结构体的不同了,即数组是一组同类型的被连续保存的数据,而结构体并不总是如此。换句话说,结构体也有可能与数组一样,例如你声明了一个由多个同类型元素组成的结构体,那么它的反汇编代码特征将与数组一致。有人也许会问,那我们在这种情况下怎样去分辨它们呢?答案是没必要这样做,因为此时无论是从数据结构或从代码逻辑上讲,数组与结构体已经不分彼此了,我们为什么还要去区分它们呢?

四、结构体与类

在C++中,结构体与类是非常相似的,它们都有默认的构造函数与析构函数,也都可以提供自己的接口函数。但是除此之外它们还是有很多不同的。

比如类既可以由结构体继承,也可以由其他的类继承而来,而且类还可以派生出新的子类,但是结构体做不到这些。而且结构体内的所有数据默认都是可以被外界所访问的,因此结构体仅是一个数据的集合,它并不能为维护面向对象的基本思想提供必要的支撑。

在逆向工程中,我们怎样才能分辨出结构体与类的区别呢?又怎样确定结构体或类的大小呢?答案是很难,或者说基本不可能。

一般情况下,我们要逆向的东西肯定不是我们自己写的,而且会遇到由内存对齐问题带来的困扰,并且还有类似于静态数据成员、虚函数与派生类等问题,这让我们确定它们的大小变得基本不太可能。而且,实现相同功能的结构体与类,其生成的二进制代码应该是完全相同的,因此我们也很难分辨这是一个结构体,还是一个类。

五、变量作用域的识别

变量的作用域一般根据其类型而定,比如全局变量与局部变量,我们仅根据其名字就可以大致推断出它们的作用域的差异。

但是除了全局变量以外,其他变量的作用域并不能通过反汇编特征来分辨。以局部变量为例,我们只能通过初始化该变量与最后一次引用此变量的区间为界限,来判断此局部变量的具体作用域,并不能通过其他方式确定。

一般情况下,我们只需要分辨此变量的类型,并粗略地确定其作用域即可。即便是我们要将目标程序还原为源代码,也不需要对变量的具体作用域太过较真,因为我们在逆向出目标程序的基本逻辑之后,后面的工作在还原为源代码时可以根据编程的常识做细微调整。

具体来说,变量总共分为以下几种类型。

全局变量:全局变量的数据总是存储在PE文件中的数据段或代码段中,在游戏修改社群内也被称为“基址”。全局变量的特点是其生存周期与其所在的模块相同,其初始化的内容大多在程序执行之前就已经被保存在程序的数据段中,访问方式为对某一地址空间的直接访问。

局部变量:局部变量的数据保存在栈中,其生命周期与其所在的函数作用域一致,访问方式是使用ebp或esp间接访问。

静态局部变量:静态局部变量的数据保存方式及访问方式与全局变量基本一致,因此很容易被误认为是全局变量。但是在保存此变量的临近位置往往会有一个标志位控制其具体的作用域,当此标志位为1时证明此变量已经被初始化。

堆变量:堆变量的数据保存在new出来的堆空间中,其作用域由与new对应的delete控制,访问方式是使用new出来的指针访问其中的数据。

为了使您对变量类型建立一个比较系统的认识,我们以代码清单5为例演示在实战中可能遇到的情况。

西拉IP代理,免费代理IP,代理IP地址,IP代理服务器

代码清单5  变量类型示例

由于Release版的优化不利于我们演示变量类型的特点,因此我们只采用Debug版的反汇编代码讲解,如代码清单6所示。

西拉IP代理,免费代理IP,代理IP地址,IP代理服务器

代码清单6  变量类型示例的Debug版反汇编代码

为了便于理解,对以上的反汇编代码做了一些处理,使其显得更加清晰明了,在真实情况下IDA生成的反汇编代码可能与以上代码有所不同。

但是通过以上代码,我们已经可以比较直观地分辨出各种变量类型的异同了。

阅读 881   

相关推荐

什么是AJAX? 什么是AJAX?
什么是AJAX?

AJAX,或异步JavaScr ip t和XML,是一组结合了JavaScript和XML的Web开发技术,允许Web应用程序在后台与服务器通信,而不会干扰当前页面。异步意味着在异步脚本运行时可以运行其他函数或代码行。XML曾经是传递数据的主要语言; 然而,术语AJAX用于所有类型的数据传输(包括JSON;我猜“AJAJ”听起来不像“AJAX”那样干净舒服[双关语])。 . . .

2018年12月21日
IPSec VPN 基本工作原理 IPSec VPN 基本工作原理
IPSec VPN 基本工作原理

IP Sec VPN是一项应用最广泛,也最为重要的一种VPN解决方案。它最大特点是安全性高,主要体现在两方面:一是IPSec VPN隧道是要经过一整套安全参数(SA)协商,并得到隧道两端共同认可后才能建立的,即VPN隧道本身也是受保护的;二是在IPSec VPN中传输的数据不仅要经过加密处理,还支持数据完整性验证和数据源身份认证功能(支持像预共享密钥、数字证书和数字信封等多种认证方式),进一步确保 . . .

2018年12月21日
全世界最大的APT组织发起的APT通缉,算不算是APT? 全世界最大的APT组织发起的APT通缉,算不算是APT?
全世界最大的APT组织发起的APT通缉,算不算是APT?

APT(Advanced Persistent Threat)是指高级持续性威胁。 利用先进的攻击手段对特定目标进行长期持续性网络攻击的攻击形式。 . . .

2018年12月21日
黑客都是怎么检查电脑是否中病毒! 黑客都是怎么检查电脑是否中病毒!
黑客都是怎么检查电脑是否中病毒!

电脑病毒相信大家都不陌生,现在的病毒已经从以前的破坏电脑程序到如今的偷偷窃取用户隐私信息,实在是可恶至极。今天来教大家检查电脑是否中病毒。 . . .

2018年12月20日
WebSocket WebSocket
WebSocket

WebSocket是一种通信协议,用于从用户的Web浏览器到服务器的持久,双向,全双工 TCP连接。 . . .

2018年12月20日
使用查询来记录SQL Server数据库

您是否知道可以使用查询来记录SQL Server数据库?这个关于系统表的简单查询就是这样做的。您可以轻松地将结果剪切并粘贴到Word文档中,并改善外观。想象一下你将节省的打字数量!我使用此查询 . . .

2018年12月20日
将数据库从开发迁移到研发

如果您在一家小公司工作,那么您的开发,测试和生产数据库可能位于同一台服务器上。但是,大多数组织都意识到与此类设置相关的风险。如果您的服务器因磁盘故障或停电而变得无法使用,您不仅会损失当前客户的 . . .

2018年12月20日
如何使用SQL查询来记录数据库

您是否知道可以使用SQL查询来记录SQL Server 2000数据库?这个关于系统表的简单查询就是这样做的。您可以轻松地将结果剪切并粘贴到Word文档中,并改善外观。想象一下你将节省的打字数 . . .

2018年12月20日
Microsoft的网络访问保护可以确保安全合规性

计算机安全一直是关于更新和限制的。更新确保计算机具有适当的补丁和软件版本以防止恶意代码,而限制(无论是通过网络还是系统控制)确保只允许在计算环境中发生预先批准的行为。 但安全 . . .

2018年12月19日
了解Microsoft的网络访问保护的内部和外部组件 了解Microsoft的网络访问保护的内部和外部组件
了解Microsoft的网络访问保护的内部和外部组件

Microsoft的网络访问保护是一种复杂的安全解决方案,而不是简单的“下一步,下一步完成”IT项目。它需要集成多个组件,并了解这些组件 - 以及它们连接的方式和原因 - 将为您设计最适合您业 . . .

2018年12月19日

新闻中心 代理分享 | 蜘蛛地图

全网最大的免费网页代理ip平台,提供大量免费http代理服务器免费ip代理地址

© 2016 - 2021. 西拉免费代理ip, All rights reserved. 鄂ICP备18017015号-4

在线客服