Trying to understand a function thats responsible for sending out a packet.I don't understand could it be a integer array or something? or some inline function that's not properly getting rendered in Hex-RaysI understand the else statement sends a 4 byte packet which contains a timestamp of the GetTickCount API.The if statement should send the packet that comes in the a2 is the pointer to characters with a3 being the size for all the characters.Usage is similar to thischar buffer[448];memset(buffer, 0, sizeof(buffer));//blah blah packet stuff herestrncpy(&buffer[90], blah blah blah, 250u);buffer[339] = 0;//then the call below.// 91+250+91 = 432, yet memset is 448, 16 extra probably stack padding.test(*v28, buffer, strlen(&buffer[90]) + 91);Here is the original code decompiled from Hex-Rays.void __thiscall test(void *this, const void *a2, unsigned int a3){  void *v3; // ebx@1  char *v4; // eax@3  int v5; // [sp-8h] [bp-418h]@3  int v6; // [sp-4h] [bp-414h]@3  char v7[4]; // [sp+Ch] [bp-404h]@4  char buf[1024]; // [sp+10h] [bp-400h]@3  v3 = this;  if ( a2 && (signed int)a3 > 0 )  {    *(_DWORD *)buf = 0;    memcpy(&buf[4], a2, 4 * (a3 >> 2));    v6 = 0;    v5 = a3 + 4;    v4 = buf;    memcpy(&buf[4 * (a3 >> 2) + 4], (char *)a2 + 4 * (a3 >> 2), a3 & 3);// Looks like Copy by DWORDs, not by Bytes.  }  else  {    v6 = 0;    *(_DWORD *)v7 = GetTickCount() / 0xA;    v5 = 4;    v4 = v7;  }  send(*(_DWORD *)v3, v4, v5, v6);}Here I fixed it up a little by hand, still don't understand it.void __thiscall test(void *this, const void *a2, unsigned int a3){  void *v3; // ebx@1  char *v4; // eax@3  int v5; // [sp-8h] [bp-418h]@3  int v6; // [sp-4h] [bp-414h]@3  char v7[4]; // [sp+Ch] [bp-404h]@4  char buf[1024]; // [sp+10h] [bp-400h]@3  v3 = this;  if ( a2 && (signed int)a3 > 0 )  {    *(_DWORD *)buf = 0;    //Might be a swap of the 5th offset DWORD to end of the packet?    //Or maybe it fills in the packet offsetted by the first 4 bytes?    memcpy(&buf[4], a2, 4 * (a3 / 4)); // Looks like Copy by DWORDs, not by Bytes.    v6 = 0;    v5 = a3 + 4;    v4 = buf;    //Might be a swap of the end of the packet to the 5th offset DWORD?    //Looks like some kind of footer to above memcpy function like to finish what the first function couldn't do?    memcpy(&buf[4 * (a3 / 4) + 4], (char *)a2 + 4 * (a3 / 4), a3 & 3);// Looks like Copy by DWORDs, not by Bytes.  }  else  {    v6 = 0;    *(_DWORD *)v7 = GetTickCount() / 0xA;    v5 = 4;    v4 = v7;  }  send(*(_DWORD *)v3, v4, v5, v6);}Okay I gave it some more time could this be the correct?void __thiscall test(void *this, const void *a2, unsigned int a3){  void *v3; // ebx@1  char *v4; // eax@3  int v5; // [sp-8h] [bp-418h]@3  int v6; // [sp-4h] [bp-414h]@3  char v7[4]; // [sp+Ch] [bp-404h]@4  char buf[1024]; // [sp+10h] [bp-400h]@3  v3 = this;  if ( a2 && (signed int)a3 > 0 )  {    *(_DWORD *)buf = 0;    memmove(&buf[4],a2,a3 - 4);     v6 = 0;    v5 = a3 + 4;    v4 = buf;  }  else  {    v6 = 0;    *(_DWORD *)v7 = GetTickCount() / 0xA;    v5 = 4;    v4 = v7;  }  send(*(_DWORD *)v3, v4, v5, v6);}Assembly below.text:00408750 ; =============== S U B R O U T I N E =======================================.text:00408750.text:00408750.text:00408750 ; void __thiscall test(void *this, const void *a2, unsigned int a3).text:00408750 test proc near.text:00408750                                         ; CODE XREF: ServerMainLoop+5DDp.text:00408750                                         ; ServerMainLoop+64Dp.text:00408750.text:00408750 var_404         = byte ptr -404h.text:00408750 buf             = byte ptr -400h.text:00408750 a2              = dword ptr  4.text:00408750 a3              = dword ptr  8.text:00408750.text:00408750                 sub     esp, 404h.text:00408756                 push    ebx.text:00408757                 push    esi.text:00408758                 mov     esi, [esp+40Ch+a2].text:0040875F                 push    edi.text:00408760                 test    esi, esi.text:00408762                 mov     ebx, ecx.text:00408764                 jz      short loc_408799.text:00408766                 mov     eax, [esp+410h+a3].text:0040876D                 test    eax, eax.text:0040876F                 jle     short loc_408799.text:00408771                 mov     ecx, eax.text:00408773                 lea     edi, [esp+410h+buf+4].text:00408777                 mov     edx, ecx.text:00408779                 mov     dword ptr [esp+410h+buf], 0.text:00408781                 shr     ecx, 2.text:00408784                 rep movsd.text:00408786                 mov     ecx, edx.text:00408788                 push    0.text:0040878A                 and     ecx, 3.text:0040878D                 add     eax, 4.text:00408790                 push    eax.text:00408791                 lea     eax, [esp+418h+buf].text:00408795                 rep movsb.text:00408797                 jmp     short loc_4087B7.text:00408799 ; ---------------------------------------------------------------------------.text:00408799.text:00408799 loc_408799:                             ; CODE XREF: test+14j.text:00408799                                         ; test+1Fj.text:00408799                 call    ds:GetTickCount.text:0040879F                 mov     edx, eax.text:004087A1                 mov     eax, 0CCCCCCCDh.text:004087A6                 mul     edx.text:004087A8                 shr     edx, 3.text:004087AB                 push    0               ; flags.text:004087AD                 mov     dword ptr [esp+414h+var_404], edx.text:004087B1                 push    4               ; len.text:004087B3                 lea     eax, [esp+418h+var_404].text:004087B7.text:004087B7 loc_4087B7:                             ; CODE XREF: test+47j.text:004087B7                 mov     ecx, [ebx].text:004087B9                 push    eax             ; buf.text:004087BA                 push    ecx             ; s.text:004087BB                 call    send.text:004087C0                 pop     edi.text:004087C1                 pop     esi.text:004087C2                 pop     ebx.text:004087C3                 add     esp, 404h.text:004087C9                 retn    8.text:004087C9 test endp.text:004087C9.text:004087C9 ; ---------------------------------------------------------------------------
Can someone tell me what this memcpy or maybe it's a memset? looks like a memset, rep movsd and rep movsb This is a packet sending function
ida;decompilation
This code is easy, it's just a bit messy 'cause it was generated by a decompiler. Here's a much simpler commented version :void __thiscall test(void *this, const void *a2, unsigned int a3) {    char v7[4];     int  v5 = 4;    void *v3 = this;    char buf[1024], *v4;    if (a2 != NULL && (signed int)a3 > 0)    {      //Setting the 4 first bytes to 0. Certainly the message header !      *(_DWORD *)buf = 0;      /*         Same as :         memset(buff, 0, 4);         buf[0] = buf[1] = buf[2] = buf[3] = 0;        */      /*         Copying the first a3 bytes of a2 into buff + 4.          The + 4 is to jump the 4 bytes header set to 0 previously.        */       memcpy(buf + 4, a2, a3); //There's no point in 4 * a3 / 4;      //Size has changed to a3 + 4 (4 bytes for the header)      v5 += a3;      //      v4 = buf;    }    else    {       /* _DWORD is 4 bytes. This line converts v7 into an integer to           copy the value of GetTickCount() / 10 byte by byte into it.          */      *(_DWORD *)v7 = GetTickCount() / 10;      //      v4 = v7;    }    send(*(_DWORD *)v3, v4, v5, 0); }From this I would say that this routine sends a packet with the header set to GetTickCount() / 10 if there's no message (a2 == NULL or a3 <= 0), otherwise it sets the message header to 0, the message itself to a2 and sends the packet.The thing about the original version you provided is that it was performing a copy 4 elements by 4 ... That's why the memcpy was split in two. The first one copying the elements 4 * (a3 / 4) (if a3 = 19 then it would've copied 16 elements), the second one copying the remaining a3 % 4 (a3 % 4 <==> a3 & (4 - 1) <==> a3 & 3) elements (if a3 = 19 then it would've copied 3). 