00:02
呃,大家好,呃,我们今天呢,来分享一个关于C语言题目啊,这个题目呢,是我一个学信息的朋友发给我的一个题目,这个题目呢,这写的是缓冲区溢出的代码,呃,这个题目呢比较简单,适合于这个入门来学习啊,我们先看一下这个题目。就是代码,然后再看一下针对这个代码问的三个问题。啊,他发给我这个呢,其实我写过一篇这个在我的公众号上写过一篇文章啊,然后这个是我的公众号的二维码,如果想看文章的也可以扫一下这个二维码。嗯。我们先来看一下。首先第一句呢,In Apple就是定义了一个整形的Apple变量,然后呢。定义了一个字符,字节型的这个就是叉型的buffer,长度呢是九九,也就是定义了一个这个九个字节。
01:08
再往下呢,就是gets buffer,就是通过这个gets函数呢,从这个标准输入设备上来获取输入的内容,最后保存到我们这个buffer,也就是说我们的这个字节数组里边。下面这有个if if就是Apple等于0X636464636261的话,就输出hello world。啊,其实如果我们光看这段程序的话,会感觉,哎,我们这个程序根本就没有对这个Apple进行过输入,对吧,就没有进行过赋值,也没有进行过输入,它怎么可能就是满足这个条件呢。对吧,会有这么一个想法,然后我们看一下他这个题目啊。第一个问题就是分析是哪种类型,就是哪种溢出的类型。第二个题目呢,就是给出题目的变量,Apple的地址。
02:03
例如这个地址是000X0012FF44啊,就是说这个地址呢,就是Apple的这个地址,然后根据这个地址呢,写出这个buffer各个字节的地址字符的地址啊,也就是说是可能是要我们根据这个Apple的地址来计算这个buffer的地址啊。然后第三个题目呢,就是说是abcd ask分是X61626。然后给出buffer输入方式,使得这个程序可以输出这个hello world。啊,这个题目呢,其实考察的主要是对这个局部变量的内存结构啊。呃,我们来先来看一下这个第一题啊,就是说是是哪种类型的溢出,就什么一什么溢出的类型,然后我们首先说一下这个缓冲区啊,就是通常情况下缓冲区呢。
03:02
就是说是。可以分为这个占内存和堆内存。就是对于我们经常经常来就是写代码的话啊,这个占内存呢,就是存放这个局部变量的,然后它还存放这个函数的参数。然后他还就是保存一些这个函数调用时的一些现场,就比如说他要保存一些。呃,当前战争里边的寄存器的值啊,比如说这个EBP和ESP之类的。这个EP和EP呢,指的就是32,说的是32位操作系统下的这个。寄存器啊,然后堆内存呢,呃,就是我们程序员通过比如说这个mylock或者是new来申请的这个。内存啊,对内存申请后呢,就必须由程序员来释放,这个占内存呢,一般情况下是不需要的哈。
04:08
呃,这个内存一般是CPU自己来维护,就是随着我们的函数的调用和函数调用的推出呢。来,自己就是。维护好,我们这写一下啊。缓冲区的类型一般就是。这。和。对。啊,一般就是战和对两种。啊,这个站就是局部变量啊,什么参数堆呢,就是通过什么new了mylock了之类的申请的啊,然后什么是缓冲区溢出呢?缓冲区溢出其实就是说是我们的。这个值就是我们的输入呢。已经超出了我们这个缓冲区的长度了。而导致把这个缓冲区长度之外的。
05:03
内存。空间中的值给覆盖掉了。简单来说呢,就是这样啊。然后就是缓冲区溢出攻击的话,其实就是在这个。呃,缓冲区溢出攻击的话,其实就是说是他把一些数据,其实是一些代码以数据的形式呢。呃。存到这个。站中或者是堆中,然后呢,再想办法执行。他这个植入的数据啊。这儿可能就是表达的不是特别清楚。嗯。我们还是接着就是说一下我们这个题目。啊,我把刚才说的这几点也记一下。就是缓冲区的类型,然后就是。
06:02
缓冲区。一出就是。数据长度超过缓冲区的长度。导致。数据覆盖掉。缓冲区之外的。内存啊。缓冲区溢出攻击啊,就是。构造这个输入的数据。嗯,然后。通过特定的方式。执行输入的数据。而这些数据其实本身它就是一些可执行的代码。
07:04
啊,他其实就是就是这个样子的。然后我们接着来看这个题目啊。屏幕第一题就是说是要分析是哪种类型的一出。呃,因为这是局部变量对吧。局部变量的话,肯定第一题给给出的类型就是占一处。就是战役处。嗯,然后再来这个第二题,就是比如说是Apple的地址是0X12FF44,然后让我们给出这个buffer的这个地址。然后我来画一下啊。一般我们这里讲讨论这个32位的这个。呃,机器啊,32位机器的话,一般就是长度都是四个字节嘛。对吧。
08:00
然后把这的这个地址给出,地址的话是0X0012FF44对吧,而这一块呢,是这个。Apple的地址对吧。Apple这个变量的地址。一般情况下,呃,在C语言中的话。呃,先定义的这个变量的地址。比这个后定义的变量的地址要高,因为这使用的是占空间,占空间它的这个地址延伸的方向呢,是从高到低的。啊,也就是说我们这里呢,是。地址。然后下面呢。是D地址。然后就是知道了这个增长的方向以后。
09:04
知道这个增长的方向以后呢,我们就知道这个buffer的地址肯定是要比这个地支小。但是是不是就是说是用这个Apple的地址减去九,因为它的长度是九,就能得到这个buffer的地址呢?其实不是啊,因为就是说是。那是这个。32位的系统的话,它是按照这个四字节进行对齐的。它虽然是九个字节,但是它也要按四个字节,四个字节那么去对齐啊。我这一条这里面就代表的是四个字节啊,所以的话往下其实是减12啊。也就是说拿这个0X12FF44减12就是这个八分的这个地址,但是这个0X0012FF44是一个16进制,它把12呢转换成这个。
10:04
呃,16进制呢,就是C是吧,所以的话,我们的地址我一点一点的往下排啊。这么排列一下的话,就比较容易容易一些了。然后再是零对吧。四个字节嘛。这呢,就是。这应该是3C。对吧。这儿的话就应该是三。Far。对吧,这样的话其实就整个下来。这就是12个字节。对吧。不行,我们可以数一下嘛,对吧。吧,然后画下吧。有点大,画的稍微小一点。
11:08
还是有点偏大啊。啊,没关系,就这样啊。这3839AB。然后呢?C。D。E。F。F完了就直接就是零了,对吧,是逢16进一。4041。四二。四三,然后到这儿的话,Apple的话,其实地址刚好是四四。但是它的长度,因为它是整形嘛,就是四个字节对吧。啊。所以的话,我把这颜色选中一下。
12:03
给一个。黄色吧,这一部分呢,就是代表的。Apple的地址。而这一部分。再给个其他的颜色,给个绿色吧。而这部分呢,就是buffer的这个地址。但是buffer的起始地址呢,是0X0012F38。然后从。0012F38开始数九,自己就是八的地址,而这三个地址呢,其实就是用来进行一个对齐的啊,32位的这种操作系统呢,它四字节对齐,它每次读四个字节的时候,其实访问速度是最快的啊,访问速度是最快的。呃,所以的话,我们这儿呢,给算出来的8UFF地址就是0X12F f38,然后看最后最后一题,最后一题呢,就是说是abcd的阿斯克码分别是这个000X61626364,然后我们怎么样。
13:13
对这个buffer进行一个输入,然后就可以使这个程序输出这个hello word这一块呢,就使用到C语言的一个特性啊,C语言一个什么特性呢?就是说是C语言可以允许数组,就是越界访问。啊,也就是说他不对边界进行检查,我们只要输出的时候。能把整个Apple这也覆盖掉就可以了,所以的话,我们其实输入12个任意字符以后。给一个。Abcd。就可以了。好,来看一下啊。就是说我才给一一。一。
14:03
然后这是abcd。啊就可以了,但是abcd的是0X61626364,但是Apple比的时候是0X64636261对吧,这样的话能相等吗?其实是能相等的啊。呃,因为。Apple的地址。是从四四开始的。他呢,地址实际是444546和四七这么四个地址。而这个顺序它其实是就是一种内存的顺序啊,叫字节序,字节序呢,不在咱们这次讨论的范围之内,这个字节序呢。呃,也算是看内存的一个基础吧,字节序分的这种就是主机字节序,网络字节序,就是根据这个呃,主机和网络来说的,当然了,主机呢,又分为这种,呃,大尾方式和小尾方式,这是。
15:06
这是根据CPU不同而不同的啊,然后这个网络的这个字节序呢,用的是这种大的方式啊,就像Java这种语言,我记得也是用的搭尾方式啊。啊,所以的话就是说第三题我们给出的答案呢,就是只要我们任意输入前12个字符,1234567890C12ABCD。啊,只要只要在我们。只要在gets这个部分。等待接受输入的时候,我们只要输入这个。就可以让这个程序输出这个hello啊。呃,基本上就是这样。呃,我们这次呢,主要就是把整个这个内存结构讲了一下,这个内存结构呢是占啊占的话地址是由高到低进行延伸的。
16:09
和这个。变量的地址呢,就局部变量的地址呢,是先定义的,它的地址就高,后定义的地址就低啊。所以的话,这个。知识呢,本身其实挺简单的,就是下这次呢,我们就是讲一下这个题。啊,然后我们就这么分析一下,然后下次呢,我们在这个使用代码来进行演示一下,当然了,呃,使用代码演示呢,其实也比较容易,主要也是通过代码在调试的时候,可以看一下这个内存的地址,让我们有一个更加直观的认识。好,感谢大家,再见。
我来说两句