从零开始学逆向之x86篇(三)

2021-02-23 8,223

在本系列文章中,我们将为读者从头开始介绍x86架构下的逆向工程技术。

 

7课:晶体管与存储器

 

如果需要查看所有课程的完整目录,请点击下面连接,因为它不仅提供了每节课程的简介,同时提供了每节课所涵盖的主题:https://github.com/mytechnotalent/reverse-engineering-tutorial。

 

在上节课中,我们深入研究了十六进制数制。我将把这周的课缩短,这样你们就可以复习上周的课了。除了进行手工的加减运算练习之外,大家还需要熟悉十六进制数的转换,这一点怎么强调也不为过。

 

在现实世界中,我们通常使用计算器;在现实世界中,我们通常使用的是Windows操作系统;在现实世界中,专业的逆向工程师通常使用GUI调试器,如IDA Pro等。

 

问题是,为什么我没有直接介绍逆向工程师的核心工作呢?答案很简单,必须对机器有深深的尊重和理解,才能精通它。如果不先充分了解世界,我们就永远无法改变世界。耐心和毅力是制胜法宝。

 

我将重点放在Linux和基于控制台的编程环境,因为大多数专业服务器都使用Linux,因此,它们是恶意软件首要的攻击对象。同时,如果理解了Linux汇编语言,那么掌握Windows汇编语言就会是一件非常轻松的事情。

 

废话少说,让我们回到计算机的基础知识上面来吧!

 

当我们问自己什么是计算机时,我们必须尽可能地去了解最本的东西。

 

电子计算机实际上就是由晶体管开关构成的。晶体管是硅的微观晶体,利用硅的电学特性作为开关。现代计算机使用的是所谓的场效应晶体管。

 

让我们以晶体管的3个引脚为例进行介绍。当电压施加到引脚1时,电流就会在引脚2和3之间流动。当电压从引脚1移除时,电流就会停止在引脚2和3之间流动。

 

当我们放大一点,我们将看到还有二极管和电容,当把晶体管开关结合在一起,我们现在就得到了一个存储单元。一个存储单元保持一个最小电流,当你在它的输入引脚上施加一个小电压,并在它的选择引脚上施加一个类似的电压时,就会在它的输出引脚上出现并保持一个电压。输出电压将一直保持置位状态,直到选择引脚与输入引脚上的电压消失为止。

 

为什么了解这一点非常重要呢?非常简单地,存在电压表示二进制1,而不存在电压表示二进制0,因此,存储单元可以存储一个二进制数字或二进制位:1或0,表示开或关。

 

在下一课中,我们将讨论字节和字。

 

 

8课:字节、字、双字……

 

如果需要查看所有课程的完整目录,请点击下面连接:https://github.com/mytechnotalent/reverse-engineering-tutorial,这里不仅给出了每节课的简介,同时还提供了每节课所涵盖的主题。

 

内存是以字节为单位的。一个字节由8位组成。两个字节叫做一个字,两个字叫做双字,双字包含4个字节(32位),而四字则包含8个字节(64位)。

 

一个字节含有8位,可以表示2^8的幂即256种状态。而长度为8位的二进制数的取值范围,则是从0到255,共256个值。

 

计算机中的每个内存字节都有自己的唯一地址。下面,让我们通过在main函数上设置断点来回顾Linux中一个简单的hello world应用程序的反汇编指令。为此,我们将使用GDB调试器:

 1.jpg

如果还没有弄明白,也不要担心。使用这个例子的目的,主要是为了让你先熟悉一下我们的第一个程序,顺便来了解一下计算机的内存方面的知识,将来,我们还会跟这个程序打交道。

 

下面,我们来考察一下ESP寄存器。同样,您是否了解寄存器或ESP的作用并不重要,这里只是想看看内存地址是什么样子的:


 

这里考察的内存位置是0xffffd040,当然,该地址是用十六进制表示的。我们还可以看到,ESP寄存器里面的值是0xf7fac3dc,该值也是十六进制的。

 

需要说明的是,0xffffd040是4个字节,即一个双字。正如我们在第6课中所学到的,每一个十六进制数字都占4位,即半字节。对于0xffffd040,让我们看看0的最右边的数字,在这个例子中,十六进制数0是4位长。对于十六进制数40,长度为一个字节,即8位。对于十六进制数d040,则占用两个字节,即一个字的长度。最后,fffd040是一个双字,长度为4个字节,即32位。地址开头部分的0x只是表示这是一个十六进制值。

 

实际上,计算机程序不过是存储在内存中的机器指令。32位的CPU从内存地址中获取一个双字。一个双字,其实就是连续的4个字节,从内存中读出并加载到CPU中。一旦执行完毕,CPU就会从指令指针中取回内存中的下一条机器指令。

 

好了,我们已经对汇编有了一个直观地印象。如果您还是不太明白,也不要灰心或沮丧。我们会在以后的课程中慢慢地通过几十个例子来进行详尽的解释。重要的是,您要花些时间去研究每节课所讨论的内容。如有任何问题,请随时在下面留言。

 

在接下来的教程中,我们将讨论x86架构的基础知识。

 

 

9课:x86基本架构

 

如果需要查看所有课程的完整目录,请点击下面连接:https://github.com/mytechnotalent/reverse-engineering-tutorial,这里不仅给出了每节课的简介,同时还提供了每节课所涵盖的主题。

 

计算机应用程序只是一个存储在内存中的机器指令表,实际上,组成程序的二进制数的具体含义,要视CPU处理它们的方式而定。

 

基本结构由CPU、存储器和I/O设备组成,I/O设备即输入/输出设备,它们都通过系统总线连接,具体如下所示:

 1.jpg

CPU由4个部分组成,具体如下所示:

 

1)控制单元:CPU通过它来读取指令,并对其进行解码,然后,将指令存储内存中,或从内存中检索指令。

 

2)执行单元:用于获取和检索指令的单元。

 

3)寄存器:CPU内部的存储单元,用来临时存储数据。

 

4)标志:表示执行指令过程中发生的事件。

 1.jpg

由于这里讨论的是32位的x86架构,因此,32位的CPU首先从内存中的特定地址中获取一个双字(长度为4字节或32位),并从内存中读取并加载到CPU中。这时CPU查看双字内的位的二进制模式,并开始执行获取的机器指令指示的过程。

 

在执行完一条指令后,CPU会从内存中按顺序读取下一条机器指令。在CPU中,有一个寄存器,称为EIP或指令指针,用于存放要从内存获取并执行的下一条指令的地址。

 

不难发现,如果我们能够控制EIP的内容,我们就可以改变程序的行为,使之做一些它原来不打算做的事情。这是恶意软件赖以运作的一种流行技术。

 

实际上,指令的整个获取和执行过程与系统时钟紧密相连,而系统时钟则是一个振荡器,以精确的时间间隔发出方波脉冲。

 

在下一个教程中,我们将深入考察IA-32架构的通用寄存器。

 

小结

 

在本系列文章中,我们将为读者从头开始介绍x86架构下的逆向工程技术。更多内容,敬请期待!

 

(未完待续)

 

https://0xinfection.github.io/reversing/pages/part-8-bytes-words-double-words-etc.html


本文作者:mssp299

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/153797.html

Tags:
评论  (0)
快来写下你的想法吧!

mssp299

文章数:51 积分: 662

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号