Skip to content

Integer Overflow, 整数溢出

复制本地路径 | 在线编辑

当程序中的数据超过其数据类型的范围,则会造成溢出,整数类型的溢出被称为整数溢出。

汇编代码表现(Important!)

上界溢出. 下届溢出的道理和上界溢出一样,在汇编代码中,只是把 add 替换成了 sub。

# 伪代码
short int a;
a = a + 1;

# 对应的汇编
movzx  eax, word ptr [rbp - 0x1c]
add    eax, 1
mov    word ptr [rbp - 0x1c], ax

# 伪代码
unsigned short int b;
b = b + 1;

# 对应的汇编
add    word ptr [rbp - 0x1a], 1

分析

因为计算机底层指令是不区分有符号和无符号的,数据都是以二进制形式存在 (编译器的层面才对有符号和无符号进行区分,产生不同的汇编指令)。

上界溢出有两种情况

  • 情况一: add 0x7fff, 1 == 0x8000,在有符号短整型中,0x7fff 表示的是 32767,但是 0x8000 表示的是 -32768,用数学表达式来表示就是在有符号短整型中 32767+1 == -32768

  • 情况二: add 0xffff, 1 == 0x10000, 无符号的汇编代码是对内存进行加法运算 add word ptr [rbp - 0x1a], 1 == 0x0000。在有符号的加法中,虽然 eax 的结果为 0x10000,但是只把 ax=0x0000 的值储存到了内存中,从结果看和无符号是一样的, 结果表现成为 0xffff == 65535, 65535 + 1 == 0

下界溢出一样也是有两种情况:

  • 情况一: sub 0x0000, 1 == 0xffff, 对于有符号来说 0 - 1 == -1 没问题,但是对于无符号来说就成了 0 - 1 == 65535。
  • 情况二: sub 0x8000, 1 == 0x7fff, 对于无符号来说是 32768 - 1 == 32767 是正确的,但是对于有符号来说就变成了 -32768 - 1 = 32767。

分类

未限制范围( 负数 )

负数会导致无符号数转成过大数字, 对于有符号数, 也要注意负数可能在之后的结构带来的危险.

$ cat test.c
#include<stddef.h>
int main(void)
{
    int len;
    int data_len;
    int header_len;
    char *buf;

    header_len = 0x10;
    scanf("%uld", &data_len);

    len = data_len+header_len
    buf = malloc(len);
    read(0, buf, data_len);
    return 0;
}
$ gcc test.c
$ ./a.out
-1
asdfasfasdfasdfafasfasfasdfasdf
# gdb a.out
► 0x40066d <main+71>    call   malloc@plt <0x400500>
        size: 0xf

只申请 0x20 大小的堆,但是却能输入 0xffffffff 长度的数据,从整型溢出到堆溢出

范围大的变量赋值给范围小的变量

$ cat test2.c
void check(int n)
{
    if (!n)
        printf("vuln");
    else
        printf("OK");
}

int main(void)
{
    long int a;

    scanf("%ld", &a);
    if (a == 0)
        printf("Bad");
    else
        check(a);
    return 0;
}
$ gcc test2.c
$ ./a.out
4294967296
vuln

上述代码就是一个范围大的变量 (长整型 a),传入 check 函数后变为范围小的变量 (整型变量 n),造成整数溢出的例子。

已经长整型的占有 8 byte 的内存空间,而整型只有 4 byte 的内存空间,所以当 long → int,将会造成截断,只把长整型的低 4byte 的值传给整型变量。

在上述例子中,就是把 long: 0x100000000 -> int: 0x00000000

但是当范围更小的变量就能完全的把值传递给范围更大的变量,而不会造成数据丢失。

Comments