很久之前的巅峰极客Unity逆向

很久之前,巅峰极客的两个Unity游戏逆向题。

1.png

最近开始接触到Unity的逆向,一周之内遇见了三次。
难道说这是逆向出题的新方向?
不好说,只能拿起DnSpy来一梭子先,虽然第二个题烂尾了。

DnSpy

https://github.com/0xd4d/dnSpy

Unity的逆向用IDA或者OD可能不是很好使,只好召唤DnSpy了。
DnSpy界面清爽,支持.NET和Unity等程序无源码的反编译、调试和修改。
请在github上按照需求下载对应的版本。

2.png

Misc-签到

4.png

听说三叶草等了几分钟就把flag等出来了,对这种操作不得不服气。
用dnSpy打开这个exe,可以看到程序的结构。
App1和App1.Properties分别对应主窗口和“关于”窗口。
flag在App1中显示,在WindowsFormsApp1下找找,可以看到a变量就是flag。

6.png

Re-NinJaProject

大意

游戏中操作忍者去吃小球,程序会检验此时的状态sha1值是否满足条件。如果满足,flag是此状态的MD5值前10位。
游戏状态的定义比较复杂,它由

  • 固定的头部字符串
  • 当前忍者吃到的红球list的异或值(吃到红球score++)
  • 当前忍者吃到的蓝球list的异或值(吃到蓝球score–)
  • 界面中月亮和云的坐标抑或值
  • 当前忍者hp和score的异或值(被怪碰到hp–)
    字符串组成。
    如果这个字符串的sha1值正确,算出MD5就可以了。

7.png

难点

比较麻烦的是如何确定游戏中小球、月亮和云的位置。
朋友说游戏已经被封装好了,不能查看设定的位置。
只好寄托于dnSpy的修改功能。

定位代码

载入Assembly-CSharp.dll(Unity是建立在dll上的)
查看人如其名的PalyerMove类,可以断定Update()负责实时刷新状态,C0t1Nu30RnOt()负责校验状态是否合法。
redlist保存吃到的红球,bluelist保存吃到的蓝球
hp,score保存对应的值

8.png

选中变量右键分析,可以查看在那些地方被调用。
我的机器上这个功能有点儿问题,不能找到被赋值处,可以遍历程序结构检查。
找到redlist,bluelist,score,hp的赋值和使用代码。

例如:
红球的X和Y坐标被取两位小数并转string相连后加入redlist(string数组)中。
在检验状态时,取出来进行抑或,加入状态字符串。

9.png

10.png

打印数据

由于游戏中景物的坐标不变,只是吃到球的顺序改变,对应到状态字符串中是字符串顺序改变而内容不变。
所以我在C0t1Nu30RnOt()中添加了一些代码,打印出每个球坐标的异或值以及月亮、云坐标的异或值。
剩下的交由枚举顺序爆破吧。
选中类-右键-编辑类-编辑代码-编译-选中左上文件栏-保存模块或保存全部,这样才算完成了dll覆写。

11.png

13.png

枚举状态

不必把球吃完,也没有提示不吃蓝球,所以枚举数量很大。
满打满算是10选10的全排列+10选9的全排列+…+10选0的全排列。
由当前枚举到的状态可以计算score值,但还需枚举hp值。
从游戏玩家的角度出发,自然希望吃完红球,不吃蓝球,不碰怪,hp和score都是max。
可以由此指定搜索策略。
然而我失败了,不管是优先搜索还是全面暴力都没有结果。
至此,不由得对比赛时段内就做出来的dalao们献上膝盖。

12.png

坐等官方WP来看看哪儿出了问题。

哦,原来是隐藏了一个球,告辞…

Welcome to my other publishing channels