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 '19 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 '19 at 17:52
1

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

|improve this answer|||||
  • Could you share your method and the compiled binary please? – Benjy Sep 10 '19 at 22:17
  • binary: mediafire.com/file/b2zr9cusc6sreom/Mega_Dumper.zip/file this is MegaDumper and Universal Fixer and DeObfuscator all SND tools. – SSpoke Mar 25 at 2:47
  • I would not trust that download link (no offense), just open the megadumper project in visual studio and compile it – nexide Mar 26 at 4:21
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.

Edit: Win32 dumper doesn't show .Net assembly and need a .Net dumper like MegaDumper OR ExtremeDumper

|improve this answer|||||
  • 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 '19 at 13:47
  • 2
    Yeah de4dot is actually a deobfuscator for .NET FILES... It won't extract a .NET file out of a non-.NET file... You'd need a dumper.. Oh look, your answer below, you used MegaDumper :) – the_endian Mar 12 at 18:27

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.