记录对SmartBot的逆向


title: “记录对SmartBot的逆向” date: 2020-08-08T10:30:00+08:00 lastmod: 2024-02-12T07:09:50+08:00 categories: - Reverse aliases: - /archives/34/ typora-root-url: ./....\static

起因:本来想试试看SB的,结果加载了半天没进去,就只能逆向看看他是怎么连接的。

我们先是看看是用什么写的。

查壳.png

其实我最早看的时候是用了旧版本的Exeinfope,结果只查出来是个.net编写的软件,什么壳都没显示,结果今天写文章的时候更新成了新版本的,发现直接能把壳的名字显示出来。

所以,我们还是稍微绕点弯路,看一下我刚开始是怎么看的。那既然是用.net写的,那就直接拖进Dnspy看一看代码。

初步查看.png

嗯,明显是很严重的混淆。我们可以用de4dot拖拖看。

de4dot脱壳.png

看来de4dot也没识别出来是什么壳,但是他帮我们把上面那种恶心的混淆名称给去掉了,于是我们再次拖进去看看。

去除混淆.png

嗯,虽然代码还是乱七八糟的,但是比起之前要好多啦,但是这个代码流程被混淆了,这样子阅读的难度就大大提升了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
int num2 = enumerator.MoveNext() ? -1341126532 : -1577207623;
for (;;)
{
    switch ((num2 ^ -1746658465) % 4)
    {
    case 0:
        num2 = -1341126532;
        continue;
    case 1:
        goto IL_196;
    case 3:
    {
        KeyValuePair<int, int> keyValuePair = enumerator.Current;
        Class38.smethod_3(keyValuePair.Key, ref @struct);
        num2 = -1345980630;
        continue;
    }
    }
    goto Block_12;
}

这是一种有趣的流程打乱技巧,其中只展示了一个简单的流程替换示例,实际上还有超过两百个复杂情况未能展现。其核心思想是通过一个死循环,利用一个变量(num2)来控制流程转向。首先,为num2赋予一个初始值以决定其将进入哪一个case。在这里,使用异或操作后再通过取模运算来定位,取模的基数由分支语句数量决定,如本例中有三个分支,则取模3。从加密(正向操作)的角度来看,此过程通过模拟随机数后进行异或和取模运算来简单定位。然而,从解密(反向操作)的角度出发,想要根据取模结果追溯原始num值是困难的,因为取模操作会导致信息丢失。因此,我们需要按照代码执行顺序正向推理,从num2的赋值推测代码流程,这一过程虽繁琐,但我通过使用计算器手动完成,避免编写程序。

我们的目标是展示最简单的解决方案。发现该代码使用了ConfuserEx壳进行混淆后,便开始寻找可去除此层混淆的工具。经过不懈努力,在一个技术论坛上找到了相应的脱壳机,该工具能直接解密之前难解的switch流程。通过论坛提供的方法,我获取了一个混淆程度较低的程序版本。

随后的分析和研究过程中,我采取了快速浏览关键词和程序集的方式进行。解密方法明确后,我使用Wireshark抓包工具来进一步理解软件的工作流程。

逆向分析结果

  1. 对用户Key的保存方法,是用了AES加密。大概就是下面的逻辑,最里面的一层是用他写的一个秘钥,然后外面一层是用的你的机器用户名称加上机器名称

    1
    2
    
    (Environment.UserName + Environment.MachineName)
    "EC:" + AES("LC:" + AES($KEY))
  2. 与sb服务器的交互,这里反倒是比较危险的地方,居然没有加密,只是用了一个很简单的压缩算法。

  3. 需要打开加载这么久的原因是注入的payload是从完全从服务器返回的,每次加载的时候都需要从服务器接收一个差不多240KB的文件,然后利用本地的Loader.dll文件进行注入dll,注入进去之后就是利用与注入游戏的payload进行交互。

  4. 为什么sb这么流畅就可以解释了

    1. hb通过外部软件与hook机制实现对hs的读取和操作,而sb采用直接注入方式,通过hook直接调用dx的函数。这种方法简单高效,使得操作就像游戏自身的一部分,无需经历hb的复杂过程。相比之下,hb在操作时需要读取大量数据,导致频繁卡顿。
    2. 建议兄弟直接利用该payload进行操作,这样不仅可以无忧应对游戏更新,还能显著提升速度。操作流程是:payload处理场景后将场景数据发送给客户端,客户端再将数据发送给服务器。服务器处理完毕后,将操作数据返回给客户端,客户端据此指导payload进行操作。
    3. 返回的操作是一套一次性连贯的步骤,直至遇到随机事件。遇随机事件则需重新请求数据,这也是sb操作流畅的原因。与此相对,hb的每个操作都需验证场景是否如预期,随机事件的处理尤为复杂。
    4. 目前,兄弟通过假定固定值处理随机事件,易导致错误连锁反应。理想的场景计算需考虑所有随机结果,但这要求使用高级算法,如AlphaGo的MCTS蒙特卡洛搜索树,而这方面的优化需暂时搁置。

最后贴一个炉石机器人比赛的网址,有兴趣的可以去研究一下其他高手写的AI。炉石机器人比赛:炉石传说AI

写的很仓促,过程中通过了搜索引擎查了很多信息,前前后后两天多的时间也让我学到了很多知识,文章有些地方描述的不流畅,希望可以谅解。

0%