我有这个示例程序,当使用fstack-protector-all编译时会产生堆栈粉碎。
#include <stdio.h>
#include <stdint.h>
int func(int* value)
{
uint8_t port = 1;
*value = port; //Canary value changes at this point when seen in GDB
return 1;
}
int main()
{
uint16_t index = 0;
int ret = func((int*)&index);
}
我不明白这条线有什么问题。是否需要进行类型转换?
答案 0 :(得分:6)
这是因为int
的大小和int16_t
的大小不同。 int
的大小(通常)是32位(四个字节),而int16_t
是16位(两个字节)。
因此,当您将int
写入int16_t
变量时,您会写两个字节太多,并导致undefined behavior(在这种情况下,&#34;粉碎&#34;堆栈)。
问题更具体是因为您使用指向index
的指针调用该函数,该指针是一个16位变量,但该函数需要(并使用其参数)作为32位变量。你不应该在通话中进行演员,因为隐藏了问题但没有解决它。您只需将8位值写入函数内的解除引用指针并不重要,目标仍然是32位变量,编译器将之前将8位值转换为32位值写给记忆。
答案 1 :(得分:2)
由于index
的类型为uint16_t
,因此只为其分配了16位。通过将index
的地址转换为int*
,您假装在大多数情况下可以访问超过16位--32位。
在
*value = port;
您正尝试在尚未分配的位中设置值。由于在该行中使用了未经授权的内存,因此任何事情都可能发生。