void display(const char *path)
{
char msg[128];
int8_t size;
memset(msg, 0, 128);
FILE *file = fopen(path, "r");
size_t n = fread(&size, 1, 1, file);
if (n == 0 || size > 128)
return;
n = fread(msg, 1, size, file);
puts(msg);
}
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;
display(argv[1]);
return 0;
}
我怎么能让这个缓冲区溢出?我的意思是,缓冲区是128个字节。但是,如果大小超过128,代码是否会检查?如果是,那么它只会提前返回,如果没有,它只会将少于128个字节从文件复制到msg?
答案 0 :(得分:0)
int8_t size;
是一个8位有符号值,因此它落在[-128,127]范围内。
执行此代码时:
size_t n = fread(&size, 1, 1, file);
if (n == 0 || size > 128)
return;
如果size有最高位设置(即size> = 0x80),那么它被处理为负数,从而逃避/避免检查。
假设代码读取的值大小为0x8F(十进制为143),但由于int8_t类型的大小为8位且值范围为[-128,127],因此设置最高位并且表示有符号值,表示值为-113。
因此size
(n == 0 || size > 128)
的{{1}}小于128,因为-113 > 128
为假。
这意味着代码将读取比数组大小更多的字节。它将读取143个字节但数组大小仅为128,从而触发基于堆栈的缓冲区溢出。