5

I'm trying to clean up the pseudo code to make it compile and function similar if not exactly the same as the original code.

This bit which looks like this appears in various places I'm trying to figure out what it exactly means.

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

Other places like this..

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

Assembly for the first piece of pseudo code I provide here.

.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

As far as I understand it is that the 0x3FFFFFFF has something to do with the bounds of the array?

I think after the DisconnectUser and free of memory all the playerPointer pointers get shifted to the left is that correct? or it just changes the counter in different paths.

I think the counter is either v3 can keep increasing while the loop is going but when a player gets removed it starts checking from the end of the list or something?

1 Answer 1

4

I think it should look like this I am 99.9% feel it's a element shifter something tells me that 0x3FFFFFFF is max bounds of a array so it's some compiler thing that it appends to make sure it gets the end of the array.

I was wrong 0x3FFFFFFF is used to create signed numbers to emulate subtracting by adding. See comment by 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 );
  }

Let me know if this is wrong, I'll remove the answer. (don't have original source code to compare against).

Thought I shouldn't be using memcpy because it may leave junk in memory at the very end but i think that junk does no harm and eventually will be replaced with something useful when the time comes.

Although it does seem memmove() is better suited here.

2
  • 1
    That looks quite right. One thing to notice is that 0x3FFFFFFF * 4 = 0xFFFFFFFC, or -4. It's not a literal array bound, it's just a neat way of subtracting 4 * counter from a number.
    – DCoder
    Sep 21, 2014 at 5:18
  • ahh thanks so it tries to subtract by doing multiplication lol so weird, this is full of surprises it also does right shifts for dividing power of numbers (in other parts). One day these decompilers will have patterns that can recognize everything and simplify it for you!. If IDA's Hex-Ray was open source where people would fill in patterns for everything then project would of been long ago completed atleast better, then again look at everything other then Hex-Rays complete garbage.
    – SSpoke
    Sep 22, 2014 at 2:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.