【发布时间】:2022-11-02 14:56:22
【问题描述】:
我的目标是编写一个类似金丝雀的机制来检测字符缓冲区中的溢出。我想要做的是获取缓冲区末尾的地址并在那里放置一个金丝雀,这样写入缓冲区会导致金丝雀值发生变化。经过一番调试,我发现一个问题是当我向地址写入值时,地址本身的值发生了意外的变化。谁能解释为什么会这样?
例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(int argc, char *argv[])
{
srand(time(NULL));
int secret = rand();
char buf[8];
char *aft_buf = buf + 8;
printf("aft buf address = %p\n", aft_buf);
int *canary = (int *) aft_buf;
*canary = secret;
printf("canary address = %p\n", canary); // this value becomes different from aft_buf. why?
return 0;
}
我正在用gcc -fno-stack-protector 编译,当我用-O2 标志编译时我没有遇到这个问题。
【问题讨论】:
-
您正在调用未定义的行为。
aft_buf在buf之后保留过去的地址,并且在法律上不可取消引用。将其转换为int *(或任何东西,就此而言),并取消引用写入int值是明确的 UB。 -
您的程序有缓冲区溢出和未定义的行为。
-
*canary = secret;你想哪里,你写到这里了?是什么让你认为你可能被允许这样做?如果你做了你不被允许的事情,你必须承担后果。