c - C中自发的缓冲区溢出
问题描述
我想知道是否有可能以编程方式生成缓冲区溢出,我的意思是,无需任何用户输入。
我一直在尝试使用该memcpy
函数导致缓冲区溢出,将缓冲区的内容复制到另一个较小的缓冲区中。现在,分段错误仅在源缓冲区初始化时触发,如下所示:
char * overflow = "\x40\40\x40...";
或者:
char * overflow = {"\x40\40\x40..."};
如果我将此缓冲区复制到另一个较小的变量中,它会成功溢出。但是这种声明使源缓冲区只读,所以我想知道是否可以动态生成缓冲区的内容,例如,程序可以在运行时生成一个缓冲区,可以将指令指针重定向到某个内存地址也在运行时计算。所以我尝试将其更改为:
char overflow[] = {"\x40\x40\x40\x40..."}
但是,由于某种我不太了解的原因,无论缓冲区有多长,此声明都不会触发分段错误。
为什么只读常量字符串可以触发缓冲区溢出,而变量不能?
这是我正在使用的代码:
int WINAPI mainCRTStartup(){
char buffer[100];
char * overflow = { "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x64\x63\x62\x61\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
};
printf("Ready:\n");
// 117
memcpy(buffer, overflow, 117);
//strcpy(buffer, overflow);
printf("String: %s\n", buffer);
return 0;
}
我编译它:
i686-w64-mingw32-gcc -O2 -s -DNDEBUG -static \
-nostdlib -m32 \
-o deleteme.exe deleteme.c \
-lkernel32 -lmsvcrt -fno-stack-protector
此代码成功地将指令指针设置为地址 0x61626364。
我知道这可能没有任何实际用途,我只是对这种行为感到好奇。
解决方案
当您使用char overflow[]
时,数组的内存与overflow
位于同一堆栈帧中buffer
,并且它可能位于它之后。因此,当您超出 的范围时buffer
,您将回写到overflow
,而不是覆盖堆栈帧中的返回地址字段。
制作它static char overflow[]
,或制作overflow
一个全局变量。然后它不会在堆栈帧中。您也可以尝试更改两个变量声明的顺序。
推荐阅读
- c++ - 使用 CMake (make) 和 GCC 构建和编译 gSOAP 项目
- python - 如何创建带有时间戳的“签入/签出”系统?
- angular - 本地主机上的“访问控制允许来源”
- r - 如何在R中的距离矩阵中找到最小值?我的方法不起作用
- json - 在 json 中没有嵌套数组的散列到 json
- python - 正确关闭函数调用后使用的 Tkinter
- typescript - 为@typescript-eslint/parser 设置了“parserOptions.project”
- angular - ads.txt 应该放在 Angular 8 SSR 中的什么位置?
- awk - awk 将匹配的字段更改为另一个
- r - 通过 Shinyapps.io 连接到 MongoDB Atlas