将 expression 转换为数据类型 int 时出现算术溢出错误_整数溢出错误

当程序尝试存储对于声明的整数类型而言太大的整数值时,将发生整数溢出。这是一种算术溢出错误,不仅会导致错误的结果和系统不稳定,还会导致缓冲区溢出,并为攻击者提供了切入点。让我们看看为什么可能发生整数溢出错误,它们怎么可能很危险,以及如何防止它们。

6522e6f28468aed591fb57cc3e13fa70.png

为什么发生整数溢出

在最基本的级别上,当算术运算的结果需要比目标变量更多的位时,将发生整数溢出。例如,您可以存储在32位无符号整数变量中的最大数字是4,294,967,295。用十六进制表示是0xFFFFFFFF,在这里您可以清楚地看到所有字节已经具有最大值(即,所有32位都已设置)。如果您有一个计算得出的数字较大,则结果的所有位都不适合该数据类型的32位可用,并且会出现溢出。

整数溢出情况下的行为取决于硬件,编译器和编程语言。在大多数现代系统中,该值实际上并不会溢出到相邻的存储位中,而是使用模运算将其包裹或截断以适合该变量。

对于无符号整数,这通常意味着保留最低有效位(对于32位,这将是十进制值的最后10位),实际上将结果环绕在零附近。例如,如果您有一个带有最大值的32位整数(无符号)并将其递增42,则可能会得到4,294,967,295 + 42 =41。在某些专用硬件(例如信号处理器)中,没有环绕或截断在这些情况下–最大值仅限于最大可表示的正数。

对于有符号整数类型,由于以二进制表示负数的方式,事情变得更加奇怪。因为有符号整数的最左位仅对于负数为1,所以当正值溢出时,它实际上可能变为负数。如果负值变得小于当前有符号类型的最小值,则会出现下溢–负值上溢。

攻击者如何利用整数溢出

由于它们的不确定行为,众所周知,整数上溢和下溢错误很难调试。它们往往发生在非常特定的情况下,并且可能会静默地返回不正确的结果,尤其是在与签名错误结合时。例如,计数器变量可以初始化为-1,并在每次读取之前递增,这在理论上意味着它应始终为0或正值。如果出现问题,并且计数器仍为负数时将其强制转换为无符号整数,则您可能会得到一个从4,294,967,295向下计数而不是从0向上计数的计数器。

根据使用结果的位置,这种错误的计算可能导致从奇怪的错误消息到航天器坠毁的任何事情。但是,除了直接后果外,整数溢出还可以为攻击提供起点。如果将来自用户输入的整数用作缓冲区大小,则攻击者可能能够操纵这些值以导致缓冲区溢出,从而可能导致任意代码执行。此类漏洞通常涉及直接在内存缓冲区上运行的C / C ++程序。

防止整数溢出情况

因为整数溢出仅发生在有效代码中的特定操作数值上,所以防止它们发生的唯一可靠方法是对理论上可能会出现溢出值的每个整数操作使用溢出检查或值完整性测试。您可以为此使用内置的编译器函数或外部库。

使用适当的大整数类型也很重要,特别是如果将操纵大数的话。在Python之类的编程语言中,数字变量的内部类型会自动调整以匹配它们的值,从而防止了基本整数溢出。

4ee8cde0f5cc1a1dbfe3d8e22e0e9269.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值