1

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.

  • Did you try Resource Hacker to extract the dll from exe? – Biswapriyo Jun 24 at 16:02
  • Yes I did, among other things. I've pretty much tried every known packer and I think it's going to need a lot more reverse engineering to be extracted. – nexide Jun 24 at 17:52
1

You can use de4dot, its best to restore a packed assembly, if failed to unpack files try x64dbg and ScyllaHide plugin to dump and restore the dll with following the steps:

  1. open the file in x64dbg
  2. goto plugins -> Scylla
  3. click on "Pick DLL"
  4. select dll from the list
  5. click on "Dump"
  6. save and done!

for identify packers and more info check this tools: - detect it easy - exeinfo

  • de4dot shows this error "WARNING: The file isn't a .NET PE file" and Scylla doesn't show Assembly-CSharp.dll in the dlls list – nexide Jun 25 at 13:47
0

I successfully dumped all the dlls using MegaDumper, I had to compile it myself since there are no binaries provided.

  • Could you share your method and the compiled binary please? – Benjy Sep 10 at 22:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.