实例解说未知游戏文件花样的逆向剖析要领(上) | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

实例解说未知游戏文件花样的逆向剖析要领(上)

申博_新闻事件 申博 106次浏览 未收录 0个评论

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

媒介

当人们对未知文件花样举行逆向剖析时,一般倾向于运用现成的提取器,然则,偶然关于所议论的花样并没有大众信息可用(比方,当开发公司运用自身特别的花样来珍爱文件时),而且,文件花样能够存在伟大的差别,这时候,我们就不得不自身着手举行逆向剖析了。而本教程的目标,就是向读者展现逆向剖析未知花样文件的基础步调。

先决前提

为了顺利完成本文的义务,须要读者相识以下言语:

· C++言语

· x86汇编言语(Intel语法)

关于本文触及内容,我会全力给出浅显的诠释,然则,读者最好对上述言语有所相识。

所需东西

本文中将用到以下东西:

· HexEdit(或其他十六进制编辑器)

· OllyDBG(须要用到Stealth64插件)

· IDA Pro(我运用的是6.8版本)和Hex-Rays Decompiler

这里,我们假定读者关于这些东西都能闇练运用。

那末,我们将要做些甚么呢?

我们将剖析Brawl Busters用于珍爱其数据的文件花样。Brawl Busters是一款行动格斗游戏,如今已下架,荣幸的是,我们能够经由过程Google搜刮轻松找到它。

在本文中,我还将供应很多的伪代码,以演示怎样经由过程我们的逆向剖析效果来制造响应的提取器。

搭建试验情况

下载游戏后,先翻开其装置文件夹,然后翻开个中的“bin”文件夹。这时候,将看到一个名为“pbclient.exe”的文件,它就是游戏客户端。

我已上传了pbclient.exe的修补版本,这也是我一向在用的版本。现实上,我只是修补了一些前提跳转以防备XTrap被加载。在bin文件夹中,将pbclient.exe重定名为您喜好的称号,然后将修补后的pbclient.exe放入该文件夹中。

实例解说未知游戏文件花样的逆向剖析要领(上)

完成后上面的事变后,我们就预备好了完整一致的装置文件夹。好了,该着手了!

如今,请细致考核根文件夹,看看可否找出现实游戏数据的存储地位。就本例来讲,这彷佛不是甚么难事,因为个中有一个“Data”文件夹,以是,无妨翻开该文件夹,看看内里究竟是甚么:

实例解说未知游戏文件花样的逆向剖析要领(上)

这里看起来确切像是游戏数据!若是向下转动,还会看到一些配置文件(.ini)和一些图象(比方Splash.png)。

这个文件夹中的大多数文件都有一个新鲜的.bus扩展名,彷佛存储了大批的UI数据。而这些数据,恰是我们感兴趣的内容。

关于初学者来讲,.bus意味着甚么呢?别忘了,该游戏的称号为“Brawl Busters”,因而“.bus”极能够就是“.busters”的简写。

到如今为止,虽然我们还没有举行太多的探究,但已晓得游戏将大部分数据都存储在.bus文件中,而且这些文件看起来像是采用了专有花样(因为从Google中搜不到任何这方面的信息)。

那末,这些花样的文件究竟长啥样呢?如今,该十六进制编辑器上场了。在运用记事本之前,我老是先运用这些范例的编辑器,因为这些文件一般没法作为纯文本文件读取。让我们先翻开一个身量较小的文件,好比“Anim.bus”:

实例解说未知游戏文件花样的逆向剖析要领(上)

这里彷佛看不出甚么门道……数据彷佛是经由加密的。

让我们翻开一个大一些的文件,好比“Anim_Mob_Zombie_Unique_Heavy.bus”:

实例解说未知游戏文件花样的逆向剖析要领(上)

彷佛照样看不出甚么门道,不外,我们发明这两个文件有一个相似之处:每一个文件的前33个字节都为0。若是我们翻开更多的.bus文件,依旧会看到,它们的前33个字节都是用0添补得。这多是一个有效的细节,以是请记着它。

