I'm trying to reverse engineer a game made with the Unity engine, and usually all of the games's scripts are in the files \<Game>_Data\Managed\Assembly-CSharp.dll
and \<Game>_Data\Managed\Assembly-CSharp-firstpass.dll
. However this game doesn't have the assembly dll in the managed directory.
I tried decompiling the exe with dnSpy but it doesn't look like there is any .NET assembly inside:
I also used Process Monitor to check if the game loads any other .dll but it doesn't. However, using Cheat Engine's mono dissector function I can see the two assembly dll's and all the classes and methods inside:
So my hypothesis is that the dll is embedded inside the exe somehow and loaded to the memory when the game starts.
I debugged the game's executable with x64dbg, searched for string references for "Assembly-Csharp" and put a breakpoint where I think the dll is loaded, and found this:
I decompiled this part of the program with ghidra and got this: (I also decompiled it with x64dbg and got a similar result minus the variables names)
undefined * FUN_1401a0070(undefined *puParm1,void **ppvParm2,undefined8 uParm3,undefined8 uParm4)
{
char cVar1;
char cVar2;
char *pcVar3;
longlong lVar4;
void **ppvVar5;
undefined **ppuVar6;
int iVar7;
bool bVar8
; int iVar9;
undefined in_stack_ffffffffffffffb8;
undefined uVar10;
undefined7 in_stack_ffffffffffffffb9;
int in_stack_ffffffffffffffc0;
undefined8 local_38;
ulonglong local_30;
iVar7 = 0;
ppuVar6 = &PTR_s_Managed/Assembly-CSharp.dll_140f42ad8;
do {
pcVar3 = (char *)FUN_140007820();
iVar9 = (int)uParm4;
bVar8 = SUB81(uParm3,0);
lVar4 = -(longlong)pcVar3;
do {
cVar2 = *pcVar3;
cVar1 = pcVar3[(longlong)(*ppuVar6 + lVar4)];
if (cVar2 != cVar1) break;
pcVar3 = pcVar3 + 1;
} while (cVar1 != '\0');
if (cVar2 == cVar1) {
lVar4 = -1;
local_30 = 0xf;
local_38 = 0;
uVar10 = 0;
pcVar3 = (&PTR_s_StreamingAssets/OtherAssets/Back_140f42ae8)[(longlong)iVar7];
goto code_r0x0001401a012d;
}
ppuVar6 = ppuVar6 + 1;
iVar7 = iVar7 + 1;
} while ((longlong)ppuVar6 < 0x140f42ae8);
*(undefined8 *)(puParm1 + 0x18) = 0xf;
*(undefined8 *)(puParm1 + 0x10) = 0;
*puParm1 = 0;
FUN_14000b310(puParm1,ppvParm2);
goto LAB_1401a01a0;
while( true ) {
lVar4 = lVar4 + -1;
cVar2 = *pcVar3;
pcVar3 = pcVar3 + 1;
if (cVar2 == '\0') break;
code_r0x0001401a012d:
if (lVar4 == 0) break;
}
FUN_14000a8f0(&stack0xffffffffffffffb8);
cVar2 = FUN_1402d8ab0(&stack0xffffffffffffffb8);
*(undefined8 *)(puParm1 + 0x18) = 0xf;
*(undefined8 *)(puParm1 + 0x10) = 0;
ppvVar5 = (void **)&stack0xffffffffffffffb8;
if (cVar2 == '\0') {
ppvVar5 = ppvParm2;
}
iVar9 = -1;
bVar8 = false;
*puParm1 = 0;
FUN_140009870(puParm1,ppvVar5);
if (0xf < local_30) {
operator_delete((void *)CONCAT71(in_stack_ffffffffffffffb9,uVar10),(MemLabelId)0x3b,bVar8,iVar9,
(char *)CONCAT71(in_stack_ffffffffffffffb9,uVar10),in_stack_ffffffffffffffc0);
}
local_30 = 0xf;
local_38 = 0;
in_stack_ffffffffffffffb8 = 0;
LAB_1401a01a0:
if (&DAT_0000000f < ppvParm2[3]) {
operator_delete(*ppvParm2,(MemLabelId)0x3b,bVar8,iVar9,
(char *)CONCAT71(in_stack_ffffffffffffffb9,in_stack_ffffffffffffffb8),
in_stack_ffffffffffffffc0);
}
*(undefined **)(ppvParm2 + 3) = &DAT_0000000f;
ppvParm2[2] = (void *)0x0;
*(undefined *)ppvParm2 = 0;
return puParm1;
}
And now I'm stuck, I'm looking for a way to extract this dll from the exe (if it's inside at all) and then decompile to C#. Alternatively I would like to know if there is a way to decompile the IL code that cheat engine provides with the mono dissector tool, and translate it to readable C#.
I'm pretty much a novice in reverse engineering so I'm sure I missed a lot of stuff, any help is welcome.