最近有做到两类不同的游戏类的题,尤其是unity游戏逆向,这个我感觉还挺有意思的,而且近期出现的还蛮多的,浅浅记录一下O(∩_∩)O~~

unity3D

它允许开发者通过可视化工具和编程快速构建 2D/3D 游戏、动画等内容,并发布到多个平台(如 PC、手机、主机等)。

image-20250531210953147

一大优点是跨平台,支持它能跨平台的得力于两种脚本处理的方式

  • Mono

传统 C# 解释执行,兼容性好但性能较低(逐渐淘汰)。

构建应用非常快,必须将代码发布成托管程序集(.dll文件,由mono或者.net生成)。

  • IL2CPP

将 C# 转为 C++ 再编译,提升性能(主流选择,但逆向难度更高)。

相比Mono构建应用慢,可以启用引擎代码剥离(Engine code stripping)来减少代码的大小。

篇文章对这两个部分有很好的解释

Unity之IL2CPP - 知乎

所以对我们做题来说

Momo出包

主要逻辑在Assembly-CSharp.dl

这是 Unity 默认将开发者编写的 C# 代码编译成的动态链接库(DLL),包含游戏的核心逻辑(如角色控制、UI、游戏规则等)。

所以我们只需要把Assembly-CSharp.dl放到dnsy里面反汇编,分析代码逻辑即可

这里我之前做过几个

[BJDCTF2020]BJD hamburger competition

玩一下游戏发现是这样子的

image-20250531201956487

用dnsy打开.dll,在{}里面找关键的函数

玄机在ButtonSpawnFruit处,主要是因为这里面有输出的字还有flag的标识

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;

// Token: 0x02000004 RID: 4
public class ButtonSpawnFruit : MonoBehaviour
{
// Token: 0x0600000A RID: 10 RVA: 0x00002110 File Offset: 0x00000310
public static string Md5(string str)
{
byte[] bytes = Encoding.UTF8.GetBytes(str);
byte[] array = MD5.Create().ComputeHash(bytes);
StringBuilder stringBuilder = new StringBuilder();
foreach (byte b in array)
{
stringBuilder.Append(b.ToString("X2"));
}
return stringBuilder.ToString().Substring(0, 20);
}

// Token: 0x0600000B RID: 11 RVA: 0x00002170 File Offset: 0x00000370
public static string Sha1(string str)
{
byte[] bytes = Encoding.UTF8.GetBytes(str);
byte[] array = SHA1.Create().ComputeHash(bytes);
StringBuilder stringBuilder = new StringBuilder();
foreach (byte b in array)
{
stringBuilder.Append(b.ToString("X2"));
}
return stringBuilder.ToString();
}

public void Spawn()
{
FruitSpawner component = GameObject.FindWithTag("GameController").GetComponent<FruitSpawner>();
if (component)
{
if (this.audioSources.Length != 0)
{
this.audioSources[Random.Range(0, this.audioSources.Length)].Play();
}
component.Spawn(this.toSpawn);
string name = this.toSpawn.name;
if (name == "汉堡底" && Init.spawnCount == 0)
{
Init.secret += 997;
}
else if (name == "鸭屁股")
{
Init.secret -= 127;
}
else if (name == "胡罗贝")
{
Init.secret *= 3;
}
else if (name == "臭豆腐")
{
Init.secret ^= 18;
}
else if (name == "俘虏")
{
Init.secret += 29;
}
else if (name == "白拆")
{
Init.secret -= 47;
}
else if (name == "美汁汁")
{
Init.secret *= 5;
}
else if (name == "柠檬")
{
Init.secret ^= 87;
}
else if (name == "汉堡顶" && Init.spawnCount == 5)
{
Init.secret ^= 127;
string str = Init.secret.ToString();
if (ButtonSpawnFruit.Sha1(str) == "DD01903921EA24941C26A48F2CEC24E0BB0E8CC7")
{
this.result = "BJDCTF{" + ButtonSpawnFruit.Md5(str) + "}";
Debug.Log(this.result);
}
}
Init.spawnCount++;
Debug.Log(Init.secret);
Debug.Log(Init.spawnCount);
}
}

分析一下可以看到,给出的字符串DD01903921EA24941C26A48F2CEC24E0BB0E8CC7是flag进行sha1加密后的值,使用工具对字符串解密。

解密结果md5加密后取大写前20位即为flag

IL2CPP出包

主要逻辑在 GameAssembly.dll(Windows)或 libil2cpp.so(Android/iOS)

IL2CPP 会将 C# 代码转换为 C++,再编译为原生二进制文件,进而被封装到 GameAssembly.dll中。

还有一个文件global-metadata.dat:此文件包含 IL2CPP 的元数据(如类名、方法名、字段等),用于还原代码结构。

因而又分为两种windows下和安卓下

好像目前对于il2cpp逆向都以Android中的.so文件居多,弄了好几天才知道windows下的怎么操作

哭了::>_<::

PC

当我们有了以下这两个前置文件之后

1.GameAssembly.dll

2.global-metadata.dat

需要专门的Unity工具去dump它,这里用的工具是I2CppDumper

用Il2CppDumper.exe工具打开GameAssembly.dll后再选中global-metadata.dat

就能得到DummyDll这个文件夹里面有Assembly-CSharp.dll从而进行分析

当然里面还有许多其它的出现