另外,另有另一个细节须要注重——若是向下转动到0x4ED0,会看到一些纯文本:

实例解说未知游戏文件花样的逆向剖析要领(上)

这就更让人感兴趣了!若是我们在互联网上搜刮“Gamebryo File Format, Version 20.6.0.0”,就会发明它是一种称为“NIF”(它代表的是NetImmerse File,但这其实不主要)的已知花样。

这些NIF文件彷佛是些模版(models),它们的纹理是运用DDS文件举行加载的。若是我们在HexEdit中搜刮“DDS”,我们也会取得一些效果,比方”texname=”FX_GhostTrail_A_00.dds”。这意味着某些.bus文件也会存储DDS文件。

一样,若是搜刮“Gamebryo”关键词,也会返回一些搜刮效果。我们能够从中得出甚么结论呢?好吧,.bus文件彷佛是存档(archives)文件,也就是说,它们会一次存储多个文件。文件数据之前的数据极多是用于举行加密操纵的元数据(有关存档自身及其内部文件的信息)。

让我们疾速回忆一下我们已猎取的信息:

大部分游戏数据都寄存在.bus文件中。

APT组织MuddyWater使用工具起底

简介 MuddyWater是一个APT组织,主要以中东国家的政府机构和电信部门为攻击目标,所染指的国家包括伊拉克、沙特阿拉伯、巴林、约旦、土耳其和黎巴嫩,也包含一些中东附近地区的国家,如阿塞拜疆、巴基斯坦和阿富汗等。 MuddyWater于2017年首次亮相,其间攻陷了众多组织机构,且至今一直处于活跃状态。该威胁团伙于第一阶段所使用的感染手法和诱饵文件已被众多安全机构分析过,我们在之前的文章——《MuddyWater再度扩大影响范围》中对其也有过描述。 然而,感染之后的过程的细节迄今为止还没有被公开过。MuddyWater融合了多种工具和技术来

这些.bus文件能够同时寄存多个文件,因而,它们现实上是文件存档。

该游戏运用Gamebryo引擎,因为存储的文件彷佛是NIF/KFM/DDS花样的文件(若是您想考证这一点,能够翻开其他文件并搜刮这三个关键字)。

下一步该做些甚么呢?我们必需弄清晰客户端是怎样解密/加载这些文件的。这是我们越发感兴趣的方面。

应用IDA Pro举行静态剖析

让我们回到“bin”文件夹,并经由过程IDA Pro翻开pbclient.exe来剖析该文件。

起首,我们要做的事变就是寻觅导入函数。那末,我们要找哪些导入函数呢?好吧,既然客户端必需翻开这些文件,因而极能够会运用诸如CreateFile或fopen之类的API。

下面,让我们最先搜刮第一个导入函数:

实例解说未知游戏文件花样的逆向剖析要领(上)

CreateFileMapping会接收一个文件句柄,该文件一般由API(如CreateFile)返回,因而,让我们交织援用该API。

我们找到的第一个援用就位于这个函数中:

