Unity游戏:在exe中嵌入的Assembly dll

逆向工程 dll 。网 游戏黑客
2021-06-17 09:20:40

我正在尝试对使用 Unity 引擎制作的游戏进行逆向工程,通常所有游戏的脚本都在文件\<Game>_Data\Managed\Assembly-CSharp.dll\<Game>_Data\Managed\Assembly-CSharp-firstpass.dll. 但是这个游戏在托管目录中没有程序集dll。

我尝试使用 dnSpy 反编译 exe,但看起来里面没有任何 .NET 程序集:

我还使用进程监视器来检查游戏是否加载了任何其他 .dll,但它没有。但是,使用 Cheat Engine 的单声道解析器功能,我可以看到两个程序集 dll 以及其中的所有类和方法:

所以我的假设是 dll 以某种方式嵌入在 exe 中,并在游戏开始时加载到内存中。

我用 x64dbg 调试了游戏的可执行文件,搜索了“Assembly-Csharp”的字符串引用,并在我认为加载了 dll 的位置放置了一个断点,然后发现了这个:

我用 ghidra 反编译了这部分程序,得到了这个:(我也用 x64dbg 反编译了它,得到了类似的结果,减去了变量名)

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;
}

现在我被卡住了,我正在寻找一种方法来从 exe 中提取这个 dll(如果它在里面),然后反编译为 C#。或者,我想知道是否有办法反编译作弊引擎随单声道解剖器工具提供的 IL 代码,并将其转换为可读的 C#。

我几乎是逆向工程的新手,所以我确定我错过了很多东西,欢迎任何帮助。

3个回答

Nexide,疯狂猜测,但您的游戏符合 il2cpp。您可以使用 Scylla 转储 GameAssembly.DLL,您将获得一个哑文件夹,然后使用 Il2cppDumper,将 Globalmeta.dat 文件和 GameAssembly.dll-Dumped 文件拖到所有 il2cppdumper dll 所在的位置,然后运行Il2cppdumper 然后按 GameAssembly.dll 然后按 Globalmeta 数据,你会得到一个带有 Csharpassembly 和其他所有东西的虚拟 dll,但你实际上不会从中得到实际的代码,只有偏移量和方法,你必须使用 Ida 反向亲获取本机代码,不知道有没有其他的反编译方法

我成功地使用MegaDumper转储了所有的 dll ,我不得不自己编译它,因为没有提供二进制文件。

您可以使用de4dot,它最好恢复打包的程序集,如果解压文件失败,请尝试使用x64dbgScyllaHide插件来转储和恢复 dll。

编辑:Win32的翻斗没有装配显示.Net和需要的.Net自卸车像MegaDumper OR ExtremeDumper