为何手动输入与Python脚本生成输入在缓冲区溢出测试中结果不同?
缓冲区溢出测试中不同输入方式导致崩溃地址差异的原因
测试代码
#include <stdio.h> #include <string.h> int main(int argc, char** argv){ char buffer[10]; strcpy(buffer, argv[1]); return 0; }
两种测试场景及结果
场景1:直接通过gdb传递命令行参数
执行命令:
run AAAAAAAAAAAAAAAAAAAA
崩溃输出:
Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? ()
场景2:通过文件或Python脚本传递输入
执行命令示例1:
run < attack.txt
执行命令示例2:
run <<< $(python -c 'print("\x41"*20)')
崩溃输出:
(gdb) run < attack.txt Program received signal SIGSEGV, Segmentation fault. 0x08055718 in __strcpy_sse2 ()
差异原因
核心区别:输入的传递路径完全不同
场景1的逻辑:
该方式下,20个A是作为程序的**命令行参数(argv[1])**传入的。strcpy将这个字符串复制到长度仅为10的buffer中,发生缓冲区溢出后直接覆盖了栈上的函数返回地址(EIP/RIP)。当main函数执行return时,CPU尝试跳转到被覆盖为0x41414141的地址,触发段错误。场景2的逻辑:
用<或<<<传递的内容是发送到程序的标准输入(stdin),但你的代码完全没有读取stdin的逻辑——此时argv[1]是空值(NULL指针)。strcpy(buffer, argv[1])相当于把NULL作为源地址传入,strcpy的底层实现__strcpy_sse2在尝试读取NULL指向的内存时直接触发段错误,因此崩溃地址停在__strcpy_sse2的执行位置,而非被覆盖的返回地址。
简单来说:两种输入方式的内容根本没传到同一个地方,场景2的输入完全没被程序处理,反而让strcpy操作了非法的NULL指针。
内容的提问来源于stack exchange,提问作者r3k0j
相关产品推荐
相关产品推荐

