您好我的一位朋友向我展示了这段代码,以便对数组/堆栈绑定检查提出一点意见。
#include <stdio.h>
void foo() {
unsigned long long a[1];
a[3] -= 5;
printf("Print me!\n");
}
int main(){
foo();
return 0;
}
当我运行此代码时,它会一直打印“打印我!\ n”,它不会停止。我用MingW 64bit编译代码。这里发生了什么事?我希望有人解释我,为什么它会不断打印文本。
答案 0 :(得分:3)
您通过命令a[3] -= 5;
损坏线程堆栈,因为将var更改为数组范围。这种行为完全不可预测,在其他系统上可能会有所不同。我想你只需修改堆栈上的返回地址来调用printf
如果您想了解 - 请使用反汇编程序。
答案 1 :(得分:1)
您正在foo()中更改堆栈框外的值。
具体来说,你是从返回地址中减去5(如果这是正常的x86-32调用约定)
如果main中的foo()调用编译成类似
的内容 call ebp-126
(调用短偏移量)指令长度为5个字节。
因此,返回将转到呼叫,而不是呼叫之后。呼叫将再次执行。
这与代码获得的反可移植和未定义一样,因为它依赖于调用约定和编译器发出的特定指令。
答案 2 :(得分:0)
看起来可能是stack buffer overflow。
您正在引用堆栈数组a
中的未定义索引。这可能会覆盖堆栈上的返回地址。
当函数return
到main
函数时,它很可能再次执行foo
,因为返回地址可能被设置为调用函数之前的值。 - 5
操作。