(注重:为了便于明白,我将只管运用反编译器,虽然我们不克不及完整信任其输出内容,但至少能够相识函数的也许作用)

    char __userpurge [email protected]<al>(int [email protected]<eax>, HANDLE *[email protected]<edi>, _DWORD *a3, DWORD a4)
    {
      char v4; // [email protected]
      HANDLE v5; // [email protected]
      void *v6; // [email protected]
      char v7; // [email protected]
      DWORD v9; // [email protected]
      HANDLE v10; // [email protected]
      char v11; // [email protected]
      LPVOID v12; // [email protected]
      char v13; // [email protected]
      HANDLE hObject; // [sp+Ch] [bp-4h]@1
    
      v4 = 0;
      v5 = CreateFileA(*(LPCSTR *)(a1 + 20), 0x80000000, 1u, 0, 3u, 0, 0);
      v6 = v5;
      hObject = v5;
      if ( v5 == (HANDLE)-1 )
      {
        v7 = GetLastError();
        sub_40FB04();
        sub_4E7D8B(5, 16, "CreateFileA - Failed (%d)", v7);
        return 0;
      }
      v9 = GetFileSize(v5, 0);
      if ( a4 > 0 && v9 < a4 )
      {
        CloseHandle(v6);
        return 0;
      }
      v10 = CreateFileMappingA(v6, 0, 0x4000002u, 0, v9, 0);
      *a2 = v10;
      if ( !v10 )
      {
        v11 = GetLastError();
        sub_40FB04();
        sub_4E7D8B(5, 16, "CreateFileMappingA - Failed (%d)", v11);
        CloseHandle(hObject);
        return 0;
      }
      v12 = MapViewOfFile(v10, 4u, 0, 0, 0);
      *a3 = v12;
      if ( v12 )
      {
        v4 = 1;
      }
      else
      {
        v13 = GetLastError();
        sub_40FB04();
        sub_4E7D8B(5, 16, "MapViewOfFile - Failed (%d)", v13);
        CloseHandle(*a2);
      }
      CloseHandle(hObject);
      return v4;
    }

这个函数彷佛是依据指定文件名来建立文件的(个中,a1是一个字符串,稍后会细致引见)。若是没有发生毛病,a3参数将包罗内存映照文件(MapViewOfFile)的基地点。

