我想知道是否有可能以编程方式生成缓冲区溢出,我的意思是,没有任何用户输入。
我一直在尝试使用该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
一个全局变量。那么它就不会在堆栈帧中。您也可以尝试更改两个变量声明的顺序。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句