欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C和混编混合编程----strcpy缓存溢出原理

程序员文章站 2022-05-03 15:45:10
...

今天老师给了一到程序,让我们分析分析原理,关于strcpy缓存溢出原理的,反汇编一遍遍调试,终于看明白了,记录一下
C程序:

#include "string.h"
#include "stdio.h"
char *shellcode="\x64\x65\x66\x67\x68\x69\x70\x71\x05\x10\x40\x00";
void fun1(int a, int b)
{
   printf("fun1 run!para a=%d,b=%d\n",a,b);
}
void fun2(int a)
{
   printf("fun2 run! para a=%d\n",a);
}
void fun3(int a,int b,int c)
{
  printf("fun3 run! para a=%d,b=%d,c=%d\n",a,b,c);
}
int main(int argc, char* argv[])
{
	printf("begin\n");
    char a[4]={0};
	strcpy(a,shellcode);
	fun1(2,3);
    fun2(4);
	fun3(4,5,6);

	return 0;
}

运行结果:
C和混编混合编程----strcpy缓存溢出原理
可以看出,按照正常的C的话,fun2函数应该只会执行一次,但执行了两次,事出反常必有妖,让我们来分析一下,反汇编:

当程序执行strcpy前,a的值是0x0019ff2c,这个是地址,存放的是0000000,在这里我们要特别注意0019ff30和0019ff34地址里面的值,后面执行fun2会用到
C和混编混合编程----strcpy缓存溢出原理
执行完strcpy后,a内容是地址为0x0019ff2c存放的值,我们可以看到0019ff30和0019ff34地址存放的内容发生了改变,这个时候我们再看C程序中shellcode数组的值:
C和混编混合编程----strcpy缓存溢出原理

char *shellcode="\x64\x65\x66\x67\x68\x69\x70\x71\x05\x10\x40\x00";

发现0x0019ff2c到0019ff34存放的数据就是这些值,而且0019ff30和0019ff34存放的数据被这些覆盖了。a数组大小为4,shellcode是12,a的数组存放不了shellcode的值,而strcpy函数不会检查要复制的内容的大小,只管把要复制的内容复制过来,内存不够,覆盖内存中其他数据。

当执行完fun3是,按说应该程序结束,来让我们看看,为什么fun2还会执行
C和混编混合编程----strcpy缓存溢出原理
当执行到pop ebp是,当前esp的值为0019ff30,内容为68697071,执行完后ebp的值就是68697071,ebp的值原本不是这个,因为使用strcpy把原本的内容覆盖了

C和混编混合编程----strcpy缓存溢出原理
当执行到ret时,这个时候我们就要注意了,因为执行完这条语句就会去执行fun2函数,ret指令相当于执行:

pop eip

这个时候esp的值为0019ff34,内容为00401005,执行ret后eip=00401005
C和混编混合编程----strcpy缓存溢出原理
我们来看看fun2函数地址,是00401005,这就是为什么执行完fun3回去执行fun2
C和混编混合编程----strcpy缓存溢出原理

总结:

  1. strcpy 函数不对数组边界进行检查,只管把要复制的内容复制过来,内存不够,覆盖内存中其他数据,很容易造成缓冲区溢出的漏洞
  2. shellcode数组里的值一共12位,最后ret语句会把最后4位赋值给eip,我们可以利用这个跳转到我们想要执行的代码处
  3. 向缓冲区内填充数据,如果数据的长度很长,超过了缓冲区本身的容量,那么数据就会溢出存储空间,而这些溢出的数据还会覆盖在合法的数据上,这就是缓冲区和缓冲区溢出的道理。

参考

https://blog.csdn.net/yahohi/article/details/7724669
https://blog.csdn.net/xiaoyuai1234/article/details/52121588

相关标签: win32汇编