int __fastcall h_net_recv(int fd, unsigned __int8 *buf, int len, unsigned __int8 *base_buf, unsigned int base_len) { int fd_moved; // esi@1 harmony_session_data **harmsess_ptr; // edi@1 void *v7; // eax@2 harmony_session_data *v8; // esi@2 harmony_session_data *harmsess; // ebx@6 int crypt_flags; // eax@6 unsigned __int8 v11; // dl@8 int v12; // eax@8 int v13; // esi@9 unsigned int v14; // edi@9 unsigned int v15; // edx@10 unsigned int v16; // esi@12 unsigned int v17; // eax@13 unsigned int v18; // eax@16 int result; // eax@19 int v20; // ecx@21 unsigned int v21; // esi@25 int v22; // eax@29 int v23; // edx@29 int v24; // esi@29 unsigned int v25; // ecx@29 unsigned int v26; // eax@30 int v27; // eax@33 int v28; // eax@36 int v29; // eax@39 int v30; // eax@42 int v31; // eax@45 int v32; // eax@48 int v33; // eax@51 unsigned int v34; // eax@54 int v35; // esi@55 char v36; // dl@55 int v37; // esi@58 char v38; // dl@58 char v39; // dl@61 int v40; // esi@61 char v41; // dl@64 int v42; // esi@64 unsigned __int8 v43; // dl@70 int v44; // eax@70 int v45; // esi@71 int v46; // ecx@71 unsigned int v47; // edi@71 unsigned int v48; // edx@72 unsigned int v49; // esi@74 unsigned int v50; // eax@75 unsigned int v51; // eax@78 int buf_moved; // [sp+Ch] [bp-4h]@1 unsigned int lena; // [sp+18h] [bp+8h]@69 int srca; // [sp+1Ch] [bp+Ch]@9 signed int srcb; // [sp+1Ch] [bp+Ch]@54 int srcc; // [sp+1Ch] [bp+Ch]@71 unsigned int base_lena; // [sp+20h] [bp+10h]@7 int base_lenb; // [sp+20h] [bp+10h]@27 buf_moved = (int)buf; fd_moved = fd; harmsess_ptr = (harmony_session_data **)ea_funcs.ea_fd2harmsession(fd); if ( !*harmsess_ptr ) { harm_message( "\n** Missing Harmony session information @ fd #%d. **\nServer might run unstable now. Please report this immediately!\n\n", fd_moved); v7 = (void *)ea_funcs.alloc(0xB4u); v8 = (harmony_session_data *)v7; if ( v7 ) ZeroMemory(v7, 0xB4u); else v8 = 0; *harmsess_ptr = v8; } harmsess = *harmsess_ptr; crypt_flags = (*harmsess_ptr)->crypt_flags; if ( crypt_flags == 1 ) { base_lena = 0; if ( len ) { do { *(_BYTE *)(base_lena + buf_moved) ^= *(_BYTE *)(*(_DWORD *)&harmsess->gap_11[47] + *(_DWORD *)&harmsess->gap_11[43]); v11 = *(_BYTE *)(base_lena + buf_moved); v12 = ((unsigned __int16)*(_DWORD *)&harmsess->gap_11[47] + 1) & 0x3FF; *(_DWORD *)&harmsess->gap_11[47] = v12; if ( (_BYTE)v12 == 5 ) { g_global_aes->key_count = 8; g_global_aes->key_size = 4; g_global_aes->round_count = 14; v13 = *(_DWORD *)&harmsess->gap_11[47]; srca = v11; v14 = v13 + 13 * *(_BYTE *)(*(_DWORD *)&harmsess->gap_11[43] + v13) + (v11 << 7); if ( v14 >= 0x3A0 ) { v15 = v14 / 0x3A0; do { v14 -= 928; --v15; } while ( v15 ); } v16 = srca * *(_BYTE *)(*(_DWORD *)&harmsess->gap_11[43] + v13) + v13 + 4; if ( v16 >= 0x3F0 ) { v17 = v16 / 0x3F0; do { v16 -= 0x3F0u; --v17; } while ( v17 ); } if ( abs(v14 - v16) >= 32 ) { aes_setupkey_enc(g_global_aes, (unsigned int *)(v14 + *(_DWORD *)&harmsess->gap_11[43])); aes_encrypt( g_global_aes, (unsigned __int8 *)(v16 + *(_DWORD *)&harmsess->gap_11[43]), (unsigned __int8 *)(v16 + *(_DWORD *)&harmsess->gap_11[43])); v18 = 0; do { *(_BYTE *)(v18 + *(_DWORD *)&harmsess->gap_11[43] + v16) ^= *(_BYTE *)(v18 + *(_DWORD *)&harmsess->gap_11[43] + v14) + 3; *(_BYTE *)(v18 + *(_DWORD *)&harmsess->gap_11[43] + v16 + 1) ^= *(_BYTE *)(v18 + *(_DWORD *)&harmsess->gap_11[43] + v14 + 1) + 3; *(_BYTE *)(v18 + *(_DWORD *)&harmsess->gap_11[43] + v16 + 2) ^= *(_BYTE *)(v18 + *(_DWORD *)&harmsess->gap_11[43] + v14 + 2) + 3; *(_BYTE *)(v18 + *(_DWORD *)&harmsess->gap_11[43] + v16 + 3) ^= *(_BYTE *)(v18 + *(_DWORD *)&harmsess->gap_11[43] + v14 + 3) + 3; v18 += 4; } while ( v18 < 0x10 ); } } ++base_lena; } while ( base_lena < len ); } return len; } if ( crypt_flags == 2 ) return len; v20 = *(_DWORD *)&harmsess->gap_11[39]; if ( v20 ) goto LABEL_25; if ( base_len < 2 ) return len; if ( *(_WORD *)base_buf != 114 ) { result = len; harmsess->crypt_flags = 2; return result; } LABEL_25: v21 = 39 - v20; if ( base_len < 39 - v20 ) v21 = base_len; base_lenb = base_len - v20 - 39; memcpy(&harmsess->field_10 + v20, base_buf, v21); *(_DWORD *)&harmsess->gap_11[39] += v21; if ( *(_DWORD *)&harmsess->gap_11[39] >= 0x27u ) { *(_DWORD *)&harmsess->gap_11[43] = ea_funcs.alloc(0x400u); v22 = ea_funcs.alloc(0x400u); v23 = *(_DWORD *)&harmsess->gap_11[43]; v24 = *(_DWORD *)&harmsess->gap_11[2] ^ *(_DWORD *)&harmsess->gap_11[7] ^ 0xA9384445; *(_DWORD *)&harmsess->gap_11[51] = v22; v25 = 0; do { v26 = v25 >> 1; if ( v25 & 1 ) v26 ^= v24; if ( v26 & 1 ) v27 = v24 ^ (v26 >> 1); else v27 = v26 >> 1; if ( v27 & 1 ) v28 = v24 ^ ((unsigned int)v27 >> 1); else v28 = (unsigned int)v27 >> 1; if ( v28 & 1 ) v29 = v24 ^ ((unsigned int)v28 >> 1); else v29 = (unsigned int)v28 >> 1; if ( v29 & 1 ) v30 = v24 ^ ((unsigned int)v29 >> 1); else v30 = (unsigned int)v29 >> 1; if ( v30 & 1 ) v31 = v24 ^ ((unsigned int)v30 >> 1); else v31 = (unsigned int)v30 >> 1; if ( v31 & 1 ) v32 = v24 ^ ((unsigned int)v31 >> 1); else v32 = (unsigned int)v31 >> 1; if ( v32 & 1 ) v33 = v24 ^ ((unsigned int)v32 >> 1); else v33 = (unsigned int)v32 >> 1; *(_DWORD *)(v23 + 4 * v25++) = v33 ^ 0xD71A89B0; } while ( v25 < 0x100 ); v34 = 0; srcb = -1; do { v35 = *(_DWORD *)&harmsess->gap_11[43]; v36 = byte_10007898[v34]; if ( v34 & 1 ) *(_BYTE *)(v35 + v34) ^= v36; else *(_BYTE *)(v35 + v34) += v36; v37 = *(_DWORD *)&harmsess->gap_11[43] + v34 + 1; v38 = byte_10007899[v34]; if ( srcb & 1 ) *(_BYTE *)v37 ^= v38; else *(_BYTE *)v37 += v38; v39 = byte_1000789A[v34]; v40 = *(_DWORD *)&harmsess->gap_11[43] + v34 + 2; if ( (v34 & 1) == 1 ) *(_BYTE *)v40 ^= v39; else *(_BYTE *)v40 += v39; v41 = byte_1000789B[v34]; v42 = *(_DWORD *)&harmsess->gap_11[43] + v34 + 3; if ( (srcb & 1) == 1 ) *(_BYTE *)v42 ^= v41; else *(_BYTE *)v42 += v41; srcb += 4; v34 += 4; } while ( v34 < 0x400 ); memcpy(*(void **)&harmsess->gap_11[51], *(const void **)&harmsess->gap_11[43], 0x400u); harmsess->crypt_flags = 1; if ( base_lenb <= 0 ) return len; sub_10017AA0(buf_moved, base_lenb, len + buf_moved - base_lenb); lena = 0; if ( base_lenb ) { do { *(_BYTE *)(lena + buf_moved) ^= *(_BYTE *)(*(_DWORD *)&harmsess->gap_11[47] + *(_DWORD *)&harmsess->gap_11[43]); v43 = *(_BYTE *)(lena + buf_moved); v44 = ((unsigned __int16)*(_DWORD *)&harmsess->gap_11[47] + 1) & 0x3FF; *(_DWORD *)&harmsess->gap_11[47] = v44; if ( (_BYTE)v44 == 5 ) { g_global_aes->key_count = 8; g_global_aes->key_size = 4; g_global_aes->round_count = 14; v45 = *(_DWORD *)&harmsess->gap_11[47]; v46 = *(_BYTE *)(*(_DWORD *)&harmsess->gap_11[43] + v45); srcc = v43; v47 = v45 + 13 * v46 + (v43 << 7); if ( v47 >= 0x3A0 ) { v48 = v47 / 0x3A0; do { v47 -= 928; --v48; } while ( v48 ); } v49 = srcc * v46 + v45 + 4; if ( v49 >= 0x3F0 ) { v50 = v49 / 0x3F0; do { v49 -= 1008; --v50; } while ( v50 ); } if ( abs(v47 - v49) >= 32 ) { aes_setupkey_enc(g_global_aes, (unsigned int *)(v47 + *(_DWORD *)&harmsess->gap_11[43])); aes_encrypt( g_global_aes, (unsigned __int8 *)(v49 + *(_DWORD *)&harmsess->gap_11[43]), (unsigned __int8 *)(v49 + *(_DWORD *)&harmsess->gap_11[43])); v51 = 0; do { *(_BYTE *)(v51 + *(_DWORD *)&harmsess->gap_11[43] + v49) ^= *(_BYTE *)(v51 + *(_DWORD *)&harmsess->gap_11[43] + v47) + 3; *(_BYTE *)(v51 + *(_DWORD *)&harmsess->gap_11[43] + v49 + 1) ^= *(_BYTE *)(v51 + *(_DWORD *)&harmsess->gap_11[43] + v47 + 1) + 3; *(_BYTE *)(v51 + *(_DWORD *)&harmsess->gap_11[43] + v49 + 2) ^= *(_BYTE *)(v51 + *(_DWORD *)&harmsess->gap_11[43] + v47 + 2) + 3; *(_BYTE *)(v51 + *(_DWORD *)&harmsess->gap_11[43] + v49 + 3) ^= *(_BYTE *)(v51 + *(_DWORD *)&harmsess->gap_11[43] + v47 + 3) + 3; v51 += 4; } while ( v51 < 0x10 ); } } ++lena; } while ( lena < base_lenb ); } result = base_lenb; } else { result = 0; } return result; }