IDA PRO Hex-Rays 1.5 伪代码理解-=0x3FFFFFFFu;+= 0x3FFFFFFFu;

逆向工程 艾达 反编译 去混淆 六线谱
2021-06-25 23:05:49

我正在尝试清理伪代码,使其编译和功能相似,如果与原始代码不完全相同。

这个看起来像这样的位出现在不同的地方,我试图弄清楚它到底意味着什么。

  if ( ZonePlayerCount > 0 )
  {
    v3 = 0;
    v4 = 0;
    v5 = playerPointerList;
    v6 = &playerPointerList[1];
    do
    {
      if ( *(unsigned int *)&(*v5)->IPAddressDWORD.S_un.S_un_b.s_b1 == IPAddress && (*v5)->Port == Port )
      {
        printf("Connection is broken because same ip/port requested another connection\n");
        sub_41CBD0((int)&(*v5)->encryptionPointer->ConnectionStatus);
        Memory = *v5;
        if ( *v5 )
        {
          DisconnectUser(*v5);
          free(Memory);
        }
        --ZonePlayerCount;
        memcpy(v5, v6, 4 * (v4 + ZonePlayerCount));
        --v3;
        v4 -= 0x3FFFFFFFu;
        v6 = (char *)v6 - 4;
        --v5;
      }
      ++v3;
      v4 += 0x3FFFFFFFu;
      v6 = (char *)v6 + 4;
      ++v5;
    }
    while ( v3 < ZonePlayerCount );
  }

其他地方这样..

    v1 = 0;
    if ( ArenaArrayLength > v1 )
    {
      v18 = 0;
      v19 = Arenas;
      v20 = &Arenas[1];
      do
      {
        if ( ProcessArena(*v19) )
        {
          if ( (*v19)->ArenaName[0] )
            WriteSubGameLog("Private arena dropped: %s\n", (*v19)->ArenaName);
          else
            WriteSubGameLog("Arena dropped\n");
          bufa = *v19;
          if ( *v19 )
          {
            ShutdownArena(*v19);
            free(bufa);
          }
          --ArenaArrayLength;
          memcpy(v19, v20, 4 * (v18 + ArenaArrayLength));
          --v1;
          v18 -= 0x3FFFFFFFu;
          v20 = (char *)v20 - 4;
          --v19;
        }
        ++v1;
        v18 += 0x3FFFFFFFu;
        v20 = (char *)v20 + 4;
        ++v19;
      }
      while ( v1 < ArenaArrayLength );
    }

我在这里提供的第一段伪代码的汇编。

.text:00412D7B                 mov     esi, offset playerPointerList
.text:00412D80                 mov     ebx, (offset playerPointerList+4)
.text:00412D85
.text:00412D85 loc_412D85:                             ; CODE XREF: NewConnectionRequest+C0j
.text:00412D85                 mov     eax, [esi]
.text:00412D87                 mov     ecx, [esp+20h+IPAddress]
.text:00412D8B                 cmp     [eax+2F3h], ecx
.text:00412D91                 jnz     short loc_412DFC
.text:00412D93                 mov     dx, [esp+20h+Port]
.text:00412D98                 cmp     [eax+2F7h], dx
.text:00412D9F                 jnz     short loc_412DFC
.text:00412DA1                 push    offset aConnectionIsBrok ; "Connection is broken because same ip/port "...
.text:00412DA6                 call    _printf
.text:00412DAB                 mov     eax, [esi]
.text:00412DAD                 add     esp, 4
.text:00412DB0                 mov     ecx, [eax+28h]
.text:00412DB3                 call    sub_41CBD0
.text:00412DB8                 mov     ecx, [esi]      ; player
.text:00412DBA                 test    ecx, ecx
.text:00412DBC                 mov     [esp+20h+Memory], ecx
.text:00412DC0                 jz      short loc_412DD4
.text:00412DC2                 call    DisconnectUser
.text:00412DC7                 mov     ecx, [esp+20h+Memory]
.text:00412DCB                 push    ecx             ; Memory
.text:00412DCC                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00412DD1                 add     esp, 4
.text:00412DD4
.text:00412DD4 loc_412DD4:                             ; CODE XREF: NewConnectionRequest+70j
.text:00412DD4                 mov     eax, ZonePlayerCount
.text:00412DD9                 dec     eax
.text:00412DDA                 mov     ZonePlayerCount, eax
.text:00412DDF                 add     eax, edi
.text:00412DE1                 shl     eax, 2
.text:00412DE4                 push    eax             ; Size
.text:00412DE5                 push    ebx             ; Src
.text:00412DE6                 push    esi             ; Dst
.text:00412DE7                 call    _memcpy
.text:00412DEC                 add     esp, 0Ch
.text:00412DEF                 dec     ebp
.text:00412DF0                 sub     edi, 3FFFFFFFh
.text:00412DF6                 sub     ebx, 4
.text:00412DF9                 sub     esi, 4
.text:00412DFC
.text:00412DFC loc_412DFC:                             ; CODE XREF: NewConnectionRequest+41j
.text:00412DFC                                         ; NewConnectionRequest+4Fj
.text:00412DFC                 mov     eax, ZonePlayerCount
.text:00412E01                 inc     ebp
.text:00412E02                 add     edi, 3FFFFFFFh
.text:00412E08                 add     ebx, 4
.text:00412E0B                 add     esi, 4
.text:00412E0E                 cmp     ebp, eax
.text:00412E10                 jl      loc_412D85

据我了解它0x3FFFFFFF与数组的边界有关吗?

我认为在 DisconnectUser 和空闲内存之后,所有 playerPointer 指针都向左移动是正确的吗?或者它只是在不同的路径中更改计数器。

我认为计数器v3可以在循环进行时不断增加,但是当玩家被移除时,它会从列表的末尾开始检查还是什么?

1个回答

我认为它应该看起来像这样我 99.9% 觉得它是一个元素移位器,它告诉我这0x3FFFFFFF是数组的最大边界,因此它附加了一些编译器以确保它到达数组的末尾。

我错了0x3FFFFFFF用于创建有符号数以通过加法来模拟减法。查看 DCoder 的评论

  if ( ZonePlayerCount > 0 )
  {
    v3 = 0;

    do
    {
      if ( playerPointerList[v3].IPAddressDWORD.S_un.S_un_b.s_b1 == IPAddress && playerPointerList[v3].Port == Port )
      {
        printf("Connection is broken because same ip/port requested another connection\n");
        sub_41CBD0((int)&playerPointerList[v3].encryptionPointer->ConnectionStatus);
        Memory = *v5;
        if ( *v5 )
        {
          DisconnectUser(*v5);
          free(Memory);
        }

        memcpy(&playerPointerList[v3], &playerPointerList[v3 + 1], 4 * (ZonePlayerCount - v3 - 1));
        //or
        memmove(&playerPointerList[v3], &playerPointerList[v3 + 1], (ZonePlayerCount - v3 - 1) * sizeof(&playerPointerList));
        --ZonePlayerCount;
        --v3;
      }
      ++v3;
    }
    while ( v3 < ZonePlayerCount );
  }

如果这是错误的,请告诉我,我将删除答案。(没有原始源代码可以比较)。

我认为我不应该使用memcpy它,因为它最终可能会在内存中留下垃圾,但我认为垃圾没有害处,最终会在时机成熟时被有用的东西取代。

虽然它似乎memmove()更适合这里。