我怎么能让这个缓冲区溢出?
How could I make this buffer overflow?
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?如果是,那么它会提早 return,如果不是,它只会从文件复制不到 128 个字节到 msg?
int8_t size;
是一个 8 位有符号值,因此它落在 [-128,127].
范围内
执行此代码时:
size_t n = fread(&size, 1, 1, file);
if (n == 0 || size > 128)
return;
如果 size 设置了最高有效位(即 size >= 0x80),则它被视为负数,因此 escaping/avoiding 检查。
假设代码读取值为 0x8F 的大小(十进制为 143),但由于 int8_t 类型的大小为 8 位,取值范围为 [-128,127],因此最高有效位已设置并指示有符号值,这意味着该值为 -113。
因此 size
在 (n == 0 || size > 128)
中小于 128 仅仅是因为 -113 > 128
是假的。
这意味着代码将读取比数组大小更多的字节。它将读取 143 个字节,但数组大小仅为 128,从而触发基于堆栈的缓冲区溢出。
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?如果是,那么它会提早 return,如果不是,它只会从文件复制不到 128 个字节到 msg?
int8_t size;
是一个 8 位有符号值,因此它落在 [-128,127].
执行此代码时:
size_t n = fread(&size, 1, 1, file);
if (n == 0 || size > 128)
return;
如果 size 设置了最高有效位(即 size >= 0x80),则它被视为负数,因此 escaping/avoiding 检查。
假设代码读取值为 0x8F 的大小(十进制为 143),但由于 int8_t 类型的大小为 8 位,取值范围为 [-128,127],因此最高有效位已设置并指示有符号值,这意味着该值为 -113。
因此 size
在 (n == 0 || size > 128)
中小于 128 仅仅是因为 -113 > 128
是假的。
这意味着代码将读取比数组大小更多的字节。它将读取 143 个字节,但数组大小仅为 128,从而触发基于堆栈的缓冲区溢出。