怎么能让这个缓冲区溢出?

时间:2021-01-14 05:03:03
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;
}

How could I make this buffer overflow? I mean, the buffer is 128 bytes. But doesn't the code check if size is greater than 128? If it is, then it will just return early, and if not, it will only copy less than 128 bytes from file to msg?

怎么能让这个缓冲区溢出?我的意思是,缓冲区是128个字节。但代码是否检查大小是否大于128?如果是,那么它只会提前返回,如果没有,它只会从文件复制少于128个字节到msg?

1 个解决方案

#1


0  

int8_t size; is a 8-bit signed value, thus it falls in the range [-128,127].

int8_t大小;是一个8位有符号值,因此它落在[-128,127]范围内。

When this code is executed :

执行此代码时:

  size_t n = fread(&size, 1, 1, file);
  if (n == 0 || size > 128)
    return;

If size has is most significant bit set (that is size is >= 0x80), then it is treated has a negative number, thus escaping/avoiding the check.

如果size具有最高位设置(即大小> = 0x80),则它被处理为具有负数,从而逃避/避免检查。

Let say the code reads size with a value of 0x8F (this is 143 in decimal), but as the int8_t type has a size of 8 bits and a value range of [-128,127], the most significant bit is set and indicates a signed value, which means the value is -113.

假设代码读取大小的值为0x8F(十进制为143),但由于int8_t类型的大小为8位且值范围为[-128,127],因此设置最高位并指示已签名value,表示值为-113。

Thus size is less than 128 in (n == 0 || size > 128) simply because -113 > 128 is false.

因此,大小小于128 in(n == 0 || size> 128),因为-113> 128为假。

Which means the code will read more bytes than the size of the array. It will read 143 bytes but the array size is only 128, thus triggering a stack based buffer overflow.

这意味着代码将读取比数组大小更多的字节。它将读取143个字节但数组大小仅为128,从而触发基于堆栈的缓冲区溢出。

#1


0  

int8_t size; is a 8-bit signed value, thus it falls in the range [-128,127].

int8_t大小;是一个8位有符号值,因此它落在[-128,127]范围内。

When this code is executed :

执行此代码时:

  size_t n = fread(&size, 1, 1, file);
  if (n == 0 || size > 128)
    return;

If size has is most significant bit set (that is size is >= 0x80), then it is treated has a negative number, thus escaping/avoiding the check.

如果size具有最高位设置(即大小> = 0x80),则它被处理为具有负数,从而逃避/避免检查。

Let say the code reads size with a value of 0x8F (this is 143 in decimal), but as the int8_t type has a size of 8 bits and a value range of [-128,127], the most significant bit is set and indicates a signed value, which means the value is -113.

假设代码读取大小的值为0x8F(十进制为143),但由于int8_t类型的大小为8位且值范围为[-128,127],因此设置最高位并指示已签名value,表示值为-113。

Thus size is less than 128 in (n == 0 || size > 128) simply because -113 > 128 is false.

因此,大小小于128 in(n == 0 || size> 128),因为-113> 128为假。

Which means the code will read more bytes than the size of the array. It will read 143 bytes but the array size is only 128, thus triggering a stack based buffer overflow.

这意味着代码将读取比数组大小更多的字节。它将读取143个字节但数组大小仅为128,从而触发基于堆栈的缓冲区溢出。