在现代软件开发中,混淆和加壳是一些开发者的常用手段。尽管有很多(自以为)合适的理由使用它们,但它们实际上对开发者和用户都没有好处。
混淆和加壳
混淆
这里的混淆(obfuscate)指的是将(通常是解释性语言)的代码变量名、函数名、常量、甚至是代码逻辑通过特定工具修改为人类不可读或无语义的文本。虽然经常被同时使用,但混淆和压缩(minify)不同,后者可以解释为减少分发包体积的权宜之计,而混淆只是为了干扰人类分析者。
加壳
加壳(pack)是将可执行文件的字节码加密、混淆和压缩,以隐藏程序的执行细节并干扰人类分析者。有些加壳工具会检测并阻止在虚拟机中运行或反调试,有时也起到 DRM 的作用。
例子:VMProtect
为什么不?
尽管对部分开发者而言,不计代价保护自己的软件似乎非常合情合理,但在实际应用中,这些技术会给用户带来麻烦:
- 任何混淆和加壳技术都会或多或少地影响程序的运行效率,有些还可能导致软件的行为与预期不符。
- 恶意软件也会使用相同的技术隐藏自己,而在很多杀毒软件眼中,这些“被保护”的软件和恶意软件没什么区别。
- 应用混淆和加壳会导致用户更难亲自分析软件的行为和安全性,而一句来自开发者的承诺通常并不具有说服力。
- 世界知名的软件开发商很少使用混淆和加壳,且表现通常更好。
- 可能会阻止软件在用户的操作系统上运行,例如 Wine 或 Linux 上的 Windows 虚拟机。
对开发者而言:
- 需要向用户解释自己的软件 “只是加壳了” 而非恶意软件,有时需要说服用户关闭杀毒软件。
- 为了减少杀毒软件报告,不得不购买昂贵的代码数字签名证书。
- 可能使软件难以维护或热更新。
- 不恰当地检测用户环境可能会导致杀毒软件误报或误阻止、违背安全策略或违反当地法律。
- 难以获取来自技术用户的 Bug 报告或修改方案,通常更有助于改进软件。
- 忽视服务器端鉴权将会留下更大的安全隐患。
替代方案?
最重要的,“不计代价保护自己的软件”本身就不正确,这严重损害了用户的利益。
不应该在任何情况下将用户环境视为“可信的”,而不是通过各种检测来判定一个“可信”环境。
任何关键或需要保密的算法或资源应在服务器端通过 API 调用,且应有合适的鉴权。
成熟的软件开发商会使用知识产权法来保护自己的软件。
某些编写在线游戏作弊或盗版工具的开发者本身就没有尊重其他人的知识产权。
反作弊
很多时候,反作弊(和 DRM)是混淆、加壳和持续的用户环境监视的混合体,被广泛应用于商业化的联机游戏。
大多数反作弊通过驱动级的持续监视用户环境实现,它们有非常高的权限(用于实现它们声称的“反作弊”功能),包括无限制地访问设备上的文件、内存、硬件信息和其他正在执行的程序。用户为了运行游戏,只能选择相信反作弊提供商的信誉,而非真正意识到它的潜在影响。
这些反作弊软件可以“合法地”侵犯用户隐私,缺乏告知或将告知隐藏在格式条款中,用户除了“同意”别无他法。
拒绝反作弊的原因和混淆或加壳类似,更不用说“持续的用户环境监视”有多么荒唐。
反作弊系统也将 Linux 玩家拒之门外,即使存在 Wine 这类技术,反作弊拒绝在上面运行。
反作弊依赖驱动级权限,这是一个游戏软件不应获得的权限。具有这种特征的恶意软件被称为 Rootkit,而反作弊本身也不能保证自己是无可利用安全漏洞的。
一些激进的反作弊系统会访问整个设备的文件,并可能上传文件特征或内容。还有可能检测运行中的开发或安全分析工具,对于用户分析软件行为和安全性极为不利。
反作弊系统的错误报告会导致玩家被封禁,在一些情况下,玩家没有有效的途径解决问题,或失望于厂商的反应迟钝。很多厂商不是出于公平性和保护玩家,而是为了自己的商业利益而部署反作弊系统。
反作弊系统永远无法对抗新生的作弊方式,这只会导致更高权限的索取和更多隐私侵犯,更多地影响公平游戏的玩家而非作弊者(因为作弊者始终可以找到绕过反作弊或使其不运行的办法)。
唯一有效的方法是服务器端反作弊。通过分析客户端上传的数据,可以阻止任何修改客户端关键数据的行为。如果服务器无法实现此功能,则说明此游戏不需要反作弊系统。
对于一些竞技性强的即时性多人游戏,低强度反作弊可以被认为是一种“必要的恶”。