CTF 中一般遇到的 Unity 逆向会遇到两种模式,一种是 Mono, 另外一种是 IL2CPP。两者都是 Unity 引擎用于将 C# 代码转换成可以在不同平台上运行代码的后端编译模式
有关 Mono 与 IL2CPP,这篇文章讲得比较详细了 浅谈Unity与.Net、Mono、IL2CPP
如果用 mono 编译的话一般是如下的结构(本题即是)


Data 里面的结构大致是这样的

逆向分析一般是看 Managed 目录下的 Assembly-CSharp.dll 这个文件,默认情况下它是绝大多数 C# 脚本文件编译打包后生成的动态链接库文件,游戏的逻辑代码基本都在这里面
用 dnSpy 打开之后就可以看到 C# 的代码了
第一关是要打开倒计时五天的那个门
找到倒计时部分的代码

分析 _countdownText, 找到这部分代码
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
|
private void Update() { if (!this._playerCamera || !this._mountedObject || !this._countdownText) { return; } if (!this._openingTriggered) { Vector3 vector = this._playerCamera.position - base.transform.position; if (vector.magnitude > 5f) { return; } vector.Normalize(); float num = Vector3.Angle(base.transform.forward, vector); if (150f > num || num > 210f) { return; } this._openingTriggered = true; this._isCountingDown = true; } if (this._isCountingDown) { this._accumulatedTime += Time.deltaTime; if (this._accumulatedTime >= 1f) { int num2 = Mathf.FloorToInt(this._accumulatedTime); this._remainingTime -= (float)num2; this._accumulatedTime -= (float)num2; this.UpdateCountdownText(); } if (this._remainingTime <= 0f) { this._remainingTime = 0f; this._countdownText.text = "Opening"; this._isCountingDown = false; this._isOpening = true; this._openingElapsed = 0f; } } if (this._isOpening) { if (this.openDuration <= 0f) { this._mountedObject.localPosition = this._mountedTargetPos; this._isOpening = false; return; } if (this._openingElapsed < this.openDuration) { this._openingElapsed += Time.deltaTime; float num3 = Mathf.Clamp01(this._openingElapsed / this.openDuration); this._mountedObject.localPosition = Vector3.Lerp(this._mountedStartPos, this._mountedTargetPos, Door1.SmoothStep(num3)); return; } this._mountedObject.localPosition = this._mountedTargetPos; this._isOpening = false; } }
|
在 dnSpy 中修改代码,跳过倒计时,选择编辑类,然后把上面的逻辑改成
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| if (150f > num || num > 210f) { return; } this._openingTriggered = true; this._remainingTime = 0f; this._countdownText.text = "Opening"; this._isCountingDown = false; this._isOpening = true; this._openingElapsed = 0f; } if (this._isCountingDown)
|
修改好后编译,再在文件中选择全部保存,这时候重新打开游戏就可以跳过五天的倒计时直接开门,flag 就在旗杆后面

第二关的 flag 是在纹理里面

使用 AssetRipper 提取纹理,打开 Simu_Data 文件夹,在 sharedassets0.assets 里面看到 Texture2D FLAG2


第三关是用插件没搞出来, 然后选择了修改跳跃高度

直接给 JumpHeight 乘以 10 就可以飞天了,爽