  • dump.cs:这个文件会把C#的dll代码的类、方法、字段列出来
  • il2cpp.h:生成的cpp的头文件,里面有相关的数据结构
  • script.json:以json格式显示类的方法信息
  • stringliteral.json:以json的格式显示所有的字符串信息

其中script.json、il2cpp.h是用来恢复符号表的,恢复的是GameAssembly.dll文件

GameAssembly.dll文件就相当于apk的那个.so文件很重要滴

[LitCTF2025]Robbie Wanna Revenge

首先是IL2CPP我们需要dump

但是dump不出来,发现是被魔改加壳了,在010里面将LIT都换成UPX

image-20250531222709015

然后脱壳工具脱一下,这样就能dump了

先用Il2CppDumper.exe工具打开GameAssembly.dll后再选中global-metadata.dat

image-20250531213208352

然后文件夹里发现Assembly-CSharp.dll,打开来在{}里面分析观察里面的函数

LitCTF 2025 Robbie Wanna Revenge-CSDN博客

这里有两种做法

一种是上面链接里面写的修改程序,使小人永远不死从而拿道flag

我们用ida把它打开然后控制台运行这个ida_with_struct_py3.py文件

image-20250604203954469

先选择dump出来的script.json再选il2cpp.h,就可以恢复GameAssembly.dll里面的函数啦

找到Assembly-CSharp.dll里面看到的playerheath函数

注意多个地方的跳转可以发现修改这边的jnz换成jz可以永远不死

右键Aessmble换一下然后EditPatch programApply patches to input file导出dll

image-20250604204356996

然后Robbie就不会死了,可以玩游戏得到flag

另一种是在CE里面激活 mono 功能,然后调用PlayerWon

这里我就用第二种了,.Net info点开

image-20250531234618948

在游戏管理那一类里面调用PlayerWon

image-20250531234638329

[MRCTF2021] EzGame

先玩一下游戏(^o^)/~很有意思

如果要得到flag的话有许多条件,第一个想到的就是用ce修改一下值就可以了

image-20250704152911804

既然是个illcpp题的话

老样子用Il2CppDumper.exe先dump一下拿到的dll看一看嘞

发现这里有界面输出的东西

image-20250704151405420

本来想还原一下函数表的,结果一查发现这个dll有Themida壳,然后还原了也没什么用

最直观的就是钻石个数了,找到之后看一下汇编语言,在分析结构那边把数据结构加上去,注意字节长度,因为有些数字不知道长度直接使用指针了

然后修改条件的数值

image-20250704174717108

然后回去点getflag的按钮,没给flag,明明已经满足条件了

想一想应该是还存在哪里检查了,单单用ce成功不了

image-20250704172136557

方法一

感觉应该是key是不断改变的,key不正确所以就不行

把key的地址记住放到里面,查看一下是什么写入了,吃了一个钻石之后再查看一下这两个看看里面的汇编,意思大概是八个字节被改变了

image-20250704175139621

查看汇编,考虑先看看伪代码

先把它这部分内存中的东西用火绒剑dump出来

用这个dll的基地址加上偏移,找到覆盖目标地址的地方dump出第一个

image-20250704180326983

因为用ida打开都是字节码,我们用函数开头的字节码信息来定位函数

image-20250704195612587

将dump下来的文件进行分析,直接搜索函数开始的字节码,按c后再p形成函数

不知道为什么我的一直看不了伪代码,看了一下别人的截图里面是对key进行位运算

直接将自己初始的key循环进行105次,得到的key修改一下就可以了

方法二

key的改变在Assembly-CSharp.dll里可以发现是每次吃到钻石后用EatTokenUpdateKey方法改变了

image-20250704200337473

要是能调用这个函数105次就好了

调用需要的函数可以使用frida或者dll注入,官方wp上用的是dll注入

这是GameAssembly.dll里导出的函数,截了一部分

image-20250707095620034

很多都是以il2cpp开头的,这种il2cpp_XXXX_XXXX_XXX形式的都是il2cpp源码中有的API函数

il2cpp-Mirror/il2cpp-v24.3/libil2cpp/il2cpp-api.cpp at master · WuFengXue/il2cpp-Mirror

先挂一下地址

image-20250707172435072

我们可以结合上面的函数调用API来写一个dll注入

因为这里GameAssembly.dll已经能打印这些函数了,所以我们可以用GetProcAddress 拿到地址,这个是系统的一个API 函数,它能从指定的dll 检索导出函数或变量的地址。

为什么要拿地址呢因为我们只有il2cpp.h这个文件只有函数声明,没有任何地方告诉编译器这个函数具体在哪儿实现(本地代码或外部 DLL),所以要用这个拿到地址

写了半天的dll注进去没成功,我笑死了咋这么命苦呢,气得我血压有点高。

不管了,加纳!

方法三

这个方法相当于frida了,因为这个项目本身是依赖于frida的

in1nit1t/uniref: A Python coding framework for analyzing Unity applications.

image-20250704155148183

直接pip安装就可以了

因为可以实时获取与修改类方法实现、调用类方法

写一个脚本调用需要的函数即可

1
2
3
4
5
6
7
8
9
10
11
12
13
from uniref import WinUniRef

if __name__ == "__main__":
f = WinUniRef("GameHack.exe")
class_GetFlag = f.find_class_in_image("Assembly-CSharp.dll", "Platformer.Flag.GetFlag")
class_GetFlag.find_field("goHome").value = True
class_GetFlag.find_field("findAlien").value = True
class_GetFlag.find_field("eatCookie").value = True

method_EatTokenUpdateKey = class_GetFlag.find_method("EatTokenUpdateKey")
for i in range(105):
method_EatTokenUpdateKey()
print("ok")

在task界面,运行代码改写值,再按getflag从而得到flag

image-20250704162551481

后面发现还有一个项目也是十分强大应该也可以用这个写,先记一下

vfsfitvnm/frida-il2cpp-bridge:一个 Frida 模块,用于在运行时转储、跟踪或劫持任何 IL2CPP 应用程序,而无需 global-metadata.dat 文件。

Android

同样是工具dump,这个只需要根据global-metadata.dat和libil2cpp.so来就可以了

几乎没什么区别,都是先dump再分析,最多global-metadata.dat上加了一个混淆

直接先看看题吧

[D3CTF 2022] D3MUG

泥萌音游党有福了。。。

拿到flag的条件是all perfect,以人类的角度来说应该不可能完成

image-20250707181638228

apk 解压后所看到的就是 arm64-v8a 和 armeabi-v7a,差不多就是 64位 和 32位的意思

先用工具dump一下,先点so文件,再点dat文件,方法都差不多

再恢复一下符号表

在恢复符号表的间隙先看看dump出来的Assembly-CSharp.dll,因为拿到flag的条件和分数没什么关系,主要准备从GameManager下手

image-20250707182321282

分析一下符号表恢复了的GameAssembly.dll,先搜索了一下这一类分析了NoteHit,

image-20250707200019940

看看更新了什么状态,啊嘞看着加载了其它模块里的方法,先放放

image-20250707202233700

看一下是什么引用了NoteHit,反正大概是先初始化东西,然后判定时间这个意思吧

image-20250707201837301

再往上引用基本都是游戏里面查看触碰的函数,先看看怎么引用d3mug里的update函数的

可以看到更新后返回的是Server::run里面的东西,根据上面看到的传递的v9是击打时间,所以是击打时间穿进去进行了加密,再点进去看看

image-20250707203859504

里面是一个伪随机数生成算法,梅森旋转算法(MT19937) 第一次见

image-20250707204305155

用assetstudio找打击时间这个我还是第一次遇到因为这种u3d碰到的也不多,其实是我题写太少了。

把apk解压后的文件放进去分析,搜了一下hit但是有三个运行一下程序可以发现是1608块的,找一个恰好有1608个的hitpoints就好了,第一列是轨道,第二列是击打时间

image-20250707210311452

呀嘞呀嘞,这个算法看着好难啊我服了,等着到时候让密码小姐姐教我吧O(∩_∩)O~~

MT19937(梅森旋转)实践训练-先知社区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <stdio.h>
#include <random>
#include <Windows.h>

using namespace std;

const DWORD hitp[] = { 0,0,0,146,292,292,439,512,585,585,658,731,804,878,1024,1170,1170,1317,1463,1463,1609,1682,1756,1756,1902,2048,2195,2341,2341,2487,2634,2634,2780,2853,2926,2926,3073,3146,3219,3219,3365,3439,3512,3512,3658,3804,3878,3951,4024,4097,4097,4243,4390,4682,4682,4682,4829,4975,4975,5121,5195,5268,5341,5414,5487,5560,5560,5853,5853,5999,6146,6146,6292,6365,6439,6439,6585,6731,6731,6731,7024,7024,7170,7317,7317,7463,7536,7609,7609,7682,7756,7829,7902,7902,7975,8048,8121,8195,8341,8487,8634,8780,9073,9073,9073,9219,9365,9365,9512,9658,9658,9804,9878,9951,9951,10097,10243,10243,10243,10390,10463,10536,10536,10682,10829,10829,10975,11121,11121,11268,11414,11414,11560,11707,11707,11853,11999,11999,11999,12146,12292,12292,12439,12439,12585,12585,12585,12731,12878,12951,13024,13097,13170,13170,13317,13463,13463,13463,13609,13756,13756,13756,13902,14048,14048,14195,14341,14487,14634,14634,14926,14926,14926,15219,15219,15219,15365,15365,15512,15512,15658,15804,15804,15951,16024,16097,16097,16170,16243,16317,16390,16390,16536,16682,16682,16829,16902,16975,16975,17121,17268,17268,17268,17414,17560,17634,17707,17780,17853,17926,17999,18073,18146,18146,18292,18439,18439,18731,18731,18731,18878,19024,19024,19024,19170,19243,19317,19463,19609,19609,19609,19756,19829,19902,20048,20195,20195,20341,20487,20487,20634,20780,20780,20926,21073,21073,21219,21365,21365,21365,21512,21585,21658,21658,21804,21951,21951,21951,22097,22243,22317,22390,22463,22536,22536,22609,22682,22756,22829,22829,22975,23121,23121,23268,23414,23560,23707,23780,23853,23926,23999,23999,24073,24146,24219,24292,24365,24439,24512,24585,24585,24731,24731,24878,24878,24878,25024,25170,25170,25317,25390,25463,25463,25609,25756,25756,25756,25902,25902,26048,26048,26195,26195,26341,26341,26414,26487,26487,26560,26634,26634,26780,26780,26926,27219,27512,27585,27658,27731,27804,27804,28097,28097,28390,28682,28682,28975,29268,29268,29560,29560,29853,29853,30146,30439,30439,30731,31024,31024,31317,31609,31609,31902,32195,32195,32487,32780,32780,32780,33365,33365,33365,33951,33951,34243,34536,34536,34829,35121,35121,35414,35707,35707,35707,35999,36292,36585,36878,36878,37024,37024,37170,37170,37463,37463,37463,37609,37756,37756,37902,38048,38048,38195,38341,38341,38487,38634,38634,38780,38926,39073,39219,39365,39512,39658,39804,39804,39951,40097,40097,40243,40390,40390,40536,40682,40829,40975,40975,41121,41268,41414,41560,41707,41853,41999,42146,42146,42292,42292,42439,42585,42731,42731,42878,42878,43024,43170,43317,43317,43463,43463,43609,43609,43682,43756,43756,43829,43902,43902,44048,44048,44195,44195,44341,44341,44487,44560,44634,44707,44780,44853,44926,44999,45073,45146,45219,45292,45365,45439,45512,45585,45658,45658,45804,45951,45951,46097,46243,46243,46536,46536,46536,46829,46829,46902,46975,47121,47121,47268,47414,47414,47560,47634,47707,47707,47853,47926,47999,47999,48146,48292,48292,48439,48585,48585,48731,48878,48878,49024,49170,49170,49243,49317,49463,49463,49609,49756,49756,49902,49975,50048,50048,50121,50195,50268,50341,50341,50487,50487,50707,50707,50926,50926,51073,51219,51365,51512,51512,51585,51658,51804,51804,51951,52097,52097,52170,52243,52317,52390,52390,52536,52609,52682,52682,52829,52975,52975,53121,53268,53268,53414,53560,53560,53707,53853,53853,53926,53999,54073,54146,54146,54219,54292,54365,54439,54439,54512,54585,54658,54731,54731,54878,54878,55024,55024,55024,55317,55317,55317,55609,55609,55609,55902,55902,55902,56195,56268,56341,56487,56487,56634,56780,56780,56926,56999,57073,57073,57219,57292,57365,57365,57512,57658,57658,57804,57951,57951,58097,58243,58243,58390,58536,58536,58609,58682,58829,58829,58975,59121,59121,59268,59341,59414,59414,59560,59634,59707,59707,59853,59926,59999,59999,60073,60292,60292,60439,60585,60585,60731,60878,60878,60951,61024,61024,61170,61170,61317,61317,61463,61463,61463,61536,61609,61609,61756,61756,61902,61902,62048,62048,62048,62121,62195,62195,62341,62341,62414,62487,62560,62634,62634,62780,62780,62926,62926,63073,63073,63219,63219,63292,63365,63439,63512,63512,63585,63658,63731,63804,63804,63878,63951,64024,64097,64097,64170,64243,64317,64390,64390,64536,64536,64609,64682,64829,64975,65121,65268,65414,65560,65560,65707,65853,65999,66146,66146,66439,66585,66878,67170,67317,67317,67609,67902,68048,68195,68341,68487,68487,68780,68926,69073,69219,69365,69512,69658,69658,69804,69951,70243,70390,70536,70682,70829,70829,71121,71268,71560,71853,71999,71999,72292,72585,72731,72878,73024,73170,73317,73463,73609,73609,73756,73975,74195,74341,74341,74634,74707,74780,74926,74926,75073,75073,75219,75219,75219,75365,75512,75512,75658,75658,75804,75804,75804,75951,76097,76097,76390,76390,76390,76536,76682,76682,76829,76829,76975,76975,76975,77268,77268,77414,77560,77560,77561,77707,77853,77853,77999,77999,78146,78146,78146,78292,78439,78439,78731,78732,78732,78878,79024,79024,79170,79171,79317,79317,79463,79609,79609,79756,79902,79902,80048,80195,80341,80341,80487,80487,80634,80780,80780,80926,80926,81073,81073,81073,81219,81365,81512,81512,81658,81658,81658,81951,81951,81951,82097,82243,82243,82390,82536,82682,82682,82829,82829,82829,82975,83121,83121,83268,83414,83414,83560,83707,83853,83853,83999,83999,83999,84292,84292,84365,84439,84512,84585,84585,84731,84804,84878,84878,84951,85024,85097,85170,85170,85317,85390,85463,85463,85536,85609,85682,85756,85756,85829,85902,85975,86048,86048,86121,86195,86268,86341,86341,86487,86634,86634,86707,86780,86853,86926,86926,87073,87146,87219,87219,87292,87365,87439,87512,87512,87658,87804,87804,87878,87951,88024,88097,88097,88170,88243,88317,88390,88390,88536,88609,88682,88682,88829,88975,88975,89121,89121,89268,89268,89414,89414,89560,89560,89707,89707,89853,89853,89999,89999,90146,90146,90292,90292,90439,90439,90585,90585,90731,90731,90878,90878,91024,91024,91170,91170,91317,91317,91390,91463,91536,91609,91682,91756,91829,91902,91975,92048,92121,92195,92268,92341,92634,92780,92926,93219,93365,93365,93365,93365,93658,93658,93804,93878,93951,93951,94097,94243,94317,94390,94463,94536,94536,94682,94829,94829,94975,95121,95121,95268,95414,95487,95560,95634,95707,95707,95853,95853,95999,95999,96146,96292,96292,96292,96439,96585,96585,96658,96731,96804,96878,96878,97024,97170,97170,97317,97390,97463,97463,97609,97756,97756,97829,97902,98048,98048,98048,98195,98341,98341,98487,98560,98634,98634,98780,98926,98926,99073,99219,99219,99365,99512,99512,99658,99804,99804,99951,100097,100170,100243,100317,100390,100390,100536,100682,100682,100829,100975,100975,100975,101121,101268,101268,101341,101414,101487,101560,101560,101707,101853,101853,101926,101999,102073,102146,102146,102292,102439,102439,102439,102585,102658,102731,102731,102878,103024,103024,103024,103170,103243,103317,103317,103317,103463,103609,103682,103756,103829,103902,103902,104048,104195,104195,104341,104487,104487,104487,104634,104780,104853,104926,104999,105073,105073,105219,105365,105365,105512,105658,105658,105658,105804,105951,105951,106097,106170,106243,106243,106317,106390,106536,106536,106682,106756,106829,106829,106829,106975,107121,107121,107268,107268,107414,107414,107414,107560,107707,107707,107707,107853,107999,107999,107999,108146,108292,108292,108439,108585,108585,108731,108878,108878,108878,109024,109170,109170,109317,109463,109463,109536,109609,109682,109756,109756,109902,110048,110048,110048,110195,110195,110341,110341,110341,110487,110487,110634,110634,110634,110780,110780,110926,110926,110926,111073,111073,111219,111219,111219,111365,111512,111658,111731,111804,111878,111951,112024,112097,112097,112097,112390,112390,112536,112682,112682,112682,112829,112975,112975,113121,113268,113268,113414,113560,113560,113707,113853,113853,113999,114146,114219,114292,114365,114439,114439,114585,114731,114731,114878,115024,115024,115024,115170,115317,115317,115463,115536,115609,115609,115756,115902,115902,115975,116048,116121,116195,116195,116268,116341,116414,116487,116487,116560,116634,116707,116780,116780,116926,117073,117073,117219,117365,117365,117512,117658,117658,117804,117878,117951,117951,118097,118243,118243,118390,118536,118536,118682,118829,118902,118975,119048,119121,119121,119268,119414,119414,119560,119707,119707,119853,119999,119999,120146,120292,120292,120439,120439,120731,121024,121170,121463,121536,121609,121682,121756,121756,121756,121902,122048,122048,122048,122195,122341,122341,122341,122487,122560,122634,122634,122634,122780,122926,122926,122926,123073,123219,123219,123219,123365,123512,123512,123512,123585,123658,123731,123804,123804,123804,123951,124097,124097,124097,124243,124390,124390,124390,124536,124682,124682,124682,124829,124975,124975,124975,125121,125268,125268,125268,125414,125487,125560,125560,125560,125707,125853,125853,125853,125999,126146,126146,126146,126292,126439,126439,126439,126585,126585,126731,126731,126878,126878,127024,127024,127024,127170,127170,127317,127317,127463,127463,127609,127609,127609,127756,127756,127902,127902,128048,128048,128195,128195,128268,128341,128341,128414,128487,128487,128560,128634,128707,128780,128780,128853,128926,128999,129073,129146,129219,129292,129365,129365,129439,129512,129585,129658,129731,129804,129878,129951,129951,130024,130097,130170,130243,130243,130317,130390,130463,130536,130536,130682,130756,130829,130829,130829,130975,130975,131121,131195,131268,131341,131560,131707,131707,131780,131853,131926,132146,132292,132365,132439,132512,132731,132878,132878,132951,133024,133097,133463,133463,133756,134048,134048,134048,134341,134634,134634,134926,134926,135219,135219,135219,135512,135512,135658,135658,135804,135804,135951,135951,136097,136097,136243,136243,136390,136390,136536,136536,136609,136682,136682,136829,136829,136902,136975,136975,137121,137121,137268,137268,137414,137414,137560,137560,137707,137707,137780,137853,137926,137999,137999,138073,138146,138146,138219,138292,138365,138439,138439,138512,138585,138658,138731,138731,138804,138878,138951,139024,139024,139097,139170,139243,139317,139317,139463,139463,139609,139609,139756,139756,139902,139902,140195,140195,140195,140195 };

DWORD __ROR4__(DWORD a1, char a2)
{
return (a1 >> a2) | (a1 << (32 - a2));
}

int rounds(uint8_t* bytes, unsigned int a2, int a3)
{
DWORD* v3; // r4
DWORD v4; // r12
DWORD v5[2]; // r5
DWORD v6; // r3
DWORD result; // r0

v3 = (DWORD*)((char*)bytes + a3);
v4 = *(DWORD*)((char*)bytes + a3);
*(DWORD64*)&v5[0] = *(DWORD64*)((char*)bytes + a3 + 4);
v6 = *(DWORD*)((char*)bytes + a3 + 12);
*(DWORD*)((char*)bytes + a3) = *(&v5[0] + 1);
result = v4 ^ __ROR4__(*(&v5[0] + 1) ^ a2, 19);
v3[3] = v5[0] ^ __ROR4__(v6, 18) ^ __ROR4__(*(&v5[0] + 1) ^ a2, 19);
v3[1] = v6;
v3[2] = result;
return result;
}

int main(int argc, char const* argv[])
{
unsigned char enc_bytes[] =
{
0x3C, 0xAC, 0x92, 0x6F, 0x44, 0xA1, 0xC1, 0x17, 0xFD, 0x62,
0x60, 0xDD, 0x63, 0xF8, 0xE3, 0x2A, 0x5E, 0x75, 0x78, 0xBE,
0x59, 0x46, 0x33, 0xF6, 0x2E, 0x64, 0x61, 0x8A, 0x27, 0x93,
0x21, 0x7D, 0x00
};
mt19937 rng(-196167794);
for (int i = 0; i < 1608; ++i)
{
if (rng() % 7 >= 3)
{
rounds(enc_bytes, rng(), hitp[i] & 0xF);
}
}
printf("%s\n", enc_bytes);
getchar();
return 0;
}

其实update函数也可以直接调用,用frida写个脚本就行了

虽然这学期学了但是试了好久一直不行,算了下学期带个真机来试试^_^

但是这道题确实分析了好久,有个疑惑是分析了好久的0.02最后好像没有用,可能有别的做法吧,我太笨了没想出来捏::>_<::

[N1CTF2018] baby unity3d

这道题就是dat文件给加密了一下,这道题真不错O(∩_∩)O~~

一般正常的dat文件开头四字节都是 AF 1B B1 FA,010打开发现这个被加密过了

1
注意,IL2CppDumper是使用C#写的,C#在windows平台上是小端字节序,即数据的高字节保存在内存的高地址中,我们上面使用010Editor看二进制文件的时候,从左到右地址是升高的,所以上面的AF 1B B1 FA对应到C#代码中就是0xFAB11BAF,不要搞反了哦。

Il2cpp逆向:global-metadata解密-腾讯云开发者社区-腾讯云

看到这篇文章的思路特别好,膜拜

有两条一个是用frida找程序运行时文件头AF 1B B1 FA,因为有可能程序运行时把它解密了dump出解密后的文件,但是这题没有用

另一是根据dat的加载流程分析,先记一下又学到了捏

1
2
3
4
il2cpp_init
-> il2cpp::vm::Runtime::Init
-> il2cpp::vm::MetadataCache::Initialize
-> il2cpp::vm::MetadataLoader::LoadMetadataFile

后续的就是分析函数了,就略过了

总结

其实总的来看就是围绕这几个文件分析,会个大概思路就行。

突然想起来起因是做到一个rpg游戏想放一起对比的,后来发现那个游戏思路也差不多用ce断一下,在内存里找加密,就先不再赘述了。

麻鸭最近花太多时间在这上面了,可能是期末考试把这个战线拉得特别长了,而且有些题确实让我涨知识了,之前没写过dll,也没了解过系统里面的函数啥的,虽然最后也没成功给我起得要高血压了。。