随着游戏代码的发展,新游戏的技能越来越华丽,分类也越来越多,数据结构用的五花八门。而老游戏也不甘寂寞,技能数据也处理的有模有样,分析起来也颇有难度。以下面这款游戏为例,我们从逆向安全的角度来学习一下它的技能体系数据结构。
这款游戏的技能体系我们大致分为三个部分去分析,分别为技能等级结构,技能库结构,剩余级技能点数结构。下面先分析最简单的技能等级结构。
技能的分析可以从技能ID,技能等级,技能名字三个角度入手分析,而如果技能等级可以使用的话自然是最方便的一种,起码扫描起来很简单。而这款游戏恰好就可以通过技能加点来入手。
首先我们呢用CE来任意扫描一个高级魔法的等级,最终可以得到一个结果
在xdbg32中对这个地址下硬件访问断点,游戏直接断下,并得到一个+C偏移
向上分析可以看到一个跳转跳过ret,执行到+C偏移处,而上面可以得到一个循环+4的链表结构
图中可以看出这个链表最初的来源是上面的一个数组,当数组指向地址+8的位置与传入的esi相等时会跳出链表,或者当链表节点eax等于0时结束链表循环。
我们先到上面分析出数组的起始地址和范围,然后再获取下标的信息。
在上面不远处可以看到起始地址为[ecx+4],而外面传入的第一个参数在循环右移5之后与[ecx+8]进行模运算,可以获取到下标edx
经观察可以得出这个这个[ecx+8]恰好是数组中总的元素数量。
由于数组中元素较少,而链表中的节点也不多,可以判断这个数组下标其实可以不去管他,只要我们得到技能库与之关联就可以得到所有的技能信息。
接下来我们继续去分析数组起始地址ecx的来源,在执行到返回后可以得到一个+0DCE偏移
向上分析得到来来源于[ebp+8],执行到返回继续分析第一个参数,可以得到来源[eax+4]
然而这个+4并不是偏移,因为eax是一个堆栈地址,[eax+4]是一个局部变脸,并且在上面的CALL 0x2D50780中被赋值。我们到这个CALL中可以很快找到来源,并得到一个+22EC的偏移
退出这个CALL并再次下断执行到返回,可以很快得到基地址
这个数据结构总体来说是很简单的,只是中间的局部变量作为参数到CALL的赋值的操作对逆向新手有一些难度,如果对堆栈比较熟悉的话可以轻松搞定,从安全角度来讲,这里可以做的更加复杂一些。
公式就不整理了,我们接下来将要分析较为复杂的技能库结构。
玩游戏,学逆向,做安全,欢迎感兴趣的小伙伴关注我们。