> Collect green stuff, avoid red guys. Easy as pie, right? Not even your speedhacks will help you here! You might have to take a closer look and inspect it carefully. Have fun & good luck!
This challenge is a game, according to its description. Since I gave up on the challenge I was trying to do (NOdeBANKing), I went to help other teammates blocked on this challenge.
This game was using Unity3D as engine, where game logic is usually written in C# or other language that compiles to MSIL. So let's find the GameAssembly.dll, but no luck it's a native DLL and not a managed one... After opening it in IDA Free, I noticed "il2cpp_" references, and after some googling, figured out it was a tool that compile MSIL code to native x86 code.
I first thought that the game "logic" could actually be embedded in resources (the "data.unity3d" file in CSRunner_Data), but I failed to find a tool able to open the new UnityFS format, all I got was weird lz4 invalid stream issues coming from nowhere.
So, I looked for a tool able to reconstruct metadata of the "original" assembly, and finally came across [Il2CppDumper](https://github.com/Perfare/Il2CppDumper), which even comes with an IDAPython script to rename funcs and add types in IDA Pro. I used that tool to generate "dummy" assemblies that could be opened in dnSpy, even if there was no MSIL code in the assemblies, but it's a good starting point to understand the class structure.
And the tool also comes with IDAPython scripts to rename il2cpp-converted functions, which I could use since I managed to compile IDAPython and make it run on my IDA Free 7.6. I first explored Game methods, which only seemed to print debug messages stuff even if `PickupHit` and `PickupMiss` methods looked promising.
But there was another class with interesting name, `DieOnCollision`, which seemed to handle collisions, I looked at the `DieOnCollision$$OnCollisionEnter` and saw this:
```cpp    tag = UnityEngine_GameObject__get_tag(gameObject, 0i64);    if ( System_String__op_Equality(tag, StringLiteral_4306, 0i64) )    {        if ( !byte_180A0BB4F )        {        sub_1801292D0(5488i64);        byte_180A0BB4F = 1;        }        instance = Game_TypeInfo->static_fields->instance;        if ( instance )        {        v9 = DieOnCollision_TypeInfo;        if ( (DieOnCollision_TypeInfo->_2.bitflags2 & 2) != 0 && !DieOnCollision_TypeInfo->_2.cctor_finished )        {            il2cpp_runtime_class_init(DieOnCollision_TypeInfo, v7);            v9 = DieOnCollision_TypeInfo;        }        PHRASES_ENEMY = v9->static_fields->PHRASES_ENEMY;        if ( PHRASES_ENEMY )        {            v11 = UnityEngine_Random__RandomRangeInt(0, PHRASES_ENEMY->max_length, 0i64);            v12 = v11;            if ( (unsigned int)v11 >= LODWORD(PHRASES_ENEMY->max_length) )            {            v32 = sub_180129250();            sub_1801293E0(v32, 0i64);            }    LABEL_15:            Game__GameOver(instance, PHRASES_ENEMY->m_Items[v12], 0i64);            return;        }        goto LABEL_50;        }    }```
So I just had to force the `if ( System_String__op_Equality(tag, StringLiteral_4306, 0i64) )` condition to be always false (patching the `jz      loc_1806E612D` at `0x1806e6078` to a jmp), and colliding with enemies would do nothing.
Then I gave the modified assembly to our team's pro gamer (since I run Linux, and couldn't manage to get the tool mentioned before on `GameAssembly.so` of the Linux version), which was able to get the flag in two game tries.
Author: [supersnail](https://github.com/aaSSfxxx)