unity 反编译_【游戏安全】记一次Unity游戏逆向

作者论坛账号:二娃

游戏是steam上一款单机音游,难度有点高,在被虐了千百次后,我决定对这个游戏下手。

探秘

大家都知道,unity游戏的主要逻辑都在Assembly-CSharp.dll,只要用dnspy之类的工具就能够轻易的反编译出源码。于是我兴冲冲的掏出了我的dnspy,将Assembly-CSharp.dll拖了进去,然而一片空白的dnspy告诉我事情没这么简单。

8a06ddf157727d3f7ba15b8946185bb8.png

使用010 editor打开文件,发现并不是标准的PE格式,DOS头的标志MZ被修改为了ML。

3753ccb1cb193a3f402de677d04b210a.png

那就老规矩,开启游戏,对mono.dll的mono_image_open_from_data_with_name下断点观察,结果发现游戏并没有在这部分解密PE文件。抱着不想的预感,使用CE搜索了一下这个游戏的前几个字节,结果不出意料。

8f636af3484339c2ab450605f2b5268a.png

可以看到游戏并没有直接解密文件,外面长啥样内存里还是啥样。看来游戏应该是对mono的代码进行了修改,用自己的规则来加载文件。那没有办法,只能老老实实的跟着代码走一遍。

解密

将mono.dll拖进IDA,一般加载dll都会走到mono_image_open_from_data_with_name,所以我们直接定位到这里,然后从github下了一份mono的源码作为对照。顺着流程走下去会走到do_mono_image_load函数,这个函数就是用来解析加载dll文件的。

PEHeader部分

首先看到pe_image_load_pe_data,这个函数是用来解析PE Header部分的,通过对比可以看出这个函数与源码不一样,是被修改过的,ida F5代码如下

_BOOL8 __fastcall pe_image_load_pe_data(__int64 image){
    
  char *header; // rdi
  __int64 v2_image; // rbx
  signed int section_table_offset; // eax
  _BOOL8 result; // rax
  char data[128]; // [rsp+20h] [rbp-88h]

  header = *(char **)(image + 0x50);
  v2_image = image;
  result = 0;
  if ( *(_DWORD *)(image + 24) >= 0x80u )       // raw_data_len
  {
    memmove(data, *(const void **)(image + 16), 0x80ui64);// raw_data
    if ( data[0] == 'M' && data[1] == 'L' )
    {
      section_table_offset = do_load_header(v2_image, header, *(_DWORD *)&data[0x3C] - 0x4D4C);// NtHeader offset - 0x4D4C
      if ( section_table_offset >= 0 )
      {
        if ( (unsigned int)load_section_tables(v2_image, (__int64)header, section_table_offset) )
          result = 1;
      }
    }
  }
  return result;

首先可以看到被修改过的mono在识别DOS头标志的时候用的不是MZ而是ML,与修改过的dll文件一致,然后在读取0x3c位置也就是NtHeader偏移值的时候减去了0x4D4C。do_load_header主要是记录一下IMAGE_NT_HEADERS结构,与源码没什么太大的差异,唯一的区别就是在识别NtHeader标志的时候用的不是PE而是ML,与修改过的dll一致。

signed __int64 __fastcall do_load_header(__int64 image, char *header, int e_lfanew){
    
  __int64 v3; // rdi
  char *v4_header; // rbx
  __int64 v5; // rsi
  unsigned int section_table_offset; // edi
  int v8; // er11
  int v9; // eax
  char Dst; // [rsp+20h] [rbp-D8
  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值