让我们看一下CreateFileMappingA的第二个援用,它位于这个函数中:

    char __stdcall sub_52AE36(int a1, char a2, int a3, int a4, int a5, int a6, int a7)
    {
      HANDLE v7; // [email protected]
      void *v8; // [email protected]
      int v9; // [email protected]
      DWORD v10; // [email protected]
      const void *v11; // [email protected]
      int v12; // [email protected]
      const void *v13; // [email protected]
      int v14; // [email protected]
      int v15; // [email protected]
      int v16; // [email protected]
      int v17; // [email protected]
      int v18; // [email protected]
      int v19; // [email protected]
      int v20; // [email protected]
      char v21; // [email protected]
      int v22; // [email protected]
      char v23; // [email protected]
      int v24; // [email protected]
      int v26; // [sp-34h] [bp-148h]@15
      int v27; // [sp-30h] [bp-144h]@15
      int v28; // [sp-2Ch] [bp-140h]@15
      int v29; // [sp-28h] [bp-13Ch]@15
      int v30; // [sp-24h] [bp-138h]@15
      char v31; // [sp-20h] [bp-134h]@12
      int v32; // [sp-1Ch] [bp-130h]@12
      int v33; // [sp-18h] [bp-12Ch]@12
      int v34; // [sp-14h] [bp-128h]@12
      int v35; // [sp-10h] [bp-124h]@5
      int v36; // [sp-Ch] [bp-120h]@12
      LPCSTR v37; // [sp-8h] [bp-11Ch]@2
      char *v38; // [sp-4h] [bp-118h]@2
      char v39; // [sp+0h] [bp-114h]@13
      char v40; // [sp+Ch] [bp-108h]@15
      char v41; // [sp+20h] [bp-F4h]@12
      char v42; // [sp+24h] [bp-F0h]@15
      char v43; // [sp+3Ch] [bp-D8h]@15
      char v44; // [sp+50h] [bp-C4h]@12
      int v45; // [sp+68h] [bp-ACh]@12
      char v46; // [sp+74h] [bp-A0h]@15
      int *v47; // [sp+90h] [bp-84h]@15
      int v48; // [sp+94h] [bp-80h]@11
      char v49; // [sp+ACh] [bp-68h]@12
      char v50; // [sp+C4h] [bp-50h]@1
      char v51; // [sp+DCh] [bp-38h]@1
      LPCSTR lpFileName; // [sp+F0h] [bp-24h]@1
      LPCVOID lpBaseAddress; // [sp+F4h] [bp-20h]@6
      HANDLE hObject; // [sp+F8h] [bp-1Ch]@1
      HANDLE hFileMappingObject; // [sp+FCh] [bp-18h]@4
      char v56; // [sp+103h] [bp-11h]@1
      int v57; // [sp+104h] [bp-10h]@4
      int v58; // [sp+110h] [bp-4h]@1
    
      v58 = 1;
      stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(
        &v50,
        Default,
        &v56);
      LOBYTE(v58) = 3;
      sub_44B825(&v51);
      LOBYTE(v58) = 4;
      v7 = CreateFileA(lpFileName, 0x80000000, 1u, 0, 3u, 0, 0);
      v8 = v7;
      hObject = v7;
      if ( v7 == (HANDLE)-1 )
      {
        v38 = (char *)GetLastError();
        v37 = lpFileName;
        sub_40FB04(v9);
        sub_4E7D8B(5, 16, "Invalid bus file - filename:(%s), Error:(%d)", (char)v37);
    LABEL_3:
        LOBYTE(v58) = 3;
        stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v51);
        LOBYTE(v58) = 0;
        goto LABEL_21;
      }
      v57 = GetFileSize(v7, 0);
      v10 = GetFileSize(v8, 0);
      hFileMappingObject = CreateFileMappingA(v8, 0, 0x4000002u, 0, v10, 0);
      if ( !hFileMappingObject )
      {
        v38 = (char *)GetLastError();
        sub_40FB04(5);
        sub_4E7D8B(v35, 16, "CreateFileMappingA - Failed (%d)", (char)v38);
        CloseHandle(v8);
        goto LABEL_3;
      }
      v11 = operator new(0x90u);
      lpBaseAddress = v11;
      LOBYTE(v58) = 5;
      if ( v11 )
        v12 = sub_52B811(v11);
      else
        v12 = 0;
      LOBYTE(v58) = 4;
      stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::erase(
        v12 + 20,
        *(_DWORD *)(v12 + 40),
        *(_DWORD *)(v12 + 36));
      sub_40293D(*(_DWORD *)(a1 + 108));
      stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::operator=(v12 + 68, &v51);
      v13 = MapViewOfFile(hFileMappingObject, 4u, 0, 0, 0);
      lpBaseAddress = v13;
      if ( v13 )
      {
        sub_44BA2C(&v48);
        LOBYTE(v58) = 6;
        if ( (unsigned __int8)sub_52B8BA(v12, (void *)v13, v57, a1 + 32, (int)&v48) )
        {
          sub_498F89(&v49);
          LOBYTE(v58) = 7;
          v15 = stlp_std::locale::locale((stlp_std::locale *)&v57);
          LOBYTE(v58) = 8;
          sub_42E050(v15);
          LOBYTE(v58) = 7;
          stlp_std::locale::~locale((stlp_std::locale *)&v57);
          v16 = stlp_std::locale::locale((stlp_std::locale *)&v57);
          LOBYTE(v58) = 9;
          sub_50C2A7(&v49, v16);
          LOBYTE(v58) = 7;
          stlp_std::locale::~locale((stlp_std::locale *)&v57);
          v38 = (char *)v12;
          v57 = (int)&v32;
          stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(
            &v32,
            &v49);
          LOBYTE(v58) = 7;
          v17 = sub_52B518(&v41, v31, v32, v33, v34, v35, v36, v37);
          LOBYTE(v58) = 11;
          stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(
            &v44,
            v17);
          LOBYTE(v58) = 12;
          v45 = *(_DWORD *)(v17 + 24);
          LOBYTE(v58) = 13;
          v56 = *(_BYTE *)(sub_52B4C8(&v44) + 4);
          LOBYTE(v58) = 11;
          stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v44);
          LOBYTE(v58) = 7;
          stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v41);
          if ( v56 )
          {
            sub_498D74(&v46);
            LOBYTE(v58) = 16;
            v19 = stlp_std::locale::locale((stlp_std::locale *)&v57);
            LOBYTE(v58) = 17;
            sub_42E050(v19);
            LOBYTE(v58) = 16;
            stlp_std::locale::~locale((stlp_std::locale *)&v57);
            v20 = stlp_std::locale::locale((stlp_std::locale *)&v57);
            LOBYTE(v58) = 18;
            sub_50C2A7(&v46, v20);
            LOBYTE(v58) = 16;
            stlp_std::locale::~locale((stlp_std::locale *)&v57);
            v57 = (int)&v33;
            stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(
              &v33,
              &v49);
            LOBYTE(v58) = 19;
            v47 = &v26;
            stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(
              &v26,
              &v46);
            LOBYTE(v58) = 16;
            v22 = sub_52B564(&v43, v21, v26, v27, v28, v29, v30, v31);
            LOBYTE(v58) = 21;
            stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(
              &v40,
              v22);
            LOBYTE(v58) = 22;
            stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(
              &v42,
              v22 + 24);
            LOBYTE(v58) = 24;
            v23 = *(_BYTE *)(sub_4E75FD(&v40) + 4);
            LOBYTE(v58) = 21;
            sub_49324B(&v40);
            LOBYTE(v58) = 16;
            sub_52B331(&v43);
            if ( v23 )
            {
              LOBYTE(v58) = 7;
              stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v46);
              LOBYTE(v58) = 6;
              stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v49);
              UnmapViewOfFile(lpBaseAddress);
              CloseHandle(hFileMappingObject);
              CloseHandle(hObject);
              LOBYTE(v58) = 4;
              sub_402821(&v48);
              LOBYTE(v58) = 3;
              stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v51);
              LOBYTE(v58) = 0;
              stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v50);
              v58 = -1;
              sub_402821(&a2);
              return 1;
            }
            v38 = "std::make_pair(strLeaf, str) - Failed";
            v37 = (LPCSTR)16;
            v36 = 5;
            sub_40FB04(v24);
            sub_4E7D8B(v36, (int)v37, v38, v39);
            UnmapViewOfFile(lpBaseAddress);
            CloseHandle(hFileMappingObject);
            CloseHandle(hObject);
            LOBYTE(v58) = 7;
            stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v46);
          }
          else
          {
            v38 = "std::make_pair(str, pPkg) - Failed";
            v37 = (LPCSTR)16;
            v36 = 5;
            sub_40FB04(v18);
            sub_4E7D8B(v36, (int)v37, v38, v39);
            UnmapViewOfFile(lpBaseAddress);
            CloseHandle(hFileMappingObject);
            CloseHandle(hObject);
          }
          LOBYTE(v58) = 6;
          stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v49);
        }
        else
        {
          sub_40FB04(v14);
          sub_4E7D8B(5, 16, "Pkg Load Failed", v39);
          UnmapViewOfFile(v13);
          CloseHandle(hFileMappingObject);
          CloseHandle(hObject);
        }
        LOBYTE(v58) = 4;
        sub_402821(&v48);
      }
      else
      {
        v38 = (char *)GetLastError();
        sub_40FB04(5);
        sub_4E7D8B(v35, 16, "MapViewOfFile - Failed (%d)", (char)v38);
        CloseHandle(hFileMappingObject);
        CloseHandle(hObject);
      }
      LOBYTE(v58) = 3;
      stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v51);
      LOBYTE(v58) = 0;
    LABEL_21:
      stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::~basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(&v50);
      v58 = -1;
      sub_402821(&a2);
      return 0;
    }

