游戏整数溢出原理
2026/6/11 10:44:29 网站建设 项目流程

目录

一、核心原理:int 等固定长度整数的 “容量有限”

二、正溢出(公式溢出 / 正式溢出)

例子(32 位 int)

三、负数溢出(下溢 / 反向溢出)

例子(32 位 int)

四、为什么游戏能被利用?(代码设计弱点)

五、一句话总结


先把名词对齐一下: 你说的公式溢出、负数溢出、正式溢出,在游戏开发里一般统称为整数溢出(Integer Overflow),其中:

  • 公式溢出:计算伤害、金币、经验等公式时,结果超出类型上限;
  • 负数溢出:数值向下溢出(小于类型最小值),或正溢出后变成负数;
  • 正式溢出:应该是 “正溢出(Positive Overflow)”,即超过正数上限。

它们本质都利用了同一个底层原理:固定位宽的整数类型用补码存储,超出范围会 “回绕”,且游戏代码默认不做溢出校验


一、核心原理:int 等固定长度整数的 “容量有限”

游戏里伤害、金币、属性、经验,大多用32 位有符号整数(int32)存储:

  • 范围:-2³¹ ~ 2³¹−1-2147483648 ~ 2147483647
  • 二进制:最高位是符号位(0 = 正,1 = 负)

可以想象成只有 10 位的里程表

  • 最大:9999999999
  • 再加 1 → 变成 0000000000(直接回绕)

计算机里是二进制回绕,而且会把 “进位” 丢掉,只保留低 32 位。


二、正溢出(公式溢出 / 正式溢出)

表现:数值太大 → 突然变很小,或变负数。

例子(32 位 int)
  • 最大值:2147483647(二进制:0111...1111
  • 加 1:
    • 数学:2147483648
    • 实际二进制:1000...0000
    • 解释:符号位变成 1→ 被解释为负数-2147483648

游戏里怎么用

  • 伤害公式:攻击 × 倍率 × Buff叠太高 → 溢出变负数
  • 逻辑:游戏判断if (伤害 > 0)才扣血 →负数伤害变成回血
  • 金币 / 经验溢出 → 变成负数,绕过 “上限检查”,甚至直接刷满

三、负数溢出(下溢 / 反向溢出)

表现:数值太小(比最小值还小)→ 突然变很大正数。

例子(32 位 int)
  • 最小值:-2147483648(二进制:1000...0000
  • 减 1:
    • 数学:-2147483649
    • 实际二进制:0111...1111
    • 解释:符号位变成 0→ 被解释为正数2147483647

游戏里怎么用

  • 把血量、金币故意减到极小→ 下溢变超大正数
  • 例如:血量 = 1 - 1000000→ 下溢 → 血直接变成 21 亿,无敌

四、为什么游戏能被利用?(代码设计弱点)

  1. 默认不校验溢出

    • C/C++/C# 等默认unchecked,溢出不报错,直接回绕。
    • 开发觉得 “玩家打不出这么高伤害”,省了校验代码。
  2. 用了有符号类型(signed int)

    • 无符号(uint)溢出是从大到小(255→0),不会变负;
    • 有符号会正负翻转,最容易出 BUG。
  3. 校验逻辑只判断 “正数上限”

    • 常见写法:
      if (gold > MAX_GOLD) gold = MAX_GOLD;
    • 负数完全不拦→ 溢出成负数后,绕过上限,甚至可以再溢出刷满。
  4. 公式叠乘、递归翻倍

    • 技能、Buff、装备多次 “×2” → 指数增长,很快顶破 int 上限。

五、一句话总结

  • 公式 / 正式溢出:正数超出2147483647变负数(利用:回绕 + 符号位翻转);
  • 负数溢出:负数低于-2147483648变超大正数(利用:反向回绕);
  • 本质:补码存储 + 固定位宽 + 无溢出校验 + 有符号类型共同造成的 “数值绕圈”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询