在游戏开发中,为了避免被直接搜索到内存数据, 经常需要对代码和内存进行混淆, 因此对于cocos2dx+lua的游戏来说,也需要这种方式来在一定程度上防止玩家作弊

在lua中,table是个很重要的数据结构,既可以作为map使用,也可以作为array使用,因此是内存数据容器的基石,所以只要能修改了对table操作的行为,那么就可以对使用者来说,进行透明化的实现数据混淆,实现存入table时自动混淆,从table中取出时,再自动还原

虽然lua不是面向对象的语言,也没有提供复杂语言里的反射机制,不过幸好lua有metatable和metamethod机制,利用这两个机制,我们可以hook掉一些table的操作行为,实现我们想要的效果。

先简单介绍一下metatable, 对lua来说,每个值都有一个元表, table和userdata可以有各自独立的元表,而其他类型的值共享其类型所属的单一元表。对table来说,可以使用setmetatable来给其设置元表。 table中有两个重要的元方法__index和__newindex, 这两个元方法的行为是:

__index: 当访问table中一个不存在的字段时, lua会查找该表有没有__index方法,如果有,则会调用该方法
__newindex: 当对table重一个不存在的字段赋值时, 则会调用该方法

因此,我们只需要在table中用一个隐含的代理来持有所有的赋值给该table的数据, 那么就会保证__index和__newindex方法一定会被每次访问该table时都会触发。

因此,通过该原理实现了如下的一个混淆table,对所有table中的数值元素进行了混淆加密, 代码在:

https://github.com/pig-soldier/mixtable.git

其中,需要注意的是, 在lua 5.3之前, table的库方法如table.insert以及针对table的for循环是会跳过元方法的,也就是说这几种情况下__index和__newindex是不会生效的, 所以在代码中覆盖了lua的原始的这几个方法。

使用时,只要第一次创建table时, 调用create_mix_table()来创建出一个mixtable,后续只需要对这个加密表进行正常的赋值和访问操作即可。