我在开发在线游戏的游戏编辑器中工作。在我们与机器人进行的无休止的斗争中(这对服务器性能,游戏经济性,游戏体验等产生了负面影响),我们检测机器人的武器之一是将签名的As3字节码发送给客户端(也编码为As3),请他执行它。字节码将:


嵌入AES密钥(K)
K被拆分为字节码的不同部分
检查环境
通过AES加密带有K的游戏会话信息并将其发送到服务器

字节码和K每2小时更改一次

字节码与商业程序混淆。 />这种方法可以使用几个月,但是由于几个星期后,机器人又回来了。我发现它们会自动反编译我们的字节码以提取K。

注意:


K是字节数组
我不在乎如果可以自动恢复密钥(如果在合理的时间内无法自动恢复)。

您建议采用哪种方法来防止K被反编译恢复?

评论

恐怕只要他们可以使用AS3仿真器执行代码,无论您做什么,他们都可以获得密钥。

您所寻找的被称为“白盒加密”。这是关于使密码程序和密钥如此纠结,以至于您不费劲就无法提取密钥。不幸的是,没有人真正成功地完成过这样的密码系统。到目前为止,所有尝试都已被打破...但是,它可以使密钥恢复过程变得相当复杂。

白盒加密对他的最终目标无济于事,因为现实世界中使用的所有白盒加密系统都可以通过仅将白盒代码复制到密钥源(或类似代码)中并通过提供输入并读取输出将其视为黑盒的方式进行颠覆。

#1 楼

这里是有关基本问题和可能解决方案的一些想法;即使整个系统超出了您的开发预算,某些关键思想对于构建自己的解决方案也可能仍然有用。算法本身就是系统中最薄弱的环节,就像将十英寸的钢门安装在帐篷或膝盖高的围栏中一样,也无法提供安全性。如果AES实现在字节码blob的外部,则它的入口点很容易挂接,将密钥放在银色的盘子上。

(1)模块化大大有助于分析。一旦识别出一段代码可以起到一定的功能-甚至可能是著名的算法,例如CRC32,MD5或AES-调用它的目的就很清楚了。

(2)极大地优化编译器通过减少冗余来进行辅助分析。除非他们过分喜欢内联。

无论如何,这就是赢的方法:您需要建立一个大型的Shell游戏来使这些线索毫无价值,您需要通过交织大量计算来打破模块化;此外,您需要将要验证的状态作为密钥的一部分,并且需要将整个shebang绑定到特定的游戏会话,客户端进程和计算机。

一种方法是编写一种字节代码解释器,该解释器实现验证所需的基本操作:将两个单元或两个单元,添加两个其他单元,对字符串进行哈希处理,对内存范围进行校验和,检索进程ID等。本质上是一个类似于IDC或NWScript的微型常规脚本,其中包含几个特殊的“宏”操作。基本操作从单元格(寄存器)数组中获取操作数,并将其结果传递到该数组中的某个单元格。每个周期(操作)还涉及循环一组简单的RNG(xorshift,KISS等),以及基于这些RNG的功能表和单元格数组的随机排列步骤。关键点是,要验证的状态的元素必须还原为可以用来扰乱RNG状态的数值。错误的结果,所有后续指令都将被错误地解码,这意味着甚至在无法通过验证的环境中也无法分析代码。这样可以保护在验证码正确结束后计算的所有内容,例如会话密钥。

剩下的就是将每个字节码blob绑定到特定的客户端会话,即生成一个blob。专为此。另一个客户端会话具有不同的Blob,因此没有任何信息可以从合法的客户端会话中窃取,然后用于解锁机器人会话。

验证需要分解为一系列小的脚步;即,不要一次检查一个大的内存范围,而要执行几十个较小的校验和操作。

您将照常使用简单的脚本语言编写验证代码;一个特殊的程序分析生成的目标代码的依赖关系图,并确定何时可以执行哪个字节码,从而将所有内容有效地内联到一个巨大的怪物函数中。那是预处理步骤,只需完成一次。然后执行代码生成步骤,其中以伪随机方式(基于会话密钥)选择可调度的字节码,并将其编译为blob。由于每个字节码被选择,它也必须在通过鼓起,为解释器状态的适当的更新(RNG状态,功能表和单元阵列的混洗的状态)的环境中执行。至少在早期,可以在给定点上安排数百个独立的计算链。特定的会话Blob(可能从池中选择,并参数化基本校验和范围)。通过这种方式,分析合法客户的斑点可以使攻击者仅获得愚弄/模仿才能成功的一部分验证操作。在极端情况下,您可以只对过程映像的一小部分进行校验和,而攻击者则需要以原始方式呈现(或虚拟化)整个映像,因为他们不知道将对哪些特定区域进行校验和。 >
在另一个字节码系统之上实现字节码系统可能会有所限制,主要是在性能(可实现的复杂性)和可实现的模糊性(可识别的函数调用,以检索进程ID而不是普通的未命名的机器指令,窥视gs:[30h],然后从那里去)方面)。但是,即使必须使用巨型switch语句而不是函数表,该原理仍然适用。出于某些奇怪的原因,在字节码系统的顶部执行加密操作(例如Marsaglia的KISS,哈希,密码等RNG)似乎有些习惯。 >
杠杆-集成到整个系统的方式-在这里与加密一样重要。您不希望绕过十英寸的钢制门。

此外,这样的系统根本没有弹性,非常脆弱。如果一个验证操作过于渴望/约束,那么您将有成千上万的合法客户在愤怒中...叫。想要整理内容并将DLL注入正在运行的进程中,这会使加载的模块列入白名单有些棘手。例如,攻击者可能将具有NVIDIA名称的DLL注入运行在ATI卡上的游戏中。绕行也是很常见的。代码混淆(Wroblewski)
混淆转换的分类法(Collberg)

注意:诸如自动混淆器之类的罐装解决方案往往会被归类为罐装黑客。这是否是一个问题,更多的是取决于事故(受众中熟练的反向专家的存在以及他们愿意投资的时间)。例如,EA / Denuvo似乎没有通用的拆包器,尽管他们的方案比现有技术落后了大约十年。我想没有一个人既有技巧又有名望...

评论


同样值得注意的是:在理想的世界中,您可以在单个补丁程序的空间内(通过实施尽可能多的建议)大大提高安全性。这样,攻击者必须破坏所有东西才能重新进入,而不是在单独的修补程序中引入每个新功能时对其进行攻击。 (最大的缺点是,这会使质量检查变得困难得多,并且可能会延迟大补丁)。

–nneonneo
15年1月8日,0:42