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

利用Buffer Overflow调用未触发函数的可行性及地址查找技术咨询

缓冲区溢出POC相关问题

我计划出于演示/教育目的编写一个简单的概念验证(POC)程序,利用缓冲区溢出执行程序中未被正常调用的代码。初始代码如下:

#include <iostream>
#include <cstring>

void vulnerableFunction(const char* input) {
    char buffer[10];  
    strcpy(buffer, input);
}

void printSomething(){
 std::cout << "This should not be executed" << std::endl;
}

int main() {
    const char* input = "This is a long string that will cause a buffer overflow";
    vulnerableFunction(input);
    return 0;
}

我希望通过输入字符串覆盖EIP寄存器,将其指向printSomething()函数的内存地址以执行该函数。现咨询两个问题:

  1. 这种实现方式是否可行?
  2. 我已使用Immunity Debugger分析程序,能够构造字符串精确覆盖EIP且已知偏移量,但尚未找到printSomething()函数的精确内存地址,请问有哪些方法可以获取该地址?

一、实现方式是否可行

这种实现可行,但需要满足几个前提条件:

  • 关闭地址空间布局随机化(ASLR):如果系统开启了ASLR,函数地址会每次运行随机变化,无法固定指向printSomething。
  • 禁用栈保护(Stack Canary):现代编译器默认会开启栈保护机制,检测到栈溢出时会终止程序,编译时需关闭该选项(比如GCC用-fno-stack-protector参数)。
  • 使用32位编译:EIP是32位x86架构的指令指针寄存器,64位架构对应的是RIP,若用64位编译,溢出逻辑和寄存器操作会完全不同。
  • 关闭编译器优化:避免编译器将未被调用的printSomething函数优化掉(比如GCC用-O0参数),同时确保栈布局符合预期。
  • 允许栈执行(可选):部分系统默认禁止栈上代码执行,编译时添加-z execstack参数可避免意外问题(本场景是跳转到已存在的函数,并非执行栈上代码,这一步非强制)。

满足以上条件后,构造足够长的输入字符串覆盖栈上的EIP值为printSomething的地址,即可让程序执行该函数。

二、获取printSomething函数内存地址的方法

1. 在Immunity Debugger中直接查找

  • 打开程序后按下Ctrl+G,在弹出窗口中输入printSomething,直接跳转到函数起始地址;
  • 如果函数名无法直接搜索,可在反汇编窗口中查找x86函数的特征开头指令(比如push ebp; mov ebp, esp),结合函数内的cout调用特征定位地址。

2. 利用编译工具的符号表

  • 编译时添加调试信息(GCC用-g参数),用GDB调试:启动GDB后输入info functions,在列表中找到printSomething对应的地址;
  • 用nm命令查看可执行文件符号表:执行nm <你的程序文件名> | grep printSomething,直接输出函数地址。

3. 反汇编工具分析

  • 使用IDA Pro、Ghidra等反汇编工具打开程序,在函数列表中直接找到printSomething,查看其起始地址;
  • 这类工具会自动识别函数边界和符号,定位过程更直观。

4. 临时修改代码打印地址

  • 在main函数中添加一行代码:std::cout << (void*)&printSomething << std::endl;;
  • 编译运行程序,直接输出printSomething的内存地址,之后删除该行代码重新编译用于溢出测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:37:25