①通过缓冲区溢出原理改变main函数变量的值

通过缓冲区溢出原理————⑴改变main函数变量

#include <stdio.h>
int get_addr()
{ 
  int str[10]={0}; 
  for(int i=0;i<1;i++)
        printf("%x \n",str[i]);        
  return str[11]; 
}
int main()
{   
     int b=0;   
     int c=0;          
    
     c=get_addr();    
     *((int *)(c-8))=1;  
     *((int *)(c-12))=2;        
     printf("%d",b);
     printf("%d",c);
     
     return 0;
}


先贴出运行结果
说明:!!!!!
这段代码并不适合所有编译器,还有部分编译器会报错,但是不影响使用。
在这里插入图片描述

乍一看,代码就是一个主函数带一个更简单的函数。
函数实现的功能也只是简单的改变了主函数的参数。
可能有人要说了不是就传变量地址改变变量值嘛, 新手都知道的东西,这有啥?
但是请您先别急,可以再仔细看看代码。
调用函数的时候并没有给函数任何参数,而且函数内部就简简单单的定义一个整形数组。所以并不是通过常规方法改变的变量的值。
有些认真的读者读着程序可能发现了作者打印一个整形数组元素居然还用for循环。(这个东西后面再说)]
好了,认真读完程序,要是有一定汇编基础,在汇编层面找过函数栈空间的人可能已经知道怎么回事了。(那本篇文章可能不适合您)
要是您读完程序,感觉一头雾水或者有点一知半解,那么就请跟着作者一起来进入我们今天的主题————缓冲区溢出改变main函数变量值。
讲解其中涉及到的知识之前我们先概括的说明下它实现的原理 ——>通过被调函数的缓冲区溢出,取到主函数中EBP的值,再通过EBP的值来改变主函数中参数的值。

1. 首先在说缓冲区溢出前,我们先说说什么叫缓冲区?
其实对没有一点汇编基础人来说,这个概念挺难理解的,所以建议您可以去稍微了解一点汇编中栈的知识。
而对有汇编经验的人来说就简单啦,缓冲区就是栈顶指针(32位) ESP与EBP之间的那段栈空间嘛。
有汇编经验的人都知道栈有个特点——先进后出(先压入的栈的变量,后出栈),而且栈生长方向是从高地址向低地址(栈生长方向可以简单理解为压栈顺序)。
而且同一行变量,入栈顺序一般是从右向左,这也一定程度上解释了,一般数组中下标大的元素比下标小的元素先入栈(知道这点非常重要)。
2. 知道啦缓冲区是什么,我们还需要知道一点与缓冲区溢出相关的汇编知识(读者要是已经很了解了,可以跳过)
①调用函数的在汇编层面的解释就是 call +函数的地址, 而且call指令执行时会把call指令后面的那条指令的地址压入栈。
如何利用这个知识点(请关注我接下来的第二篇文章——利用缓冲区溢出执行任意内存空间处指令。)
②call指令执行后会改变寄存器EIP(指向要执行的指令)和ESP的值(因为有东西被压入栈了),后面寄存器的操作就是——>EBP入栈——>EBP =ESP——>ESP减去一个16进制数(提升栈空间)——>一些重要寄存器入栈。现在的ESP与EBP之间的空间就是缓冲区了,也就是被调用函数中定义的局部变量待的地方。而且一般来说最后一个局部变量是在压入栈的EBP的上面一个的(EBP-4)有的是(EBP-8)。
——————————————未完待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值