2016-02-04 5,085 ℃
前言
这游戏用烧饼就能很容易的修改攻击力防御力之类的,但是结算的时候发现居然有检测,没办法,只好把通讯拆开来看看了
论一个好电脑对逆向的好处
首先看看这游戏用的是啥引擎
。。。。。。
这个图标我还是第一次见,不得不说槽点实在太多。。。。。。
这游戏不是用unity3d做的,又得上IDA,不过,你这libnative.so怎么有48.9MB这么大。。。
在我这垃圾电脑静态分析这个so文件时,IDA挂掉了2次。。。最后把其他软件都关了花了30分钟终于是把这个文件静态分析完了,然后赶紧保存数据库。。。我去,居然有400+MB。。。
顺藤摸瓜
随便用一个请求的地址顺藤摸瓜一下,我这里用的是api/home/get,从引用一路摸下去,就能到达0x02502D5C这个地址上的app::WebApi<app::IWebApiHomeGet>::Decrypt函数(早知道命名这么标准我就直接搜Decrypt好了_(:з」∠)_)
引入眼帘的就是一个名为CryptoPP的类,这类库有点熟悉啊,赶紧百度一下,是一个C++用的开源加解密类库。我就喜欢这种用开源类库的游戏,可以省去不少时间。
随便看一下就能知道这游戏用的是AES算法,CFB模式,关键就在SetKeyWithIV这个函数上,我们来看看函数原型
void SetKeyWithIV (const byte *key, size_t length, const byte *iv, size_t ivLength)
OK,Key和IV都在里面了,我们再看看IDA里长啥样
那么KEY是什么呢,其实KEY就在这个封包里
那么IV呢,这里我直接上动态调试了,下个断点停下后直接查看内存,IV如下
private static byte[] IV = new byte[] { 0x2C, 0x38, 0x5F, 0x44, 0x34, 0x75, 0x68, 0x6B, 0x50, 0x3A, 0x25, 0x6E, 0x5A, 0x62, 0x49, 0x4F };
至此逆向结束,接下来就是算法实现了
算法实现
依旧是用C#写的,.net framework封装的加密类用起来就是多快好省233
using System; using System.Security.Cryptography; namespace GrimmsNotesHelper { class Crypto { public static byte[] Key; private static byte[] IV = new byte[] { 0x2C, 0x38, 0x5F, 0x44, 0x34, 0x75, 0x68, 0x6B, 0x50, 0x3A, 0x25, 0x6E, 0x5A, 0x62, 0x49, 0x4F }; public static byte[] Decrypt(byte[] toDecryptArray) { int paddinglen = 32 - (toDecryptArray.Length % 32); byte[] buffer = new byte[toDecryptArray.Length + paddinglen]; toDecryptArray.CopyTo(buffer, 0); RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = Key; rDel.Mode = CipherMode.CFB; rDel.Padding = PaddingMode.Zeros; rDel.IV = IV; ICryptoTransform cTransform = rDel.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(buffer, 0, buffer.Length); byte[] buffer2 = new byte[toDecryptArray.Length]; Array.Copy(resultArray, buffer2, toDecryptArray.Length); return buffer2; } public static byte[] Encrypt(byte[] toEncryptArray) { RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = Key; rDel.Mode = CipherMode.CFB; rDel.Padding = PaddingMode.Zeros; rDel.IV = IV; ICryptoTransform cTransform = rDel.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); byte[] buffer2 = new byte[toEncryptArray.Length]; Array.Copy(resultArray, buffer2, toEncryptArray.Length); return buffer2; } } }
游戏修改
那么这样就能看看游戏到底检测了什么,拆开commit包看一下
原来是把我方战斗攻击次数,最大伤害,还有敌方对我方照成的最大伤害等数据都传了回去,怎么修改呢?
这里提供一个简单的思路,只修改我方的防御力,然后结算的时候把跟damaged有关的damaged,max_damaged,max_damaged_combo,max_damaged_dflag,max_damaged_enemy_id,max_damaged_enemy_level,max_damaged_hit,max_damaged_id,max_damaged_type,max_damaged_wave的值全部改为0,也就是伪造成对方没有对我方造成伤害,可以成功结算(已测试通过)
但是,既然都已经把通讯解开了,于是干脆就直接撸了一个脱机,把结算封包再发一遍就行(感觉这游戏一下就被玩坏了233)
尾声
写完脱机后猛然发现这游戏居然跟白猫一样没有体力限制,于是我赶紧选择了弃坑233。所以也别向我要了,不过我留了一个Fiddler的脚本,测试上面那个修改思路的时候写的,就是修改防御力为999然后伪造无伤封包。
最后,这不出意外的话是过年前的最后一篇博文,就先祝大家新年快乐啦~
“随便用一个请求的地址顺藤摸瓜一下,我这里用的是api/home/get,从引用一路摸下去”
P大,我也碰到类似的境况,想请教下你怎么寻找的,我在ida里,直接search text,或者在string里都找不到请求地址的字符…
大大,如果想拆这游戏的立绘该做什么呢?
抱歉我不知道哦
你好,我用ida 6.6調試libnative.so,模擬器是google android sdk提供的,常常遇到調試一半apk退出,或是ida自動中斷調試,請問你有遇到同要的問題嗎?
我用的真机,没有遇到过
请问这个要怎么用
大神战国姬谭能修改吗?
不玩这个游戏。。。
導入了腳本但沒什麼效果
已經加到自訂規則了 怎麼沒效果呢@@
大神新年快乐 我想学逆向求带
我来祝你新年快乐啦