看来我们很荣幸!客户端彷佛正在运用CreateFileMappingA和MapViewOffile来映照.bus范例的文件。我们以至能够看到一些毛病音讯字符串。

在我们继承之前,须要先把一行代码弄清晰。这行代码经常出现,而且看起来异常神奇(代码见第56行):

   stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(...)

下面,我们离开加以诠释:

    stlp_std::

游戏客户端并没有直接运用C ++ STL,而是运用了stlport,这就是经常出现stlp_std的缘由,它与std::异常像。

    basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::

若是我们运用Google搜刮关键字Basic_String,能够会发明以下内容:

    template < class charT,
               class traits = char_traits<charT>,    // basic_string::traits_type
               class Alloc = allocator<charT>        // basic_string::allocator_type
               > class basic_string;

如您所见,“traits”和“Alloc”是默许参数,因而我们能够疏忽它们。

在我们的例子中,char范例被用作charT参数,这意味着它会做一样的事变:

   stlp_std::basic_string<char>::

若是我们用谷歌搜刮呢?

请看下面的代码:

   typedef basic_string<char> string;

好了,如今全部函数能够简化为:

详细代码以下所示:

   stlp_std::string::ctor_0(...) //std::string constructor, I added "_0" because std::string has different constructors

在IDA Pro中右键单击它,挑选“Rename global item”,并将其改成“stlp_std::string::ctor_0”。如今,我们将会看到:

