哈尔滨网站建设哪家好而且价格不贵,上海网站备案号查询,网站开发中的paml,wordpress自动分享到微博免责声明#xff1a;内容仅供学习参考#xff0c;请合法利用知识#xff0c;禁止进行违法犯罪活动#xff01;
如果看不懂、不知道现在做的什么#xff0c;那就跟着做完看效果#xff0c;代码看不懂是正常的#xff0c;只要会抄就行#xff0c;抄着抄着就能懂了
内容…免责声明内容仅供学习参考请合法利用知识禁止进行违法犯罪活动
如果看不懂、不知道现在做的什么那就跟着做完看效果代码看不懂是正常的只要会抄就行抄着抄着就能懂了
内容参考于易道云信息技术研究院
上一个内容88.利用游戏中的函数实现技能显示
上一个内容中把逆向得到的函数用c实现了并且可以正常获取中文名本次分析一下游戏中使用的哈希算法看看游戏中是怎样去做的分析哈算算法的目的上一个内容中做了逆向的封装通过调用游戏函数得到中文名找名字的这件事就是一个查表的事情哈希就是解决查表的事情查询的速度快其它游戏也肯定会跟哈希这种结构类似到时候看一眼应该就能知道。
然后在解析怪物信息的时候有一个怪物列表怪物里面都有一个编号那个数据包开头部分8字节的数字
我们用了0x200大小的数组来存放怪物的信息如下图 然后如果要去更新怪物的属性该怎么去更新要遍历这个数组去找要更新的怪物找到之后把怪物的指针返回出来然后对返回的指针进行修改这有什么问题吗没有什么问题如果怪物列表只是0x200的大小是没有任何问题的但如果怪物列表有两千万个怪物一次查找最大要两千万次光循环就两千万次这就查询的会很慢然后为了查询的速度更快就有了一系列的算法比如说二分算法二分算法有一个缺点它需要排序它查的效率也没有特别高但比线性无算法的查法快很多然后哈希哈希首先有一个哈希表其实就是个数组既然是数组它就会有大小实际使用时它会很大要比质数大然后有了这个哈希表之后怎样查的更快呢比如数组大小是10然后现在的id是1这时用1/10取余数1/10余数是1然后这时就把数据放到数组的1位置2、3、4、5。。。也都是同理然后哈希表就这么点东西数据那么多这怎么放的进去这肯定会有冲突如果哈希表大小是质数的情况下就有发生冲突的可能性这是数学上的一个特性然后有冲突的时候就让数组的值是一个链表结构比如1会放到数组下标1位置11也会放到数组下标1位置但是这个11是存放在1数据里的这是散列哈希如下图 这个哈希跟查技能有什么关系技能找名字也是一个查表的操作游戏中的语言包它可能涉及到几千几万条如下图根据一个英文去找一个中文 这时如果给一个英文然后去查表这时没法用哈希如上图全是字符串不是数字了哈希是找的东西/数组长度这时就要用到一个东西了哈希函数就是把字符串转换成一个数字哈希函数怎么设计只要满足字符串转数字就可以哈希函数自己实现就各种各样的都有但时有一个优劣的问题就是哈希表是一个有限的大小但是字符串的组合是无限的这种无限的变成有限的肯定会发生冲突这时候就会变成数组里面存链表然后用到链表了查询速度就会又低了所以哈希函数如果给1000个字符串做出来的算法最好不同的字符串能取得不同的结果虽然达不到但是尽量不用冲突冲突率越低算法就会越高效下图一个简单的哈希函数乘法哈希我感觉可以用哈希套哈希的结构下图中31*hashid[i]这里面的31可以是任意数字 现在了解了哈希然后开始看游戏是中的哈希是怎样的 首先来到下图位置下图位置是获取中文名字的位置 然后下图红框里的函数给它一个字符串它会返回一个数字通过上方的哈希说明可以大胆的猜测它是哈希函数 通过断点可以看出它给了函数一个字符串 0x10295FB0函数执行完得到一个数字 然后断点住按f7进入这个函数开始分析 首先从中文表结构0x8C位置取出一个数字 然后比较中文表结构0x29与0的关系 如果不是0就返回-1 然后把参数也就是英文id放到了edx里 然后再ebx0x88中文表0x88位置位置取出了一个数字这个数字可能是哈希表的大小 然后调用 0x10293E50 函数 然后按F7进入 0x10293E50 函数 然后取出字符串第一个字符cl寄存器是1字节的 然后一个if判断如果是0就返回这意思是字符串以0结尾这就说明如果是0说明这个字符串没有内容是个空的 然后有一个乘法运算这个算法跟上面简单的哈希函数例子一样 然后查了一个表 通过阿斯克码表可以看出这个0x103C21E0这个表是为了大小写问题如果是大写也变成小写 然后看到下图位置之后就能明白它实际上跟上方我们的简单例子是一样的操作 通过下图红框里的两行代码完成了 hash31*hashid[i]这样的代码 然后搞完一遍如果有字符串继续循环 然后现在知道了游戏哈希函数的逻辑然后在看它插入哈希表的操作然后在ret位置打断点跳出哈希函数 取消断点 然后按F8如下图可以看到eax得到的值这种数字被称为哈希值 然后有了哈希值就该去用哈希值/哈希表大小了看到下图有div这个指令div ecx这个意思是eaxeax/ecx这样的代码eax是被除数ecx是除数 看上方1字节的指令直观下面不够直观看懂了上面下面的应该能看到如果看不懂 百度搜索 div指令什么意思 这种或这种类似的关键词 然后ecx的值是从ebp1得来的上面怀疑过ebp的值是哈希表的大小在这也验证了 执行完div指令 然后游戏中使用了余数下图的内存里的数据不对忘记乘以4了然后代码也执行过去了没法重新截图了 它取出了一个D220 然后D220与哈希表比较大小 jae是高于跳转所以如果D220大于哈希表的大小就返回就是如果哈希表是10个大小意思就是得出的值不能超过10使用余数的话这个判断没必要写它就不可能超过10 然后ebx还是中文表结构然后中文表结构0x80位置是中文表下图位置取查了中文表 现在的一个情况是游戏中有一个表存放了一个索引然后用这个索引去查中文表那上面说没必要的判断这时是有必要的了 然后得到中文 中文 这里有一个东西用ASII阿斯克码表方式查看的时候发现中文后面跟着它的英文如下图红框内存地址与上图都是一个只是显示的编码不一样上图是UTF-16编码下图是阿斯克码 然后在存放中文的结构里也存放了中文对应的英文 然后我们的代码也改成了跟游戏一样 然后来到0x1035EF66函数 按f7进入函数 然后执行了一个跳转 然后跳转到了0x1035EE5E位置其它的不知道是干嘛的 然后跳转之后的代码 然后比较eax与ecx是否一致这里就是一个比较字符串的操作与stcmp函数意思一样这里直接跳过在ret位置打断点跳出函数 然后回到下图位置然后一致就给返回了 然后找个不一致的它会产生哈希冲突 然后发现它返回了-1没找到东西然后在换一个不一样的数据 这时从哈希表里找到的中文结构头部4字节不是-1了 这时没有执行到0x102976C0函数。这说明文字结构第一个内容是链表指向下一个数据的东西 然后代码也改了 整理一下哈希表里面放的第一个链表然后链表的内容是中文表里的某一个然后中文表第一个是next下一个链表位置然后-1表示没有链表所以找不到也就是这个英文没有对应的文字 到这应该能感觉出这种算法分析起来并不是很难只要知道入参的意思然后带着入参去一步一步跟着断点去走就可以很清晰的分析出算法来 因为就改了两行代码所以代码不会贴出来但会放到码云
总结 中文表结构0x8C位置是哈希表中文表结构0x88位置是哈希表大小中文表结构0x80位置是语言表