前言

这游戏用烧饼就能很容易的修改攻击力防御力之类的,但是结算的时候发现居然有检测,没办法,只好把通讯拆开来看看了

论一个好电脑对逆向的好处

首先看看这游戏用的是啥引擎
QQ截图20160204213107。。。。。。
这个图标我还是第一次见,不得不说槽点实在太多。。。。。。
这游戏不是用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里长啥样
QQ截图20160204215218
那么KEY是什么呢,其实KEY就在这个封包里
QQ截图20160204215321
QQ截图20160204215352
那么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包看一下
QQ截图20160204220139
原来是把我方战斗攻击次数,最大伤害,还有敌方对我方照成的最大伤害等数据都传了回去,怎么修改呢?
这里提供一个简单的思路,只修改我方的防御力,然后结算的时候把跟damaged有关的damagedmax_damagedmax_damaged_combomax_damaged_dflagmax_damaged_enemy_idmax_damaged_enemy_levelmax_damaged_hitmax_damaged_idmax_damaged_typemax_damaged_wave的值全部改为0,也就是伪造成对方没有对我方造成伤害,可以成功结算(已测试通过)
但是,既然都已经把通讯解开了,于是干脆就直接撸了一个脱机,把结算封包再发一遍就行(感觉这游戏一下就被玩坏了233)

尾声

写完脱机后猛然发现这游戏居然跟白猫一样没有体力限制,于是我赶紧选择了弃坑233。所以也别向我要了,不过我留了一个Fiddler的脚本,测试上面那个修改思路的时候写的,就是修改防御力为999然后伪造无伤封包。

百度盘

最后,这不出意外的话是过年前的最后一篇博文,就先祝大家新年快乐啦~

【4月13日】格林笔记自动刷图工具 v0.3.1

2016年4月13日 今天也是闲着无聊,根据群里反馈的东西增加了一些功能,修复了一些BUG,讲道理这游戏国内还有人玩吗。。。 准备工作 首先要能抓到HTTPS的包,f...

阅读全文

12 条评论

  1. “随便用一个请求的地址顺藤摸瓜一下,我这里用的是api/home/get,从引用一路摸下去”
    P大,我也碰到类似的境况,想请教下你怎么寻找的,我在ida里,直接search text,或者在string里都找不到请求地址的字符…

  2. 你好,我用ida 6.6調試libnative.so,模擬器是google android sdk提供的,常常遇到調試一半apk退出,或是ida自動中斷調試,請問你有遇到同要的問題嗎?

欢迎留言

7 + 3 =