实例解说未知游戏文件花样的逆向剖析要领(上)

(注重:我们发起为std::string的每一个组织函数/函数都实行该操纵,这也是为它们编号的缘由。如许的话,便可以过让反编译器的输出代码更清晰一些。)

让我们再次回到这个函数上面来!接下来,我们感兴趣的是对MapViewOfFile的挪用(见第100行)。若是您像相识其详细作用,请接见以下地点:

· https://msdn.microsoft.com/en-us/lib…(v=vs.85).aspx

在这个例子中,v13寄存的是映照视图(被映照到内存中的全部文件)的基址。然后将它作为第二个参数通报给该函数:

    sub_52B8BA(v12, (void *)v13, v57, a1 + 32, (int)&v48);

我们来看看这个函数:

    char __stdcall sub_52B8BA(int a1, void *Src, int a3, int a4, int a5)
    {
      int v5; // [email protected]
      void *v6; // [email protected]
      int v7; // [email protected]
      int v8; // [email protected]
      int v9; // [email protected]
      int v10; // [email protected]
      int v11; // [email protected]
      char *v12; // [email protected]
      int v13; // [email protected]
      int v14; // [email protected]
      int v15; // [email protected]
      int v16; // [email protected]
      char v17; // [email protected]
      int v19; // [email protected]
      int v20; // [email protected]
      int v21; // [email protected]
      int v22; // [email protected]
      int v23; // [email protected]
      int v24; // [email protected]
      char v25; // [email protected]
      rsize_t v26; // [email protected]
      int v27; // [email protected]
      int v28; // [sp-3Ch] [bp-130h]@4
      int v29; // [sp-38h] [bp-12Ch]@4
      int v30; // [sp-34h] [bp-128h]@4
      int v31; // [sp-30h] [bp-124h]@4
      int v32; // [sp-2Ch] [bp-120h]@4
      int v33; // [sp-28h] [bp-11Ch]@4
      char v34; // [sp-24h] [bp-118h]@4
      char v35; // [sp-20h] [bp-114h]@4
      int v36; // [sp-1Ch] [bp-110h]@4
      char v37; // [sp-18h] [bp-10Ch]@4
      char *v38; // [sp-Ch] [bp-100h]@3
      rsize_t v39; // [sp-8h] [bp-FCh]@3
      char *v40; // [sp-4h] [bp-F8h]@2
      char v41; // [sp+10h] [bp-E4h]@4
      char v42; // [sp+50h] [bp-A4h]@4
      char *v43; // [sp+9Ch] [bp-58h]@12
      char v44; // [sp+A0h] [bp-54h]@3
      char v45; // [sp+B8h] [bp-3Ch]@4
      char v46; // [sp+D0h] [bp-24h]@12
      char v47; // [sp+D4h] [bp-20h]@12
      int v48; // [sp+D8h] [bp-1Ch]@2
      char *v49; // [sp+DCh] [bp-18h]@3
      int *v50; // [sp+E0h] [bp-14h]@8
      int v51; // [sp+E4h] [bp-10h]@3
      int v52; // [sp+F0h] [bp-4h]@3
    
      v5 = a1;
      v6 = Src;
      if ( Src )
      {
        v48 = 0;
        memcpy((void *)(a1 + 108), Src, 0x21u);
        v40 = *(char **)(v5 + 104);
        v8 = sub_40CF95(v7);
        sub_50B9A2(v8, (char *)v6 + 33, 0x110u, v40);
        v9 = *(_DWORD *)(v5 + 104);
        if ( v9 )
        {
          v10 = *(_DWORD *)(v9 + 264);
          v40 = *(char **)(v5 + 104);
          v39 = v5 + 20;
          v38 = &v44;
          *(_DWORD *)v5 = v10;
          v11 = sub_50C22C(v38, v39, v40);
          v52 = 0;
          stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::operator=(a5, v11);
          v52 = -1;
          sub_402821(&v44);
          sub_4DC6D9();
          v12 = *(char **)(*(_DWORD *)(v5 + 104) + 268);
          v13 = 276 * *(_DWORD *)(*(_DWORD *)(v5 + 104) + 268) + 305;
          v49 = v12;
          v51 = v13;
          if ( !v12 )
          {
            sub_498D74(&v45);
            v52 = 1;
            v14 = stlp_std::locale::locale((stlp_std::locale *)&Src);
            LOBYTE(v52) = 2;
            sub_42E050(v14);
            LOBYTE(v52) = 1;
            stlp_std::locale::~locale((stlp_std::locale *)&Src);
            v15 = stlp_std::locale::locale((stlp_std::locale *)&Src);
            LOBYTE(v52) = 3;
            sub_50C2A7(&v45, v15);
            LOBYTE(v52) = 1;
            stlp_std::locale::~locale((stlp_std::locale *)&Src);
            a3 = 0;
            v51 = 0;
            v49 = &v34;
            BYTE3(Src) = 0;
            BYTE3(a1) = 1;
            sub_52C06B((char *)&a1 + 3, (char *)&Src + 3, &a3, v5 + 68);
            v29 = v16;
            v28 = v16;
            LOBYTE(v52) = 4;
            Src = &v28;
            stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(
              &v28,
              &v45);
            LOBYTE(v52) = 1;
            sub_52BFEC(&v41, v17, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37);
            LOBYTE(v52) = 6;
            sub_52C09F(&v42);
            LOBYTE(v52) = 7;
            sub_52BCA1(&v42);
            LOBYTE(v52) = 6;
            sub_50CA47(&v42);
            LOBYTE(v52) = 1;
            sub_50CA47(&v41);
            sub_52BCF1(a5);
            v52 = -1;
            stlp_std::string::dtor(&v45);
            return 1;
          }
          a1 = 0;
          if ( !v12 )
            return 1;
          a5 = 276;
          while ( 1 )
          {
            v50 = (int *)operator new(0x114u);
            v52 = 8;
            if ( v50 )
            {
              v19 = sub_52B7F1();
              v13 = v51;
              v20 = v19;
            }
            else
            {
              v20 = 0;
            }
            v52 = -1;
            v40 = (char *)v20;
            v39 = 276;
            v38 = (char *)Src + v48 + 305;
            v21 = sub_40CF95(Src);
            sub_50B9A2(v21, v38, v39, v40);
            if ( v20 )
            {
              v48 = a5;
              sub_49C45F(&v44, v20);
              v52 = 9;
              sub_498D74(&v45);
              LOBYTE(v52) = 10;
              v22 = stlp_std::locale::locale((stlp_std::locale *)&v47);
              LOBYTE(v52) = 11;
              sub_42E050(v22);
              LOBYTE(v52) = 10;
              stlp_std::locale::~locale((stlp_std::locale *)&v47);
              v23 = stlp_std::locale::locale((stlp_std::locale *)&v46);
              LOBYTE(v52) = 12;
              sub_50C2A7(&v45, v23);
              LOBYTE(v52) = 10;
              stlp_std::locale::~locale((stlp_std::locale *)&v46);
              v50 = (int *)(v13 + *(_DWORD *)(v20 + 264));
              v43 = &v34;
              sub_52C06B(v20 + 273, v20 + 272, &v50, v5 + 68);
              v29 = v24;
              v28 = v24;
              LOBYTE(v52) = 13;
              v50 = &v28;
              stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(
                &v28,
                &v45);
              LOBYTE(v52) = 10;
              sub_52BFEC(&v41, v25, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37);
              LOBYTE(v52) = 15;
              sub_52C09F(&v42);
              LOBYTE(v52) = 16;
              sub_52BCA1(&v42);
              LOBYTE(v52) = 15;
              sub_50CA47(&v42);
              LOBYTE(v52) = 10;
              sub_50CA47(&v41);
              v26 = *(_DWORD *)(v5 + 96);
              v40 = &v44;
              v39 = v26;
              if ( v26 == *(_DWORD *)(v5 + 100) )
              {
                sub_52BDBB(v39, v40);
              }
              else
              {
                sub_52C0F4(v39, v40);
                *(_DWORD *)(v5 + 96) += 24;
              }
              LOBYTE(v52) = 9;
              stlp_std::string::dtor(&v45);
              v52 = -1;
              sub_402821(&v44);
              v13 = v51;
            }
            v27 = *(_DWORD *)(v20 + 264) + *(_DWORD *)(v20 + 268);
            v40 = (char *)v20;
            if ( v13 + v27 > (unsigned int)a3 )
              break;
            operator delete(v40);
            ++a1;
            a5 += 276;
            if ( a1 >= (unsigned int)v49 )
              return 1;
          }
          operator delete(v40);
        }
      }
      return 0;
    }

