C 我在腐蚀哪个回信地址?
我有一个非常简单的学习堆栈溢出的程序C 我在腐蚀哪个回信地址?,c,stack-overflow,C,Stack Overflow,我有一个非常简单的学习堆栈溢出的程序 #include <stdio.h> #include <string.h> int main(int argc, char **argv) { char buf[128]; if(argc < 2) return 1; strcpy(buf, argv[1]); printf("Hello\n"); return 0; } #包括 #包括 int main(int argc,字符**argv)
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char buf[128];
if(argc < 2) return 1;
strcpy(buf, argv[1]);
printf("Hello\n");
return 0;
}
#包括
#包括
int main(int argc,字符**argv){
char-buf[128];
如果(argc<2)返回1;
strcpy(buf,argv[1]);
printf(“Hello\n”);
返回0;
}
策略是在argv[1]中提供大字符串以溢出buf并覆盖返回地址。但是哪一个回信地址?我想这是我输入strcpy之前保存的地址,所以当我们从strcpy正常返回时,我们将执行printf
但是,在我使用外壳代码有效负载溢出缓冲区后,我将此返回地址更改为我的外壳代码。我看到printf仍在执行。即使我再添加几个printf,它们都将被执行。显然,我更改的返回地址只影响主函数的返回,否则我甚至不应该看到正在执行的printfs
为什么会发生这种情况?当我溢出缓冲区以更改外壳代码的返回地址时,主程序是否会直接跳转到外壳代码而不执行下一个printf?
buf
是函数的一个变量,因此它存在于堆栈上。缓冲区溢出将损坏堆栈当程序执行进入main
时,main
的返回地址位于堆栈上。接下来,为buf
分配128个字节。strcpy
调用的第二个参数长度超过128字节,它在为buf
分配的空间之外涂鸦,可能会损坏返回地址
接下来,将printf
的参数和返回地址(指向printf
之后的语句)推送到堆栈上,执行跳转到printf
函数。执行请求的打印后,返回地址从堆栈中弹出,并使用下一条语句继续执行
最后,返回0到达代码>语句。分配给堆栈上局部变量的空间被恢复,并且(损坏的)返回地址从堆栈弹出,执行“返回”到由用于损坏内存的字符串字节给定的损坏地址
简而言之,缓冲区溢出只能在堆栈上已经写入的信息(过去)上涂鸦。它不能在尚未写入堆栈(未来)的信息上涂鸦。这就是为什么损坏后的printf
调用仍然正确执行的原因;损坏的数据尚未使用
堆栈,在strcpy调用:
xxxx
xxxx
return address from strcpy
&buf (arg to strcpy)
argv[1] (arg to strcpy)
buf[0]
...
buf[127]
return address from main
argc (arg to main)
argv[0] (arg to main)
argv[1] (arg to main)
...
损坏发生在buf[127]
之后。strcpy
的返回未损坏
注意:堆栈上也可能没有“返回自strcpy
”;编译器可能已内联函数调用。在典型的PC上,堆栈向下增长。这意味着调用strcpy时堆栈的内存布局如下所示:
/^^^^更高的地址^^^
[材料]
[主要客户的回信地址]
[buf[127]]
[buf[126]]
...
[buf[1]]
[buf[0]]
[参数2(指向argv[1]的指针]]
[参数1(指向buf的指针)]
[strcpy的返回地址(指向main)]
[strcpy中的局部变量]
//下位地址
通过溢出
buf
(写入buf[128]
,buf[129]
,等等),您可以写入main
的调用帧(最重要的是,main
的返回地址)。你不能影响strcpy的调用帧,因为它在buf
之前存在于内存中。printf的地址从来都不在堆栈上,所以你怎么能覆盖它呢?@melpomene,我的意思是在调用strcpy之前,我保存返回地址。然后strcpy会破坏返回地址,因为我给出了一个大字符串。当strcpy返回时,它跳转到我的外壳代码,并且不应该执行printf。如果堆栈向下增长,你不能弄乱strcpy的堆栈帧,因为它在内存中的buf
之前。@melpomene,我明白你的意思了。巴夫住在梅因。如果你把它写下来作为答案,我会接受的。这是缓冲区溢出,不是堆栈溢出。这回答了与这个问题相关的问题吗?我的意思是,询问者显然知道堆栈将被损坏,这是一个关于损坏的特定问题。