我有一个函数可以更改堆栈检查守卫的值。
此函数使用 -fstack-protector-all
编译。
这意味着将在此函数内部生成堆栈检查操作。这段添加的代码会将开始时的堆栈检查值保存到堆栈中,并在函数结束时检查保存的值。但我们正在改变值(value)。这就是为什么,我预计会产生堆栈粉碎。
unsigned long __stack_chk_guard = 0;
void change___stack_chk_guard()
{
__stack_chk_guard = 1234;
}
int main()
{
change___stack_chk_guard();
return 0;
}
那么,我可以像这样初始化__stack_chk_guard
吗?
最佳答案
首先,使用指定语言的正式回答:否。标识符 __stack_chk_guard
位于保留命名空间中,这意味着如果您使用它,您的程序将具有未定义的行为。 (它被保留是准确地使它有效的实现,以在实现堆栈保护器等功能时使用它。)
其次,技术/机械答案:否,对于使用外部标识符 __stack_chk_guard
作为其堆栈保护器实现的一部分的目标。 stack protector 的全部工作是验证函数返回时的 stack canary 是否与函数入口处存储的值相同,该值来自(取决于目标)__stack_chk_guard
或来自线程本地存储中的匿名位置。如果你在一个函数的生命周期中改变了__stack_chk_guard
,那么入口处的值必然与返回时执行比较时的值不同,堆栈保护器将触发并终止程序,就像堆栈已被粉碎。
您的测试程序没有崩溃的可能原因是 x86[_64] 是一个不再使用 __stack_chk_guard
的目标;相反,它使用更高效的基于 TLS 的变体。如果您使用的是 gcc,则可以使用 -mstack-protector-guard=global
进行编译以获得过时的行为,并且您的程序应该会按预期崩溃。
关于c - 在 C 函数中更改 __stack_chk_guard 是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57607638/