您能够已发明了,这里疏忽了很多的其他参数(和很多其他函数)——因为我们只议论密切相关的参数和函数。

我们已晓得,“Src”是我们的映照视图的地点。

    memcpy((void *)(a1 + 108), Src, 0x21u); //Src: address of mapped file view

0x21h的十进制值为33。等等,33……,看到这个值岂非我们没有想起甚么吗?没错,每一个.bus文件的前33个字节都是用0添补的。这将从地点a1+0x108处复制33个字节。

下面这个函数只要三个参数:

    sub_50B9A2(v8, (char *)v6 + 33, 0x114u, v40); //v6 = Src

0x114h是十进制的272,而且它通报的地点即是源缓冲区的地点+33(跳过一切0值)。下面,让我们来看看它的作用:

    int __stdcall sub_50B9A2(int a1, void *Src, rsize_t DstSize, void *Dst)
    {
      memcpy_s(Dst, DstSize, Src, DstSize);
      return sub_50B91E(a1, Dst, DstSize);
    }

如今其功用已很清晰了,不是吗?我们如今晓得,这里将处置惩罚272个字节。若是我们回到上一个函数,便可以够对一些变量从新加以定名了:

实例解说未知游戏文件花样的逆向剖析要领(上)

我们依然不晓得v8是甚么东东,不外,我们已晓得它是被下面的函数设置的:

    int __thiscall sub_40CF95(void *this)
    {
      if ( !dword_F57C24 )
        sub_40D5EF();
      return dword_F57C24;
    }

这里看起来异常像单例设想形式。若是你不熟悉该形式的话,发起人人谷歌一下,另外,这里只做简朴诠释:

dword_XXXX是全局变量。起首,它搜检dword_F57C24是不是为空。若是为空的话,就会挪用一个函数(类的组织函数)来举行初始化。当全部顺序中只须要该类的一个实例时,这类设想形式会异常有效。

若是您考核了响应的虚函数表并搜检了组织函数代码,就会注重到该类现实上就相符上面的设想形式。若是我们能从中取得RTTI信息(若是启用了RTTI的话),那就太好了。这个将在背面引见。

因为篇幅太长,本日我们就引见到这里。后续内容请随时存眷我们。


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明实例解说未知游戏文件花样的逆向剖析要领(上)
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址