眼睛一闭一睁,接触逆向6年过去了,技术一点没有长进,主要突出一个『懒』字。
不是什么高难技术,纯属分享。
起因最近被带动玩一款叫做“宠物小精灵防御战” 的 war3地图, 每个玩家“抓”精灵进行PK的游戏。
那么这里问题就来了, 抓精灵是有概率的,这就很气,很皮,似乎很大程度结果都要向运气看齐,说到这里不由想起了十连跑(小精灵逃跑)的悲伤。
于是我就想,抓精灵的概率是否和本地时间有关?还是和游戏时间有关? 不过这么猜那就对不起自己码农的身份了。
使用解包工具打开魔兽地图,提取出 JASS 脚本文件, 观察定位看到抓精灵的概率 GetRandomInt(1,'d')>=50 / 随机1到100的数据 大于XX时怎么怎么,就是你了。
那么魔兽的 GetRandomInt 是怎么随机呢, 种子怎么生成,算法是什么样, 应该做一个HOOK吗,搞个DLL注入还是搞个远程调用,好像问题很多。
先从逆向说起, 通过百度得知 GetRandomInt 函数在 game.dll 文件内, 定位到后如下:
进入到关键算法,准备提取算法
突然看到 程序使用了一块固定数据 参与计算, 要把这段数据复制出来再搞来搞去编程什么的,太麻烦了。
目前已知的信息, GetRandomInt 参数为两个数字, 其中种子保存在固定位置,且每次执行GetRandomInt后,种子会相应的变化,
那么,写个新程序加载game.dll ,通过搜索特征码也好,硬编码也好定位函数地址,从war3.exe内存中读取种子数据并写入自己的模块内,直接本进程调用GetRandomInt即可知道
war3下次执行GetRandomInt时的结果,从而知道,什么时候能抓到精灵,什么时候抓不到。
开始编写程序,找到war3窗口,打开进程,得到模块地址,搜索到GetRandomInt地址, +$28 得到种子地址指针 , 同时自身加载 game.dll 并找到各地址。
然后每当需要时就读取远程内存并计算下一次随机数。
贴个简单的关键代码
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
同步调试后,每次运算结果与war3相同。 立刻上线对战平台测试,什么稀有神兽想抓就抓,爽,艹翻一切。
每次GetRandomInt的数字越小,说明越容易抓到,稀有的50以下, 半神兽15以下, 神兽5以下, 每个玩家抓精灵时都会调用GetRandomInt,观察好数字决定自己抓精灵的时机就可以了,
我感觉我在这个游戏无敌了。
对了,去年还有个病毒利用魔兽jass漏洞,只要玩了后门地图就会在启动文件夹建立一个批处理文件, 批处理下载一个程序运行并感染用户的所有war3地图实现传播,太厉害了。
后记: GetRandomInt 应该可以利用得更多, 比如 Dota Imba 每个玩家开场获得一个宝箱,宝箱开出的东西是随机的,开到好东西决定了一个好的开局甚至碾压, 如果分析一下对应地图的jass文件,应该可以控制到想开什么开什么。
本文由看雪论坛 noNumber 原创,转载请注明来源:转自看雪论坛
如果你喜欢的话,不要忘记点个赞哦!
热门阅读文章:
更多优秀文章,长按下方二维码,“关注看雪学院公众号”查看!
看雪论坛:http://bbs.pediy.com/
微信公众号 ID:ikanxue
微博:看雪安全
投稿、合作:www.kanxue.com