IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> x8632位中为什么要做栈平衡。 -> 正文阅读

[C++知识库]x8632位中为什么要做栈平衡。

在32位中是通过栈进行参数传递,正常函数的调用,栈中要先压入返回地址,再压入ebp。但通过溢出执行相关函数时,只压入ebp,并不压入返回地址,因此函数正常返回时,先后执行,leave,ret,就会多出栈一次,因此,需要做栈平衡

正常调用溢出调用
leave(mov esp,ebp;pop ebp)ebpebp
ret(pop eip)返回地址栈平衡
esp

通过代码调试代码如下:

#include <stdio.h>
int add(int a,int b,int c)
{
        int sum;
        sum=a+b+c;
}
void main()
{
// char t[32];
// scanf("%s",t);
//printf("%s\n",t);
int a=1,b=2,c=3;
int sum;
sum=add(1,2,3);
printf("sum=%d\n",sum);
}

gcc编译后,通过gdb调试

 EBP  0xffffd5bc —? 0xffffd5e8 ?— 0x0
 ESP  0xffffd5bc —? 0xffffd5e8 ?— 0x0
 EIP  0x804840e (add+3) ?— sub    esp, 0x10
─────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────
   0x8048421 <add+22>    nop    
   0x8048422 <add+23>    leave  
   0x8048423 <add+24>    ret    
    ↓
   0x804840b <add>       push   ebp
   0x804840c <add+1>     mov    ebp, esp
 ? 0x804840e <add+3>     sub    esp, 0x10
   0x8048411 <add+6>     mov    edx, dword ptr [ebp + 8]
   0x8048414 <add+9>     mov    eax, dword ptr [ebp + 0xc]
   0x8048417 <add+12>    add    edx, eax
   0x8048419 <add+14>    mov    eax, dword ptr [ebp + 0x10]
   0x804841c <add+17>    add    eax, edx
──────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────
00:0000│ ebp esp  0xffffd5bc —? 0xffffd5e8 ?— 0x0
01:0004│          0xffffd5c0 —? 0x8048455 (main+49) ?— add    esp, 0xc
02:0008│          0xffffd5c4 ?— 0x1
03:000c│          0xffffd5c8 ?— 0x2
04:0010│          0xffffd5cc ?— 0x3
05:0014│          0xffffd5d0 ?— 0x1
06:0018│          0xffffd5d4 ?— 0x2
07:001c│          0xffffd5d8 ?— 0x3

进入add函数后,如上所示,add函数的地址为0x804840b,在栈中压入了,返回地址与ebp

00:0000│ ebp esp  0xffffd5bc —? 0xffffd5e8 ?— 0x0
01:0004│          0xffffd5c0 —? 0x8048455 (main+49) ?— add    esp, 0xc

修改栈顶为“aaaa”,返回地址为add函数的地址,在此次add函数结束后,再次调用add函数,如下所示:

00:0000│ ebp esp  0xffffd5bc —? 0x804b008 ?— 'aaaa'
01:0004│          0xffffd5c0 —? 0x804840b (add) ?— push   ebp
02:0008│          0xffffd5c4 ?— 0x1
03:000c│          0xffffd5c8 ?— 0x2
04:0010│          0xffffd5cc ?— 0x3
05:0014│          0xffffd5d0 ?— 0x1
06:0018│          0xffffd5d4 ?— 0x2
07:001c│          0xffffd5d8 ?— 0x3

等再次进入add函数如下所示,没有压入返回地址

EBP  0x804b008 ?— 'aaaa'
 ESP  0xffffd5c4 ?— 0x1
 EIP  0x804840b (add) ?— push   ebp
─────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────
   0x804841c <add+17>    add    eax, edx
   0x804841e <add+19>    mov    dword ptr [ebp - 4], eax
   0x8048421 <add+22>    nop    
   0x8048422 <add+23>    leave  
   0x8048423 <add+24>    ret    
    ↓
 ? 0x804840b <add>       push   ebp
   0x804840c <add+1>     mov    ebp, esp
   0x804840e <add+3>     sub    esp, 0x10
   0x8048411 <add+6>     mov    edx, dword ptr [ebp + 8]
   0x8048414 <add+9>     mov    eax, dword ptr [ebp + 0xc]
   0x8048417 <add+12>    add    edx, eax
──────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────
00:0000│ esp  0xffffd5c4 ?— 0x1
01:0004│      0xffffd5c8 ?— 0x2
02:0008│      0xffffd5cc ?— 0x3
03:000c│      0xffffd5d0 ?— 0x1
04:0010│      0xffffd5d4 ?— 0x2
05:0014│      0xffffd5d8 ?— 0x3
06:0018│      0xffffd5dc —? 0x80484a1 (__libc_csu_init+33) ?— lea    eax, [ebx - 0xf8]
07:001c│      0xffffd5e0 —? 0xf7fb43dc (__exit_funcs) —? 0xf7fb51e0 (initial) ?— 0x0

继续执行,压入ebp

EBP  0xffffd5c0 —? 0x804b008 ?— 'aaaa'
 ESP  0xffffd5c0 —? 0x804b008 ?— 'aaaa'
 EIP  0x804840e (add+3) ?— sub    esp, 0x10
─────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────
   0x8048421 <add+22>    nop    
   0x8048422 <add+23>    leave  
   0x8048423 <add+24>    ret    
    ↓
   0x804840b <add>       push   ebp
   0x804840c <add+1>     mov    ebp, esp
 ? 0x804840e <add+3>     sub    esp, 0x10
   0x8048411 <add+6>     mov    edx, dword ptr [ebp + 8]
   0x8048414 <add+9>     mov    eax, dword ptr [ebp + 0xc]
   0x8048417 <add+12>    add    edx, eax
   0x8048419 <add+14>    mov    eax, dword ptr [ebp + 0x10]
   0x804841c <add+17>    add    eax, edx
──────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────
00:0000│ ebp esp  0xffffd5c0 —? 0x804b008 ?— 'aaaa'
stack
01:0004│          0xffffd5c4 ?— 0x1
02:0008│          0xffffd5c8 ?— 0x2
03:000c│          0xffffd5cc ?— 0x3
04:0010│          0xffffd5d0 ?— 0x1
05:0014│          0xffffd5d4 ?— 0x2
06:0018│          0xffffd5d8 ?— 0x3
07:001c│          0xffffd5dc —? 0x80484a1 (__libc_csu_init+33) ?— lea    eax, [ebx - 0xf8]

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-31 23:45:54  更:2022-03-31 23:47:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:08:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码