如何使用C中的指针检测缓冲区溢出



我正在研究缓冲区溢出,到目前为止,我已经看到了许多使用数组的例子,但我对以下代码有一个问题:

void foo(){
struct {
char a[4];
char b[16];
char *p;
} s;
scanf("%s", s.p);
printf("flag: %s", s.p);
}
int main(){
foo();
}

s.p为参数的scanf是否会导致缓冲区溢出?如果是,我将如何预测在scanf中写入的字符串的保存位置(以及为了覆盖已保存的指令指针并使该漏洞发挥作用,我必须写多少?(。

我已经用gdb分析了代码,我可以看到在scanf中插入的字符串从数组a[]的位置开始覆盖,但我不知道这种情况是否总是发生,或者字符串是否保存在";"随机";位置

A"缓冲区溢出";意味着你正在写一个已经属于你的数组的末尾,并痛击它后面的任何东西

您询问的问题不同,因为s.p的初始值是不确定的-它可能根本不对应于可写地址,在这种情况下,您(很可能(会触发segfault。这并不是缓冲区溢出,而是试图访问进程空间中的随机地址。指针值无效(意味着在程序中对象的生存期内它不会指向该对象(,但没有(好的、标准的、可移植的(方法来判断非NULL指针值是否有效。

就像在数组末尾写入一样,试图通过无效指针读取或写入的行为是未定义的,这意味着编译器和运行时环境都不需要以任何特定的方式处理它。行为不能保证是可预测的或可重复的;它甚至可以在同一环境中运行同一个二进制文件(尽管在实践中往往是一致的(。如果你什么都不吃"重要";您的代码执行时不会出现明显的问题。

由于这个原因,几乎不可能检测到缓冲区溢出或事后通过无效指针进行写入或从中恢复。您的时间最好花在上,防止缓冲区溢出和通过无效指针进行写入。