字节暗面

游戏资源加密到底在防什么


在做资源安全测试时,经常能看到一个现象:一些游戏包解开后,配置表、贴图、音频几乎不需要反编译,就能被批量导出……资源这东西,是真不经放。

原因也很简单,资源天生就是要被引擎加载的,你的引擎认得这套格式,扒资源的工具也认得——认的是同一套。所以包一解,AssetStudio 一拖,贴图导成 PNG、音频导成 OGG,配置表要是明文 JSON / CSV,文本编辑器就能开。文件头还明摆着:PNG 是 89 50 4E 47、OGG 是 OggS、Unity 的 AssetBundle 是 UnityFS,扫一遍 magic bytes 就知道里头是什么。

但“要不要加密”这个问题,不能拍脑袋答。得先看攻击者会怎么来,按成本排个序:

  1. 静态提取,成本最低最常见。游戏包一解,用 AssetStudio / AssetRipper 把整套资源带名字一次导全,或者直接对 bundle、OBB grep 文件头把文件 carve 出来。零成本、能批量、写个脚本就跑,扒资源的绝大多数停在这一档。
  2. 劫解密 / Hook加载器,中等成本进阶版。资源加密了,攻击者不去破你的算法,而是等你自己解——客户端要用就得先解,那一刻明文必在内存里。Frida hook 住加载或解密入口,整包明文直接捞走。要技术、要找点、要绕反调试,但一次能拿全。
  3. GPU /解码器兜底,成本高较少见。前两档都堵死了,资源最终还得交给引擎:贴图上传 GPU、音频进解码器,那一刻必然是明文。hook 纹理上传一张张截也能拿到,可得 runtime、得跑到对应画面、拿到的还是 ASTC / ETC2 压缩块且没图集结构,想凑齐整套能累死,实战里基本没人这么扒资源。

明确了这三档,答案就清楚了:加密可以把攻击成本从“白嫖静态、脚本批量”的阶段逼到“用上 Frida、找解密点、绕反调试”,光这个成本就劝退大半。所以,加密不为“防住所有人”,是把攻击成本从地板抬起来,至于能抬多高,看后面做到什么程度。

简单直白的演示一下Hook:

byte[] enc   = File.ReadAllBytes(path);
byte[] plain = Decrypt(enc, key);                  // 你的解密
AssetBundle ab = AssetBundle.LoadFromMemory(plain); // plain 就是明文 bundle

攻击者 Hook 掉 LoadFromMemory,把传进去的 plain dump 下来,一个 UnityFS 开头的完整 bundle 就到手了,你那套 Decrypt 写得再花也没参与进来;Lua 同理,luaL_loadbuffer 进去的就是解密后的 bytecode。所以加密这层真正能较劲的,从来不是算法本身,是拿到密钥和明文有多难。

那有价值的东西干脆都放服务端不就完了?理论上是,最稳的判定都该搁在服务端。可现实里,延迟敏感的实时战斗、弱网和离线玩法、帧级的数值结算,逼着一部分数值和逻辑必须留在客户端,这时候“搬服务端”压根就不是选项,问题是既然留在客户端怎么保护它。

想保住留在客户端的高价值资源,下面三件事得一起做:

  1. 加密,这是基础,不做等于裸奔。但切记不能整包重加密。之前给一个 MMO 项目做测试,整包 AES 加密后,启动时间从 3.2 秒涨到 11.8 秒,低端机直接卡死。后来改成按需分块解密——只解密当前场景需要的 bundle,解完进缓存,CPU 占用从 35% 降到 4%。加密能拦住静态提取,但只做这个,并不保险。
  2. 强度,把第二档的成本顶上去。解密下沉 native、密钥别落到 C# / Java 托管层(托管堆好 dump),分块按需解,叠一层反 hook、反调试,脚本再狠点可以改 Lua 的 opcode 或上自定义 VM,让 unluac 这类现成工具失效。
  3. 性能,这一点最容易被忽视。解密吃 CPU、吃内存、占加载时间,整包重加密加每帧实时解密,帧率和加载肉眼可见地掉。按需解、解完缓存、native 里高效实现、热路径别叠重算法——安全和流畅是同一本账,护得太狠把游戏拖卡,等于把玩家往外赶。

实际部署中:

  • 构建流水线统一加密,密钥构建时注入,产物加访问控制,别让明文资源和密钥一起进仓库、在群里传。
  • per-resource key,从内容 hash 派生,一份资源一把钥匙,扒出一个不等于全套都开。
  • 资源完整性校验,打包时记 hash、服务端留一份,加载时比对,版本或 hash 对不上的记录上报、必要时限制登录支付这类操作。

没有扒不出来资源,引擎能加载的,最后总能落成明文。能做的是按价值和攻击成本分层,把门槛抬到对方觉得不划算,尤其是在客户端的高价值逻辑。加密强度和性能预算是一个痛点——护得不够等于没护,护过头又把游戏做卡,这中间的平衡才是资源加密真正的难点。

← 返回列表