目录
0x01.整型在计算机系统中的相关知识
- 在计算机中,整数类型分为无符号整数和有符号整数 两种。
- 有符号整数会在最高位用0表示正数,1表示负 数,而无符号整数则没有这种规则。因为计算机只认得二进制,认不得符号。
- 无符号的汇编代码是对内存进行加法运算.
- 在计算机中,整数以补码形式存储,正数的补码与原 码一致,负数的补码等于原码按位取反+1 。
- 在C语言中,各种整型数据类型的范围如下:
数据类型 | 所占字节 | 取值范围 |
short int | 2byte(word) | 0~32767(0~0x7fff) -32768~-1(0x8000~0xffff) |
unsigned short int | 2byte(word) | 0~65535(0~0xffff) |
int | 4byte(dword) | 0~2147483647(0~0x7fffffff) -2147483648~-1(0x80000000~0xffffffff) |
unsigned int | 4byte(dword) | 0~4294967295(0~0xffffffff) |
long int | 8byte(qword) | 正: 0~0x7fffffffffffffff 负:0x8000000000000000~0xffffffffffffffff |
unsigned long int | 8byte(qword) | 0~0xffffffffffffffff |
-------------------------- | ------------------ | ---------------------------------------------------- |
char | 1 | -128-127 |
unsigned char | 1 | 0-255 |
- 当一个整数存入了比它本身小的存储空间中,超出了 数据类型所能表示的范围时,就会发生整数溢出。
- 当两个有符号整数比较大小时 ,是将两数作差,若结果为正则显示被减数大,若 结果为负则显示减数大。
- 当两个有符号整数作差时出现上溢或下溢时,比较 结果会与事实相反。
- 当两个有符号整数运算时,有可能发生上溢或者下溢。
- 当无符号整数和有符号整数进行比较或运算时,会将有符号整 数转化成无符号整数之后进行比较或运算,会导致上溢下溢以及与事实相反的结论。
0x02. 上界溢出和下界溢出
上界溢出:
- 一个整数通过运算(赋值),超过了它能 表示的上限,则会变成一个很小的数。
例如:
short int a;
a=0x7fff;//32767
a++;
//此时a=0x8000 也就是-32768 计算出现问题
a=0xffff;//-1
a++;
//此时a=0x10000 但是只保留了前16位,最高位丢失 a=0
//也可以这样看,a+5=4 ,从数字层面来看,计算没有问题
unsigned short int b;
b=0x7fff;//32767
b++;
//无影响,因为未达到边界
b=0xffff;//65535
b++;
//此时b=0,65535+1=0
- 有符号整型主要是达到32767后,继续相加变成负数。 无符号 32767+5=-32764
- 无符号整型主要是达到65535后,继续相加从0开始。 有符号 65535+5=4
- 都损失了数据。
下界溢出:
- 一个整数通过运算(赋值),低于它能表 示的下限,则会变成一个很大的数。
例如:
short int a;
a=0x0000;//0
a--;
//此时a=-1(0xffff) ,从数字层面看,计算没有问题
a=0x8000;//-32768
a--;
//此时a=32767,数字变大
unsigned shrot int b;
b=0x0000;//0
b--;
//此时b=65535,数字变大
b=0x8000;//32768
b--;
//此时b=32767,没有问题
- 有符号整型主要是到-32768后,继续相减变成很大的正数。 有符号 -32768-5=32763
- 无符号整型主要是到0后,继续相减百年城很大的整数。 无符号 0-5=65531
- 数据都发生了异常。
0x03.漏洞利用
- 当程序中的整型未限制范围,做了错误的数据类型强制转换,或只从单边限制了范围,均可以利用此漏洞改写数据。
- 具体参考实例。