/* hdcp_subcmd12_rxinfo @ 0x402a88 */ int __fastcall hdcp_subcmd12_rxinfo(struct hdcp_session *sess, unsigned __int8 *msg, unsigned int len, int *out) { int result; // r0 unsigned int v9; // r8 unsigned int v10; // r10 int v11; // r9 __int16 v12; // r6 __int16 v13; // r9 unsigned int v14; // r0 int v15; // r6 bool v16; // zf int v17; // r0 int v18; // r9 unsigned int v19; // r0 unsigned int seq_valid; // r1 int rx_count; // r8 int v22; // r7 __int64 v23; // r2 _BYTE *v24; // r0 unsigned int mode; // r1 unsigned int v26; // r8 unsigned int v27; // r7 int v28; // r0 int v29; // r1 unsigned int f44; // r2 int v31; // r1 _BYTE *v32; // r1 unsigned int v33; // r3 unsigned int v34; // r6 unsigned int v35; // r7 unsigned int i; // r7 unsigned __int8 *v37; // r1 int v38; // r0 int v39; // r6 int v40; // r2 int v41; // r3 int f4c_high; // r1 unsigned int devid; // r0 int v44; // r0 unsigned int v45; // r6 unsigned __int8 v46; // [sp+4h] [bp-210h] int v47; // [sp+8h] [bp-20Ch] int v48; // [sp+Ch] [bp-208h] int v49; // [sp+10h] [bp-204h] int v50; // [sp+14h] [bp-200h] int v51; // [sp+18h] [bp-1FCh] BYREF unsigned __int16 v52; // [sp+1Ch] [bp-1F8h] BYREF int v53; // [sp+20h] [bp-1F4h] BYREF unsigned __int8 f50_high; // [sp+24h] [bp-1F0h] _BYTE v55[3]; // [sp+25h] [bp-1EFh] BYREF _DWORD v56[8]; // [sp+C0h] [bp-154h] BYREF int v57[8]; // [sp+E0h] [bp-134h] BYREF _BYTE v58[200]; // [sp+100h] [bp-114h] BYREF int v59; // [sp+1C8h] [bp-4Ch] BYREF _DWORD v60[11]; // [sp+1E8h] [bp-2Ch] BYREF v60[10] = *off_40394C; v52 = 0; ta_memclr(v58, 0x10Cu); result = 1; if ( sess == nullptr || msg == nullptr || out == nullptr ) return result; *out = 100; if ( sess->flag_24d != 0 ) { if ( asd_rpc_1a2(sess->devid) != 0 ) return 20; sess->flag_24d = 0; } if ( sess->topology_type == 6 ) { if ( sess->mode == 20 ) { if ( len <= 1 ) goto LABEL_27; v9 = msg[1]; sess->f34 = v9; v10 = *msg; sess->f30 = v10; v11 = msg[2]; sess->rx_count = v11; sess->f3c = msg[3]; if ( msg[1] == 0 && *msg == 0 ) { if ( 5 * msg[2] + 36 == len ) { v12 = 0; v47 = 32; sess->seq_valid = 0; ta_memcpy(v57, msg + 4, 0x20u); ta_memcpy(sess->rx_ids, msg + 36, 5 * v11); v46 = 0; v48 = 0; v50 = 0; v49 = 0; goto LABEL_17; } LABEL_27: sess->err_state = 7; v17 = 109; LABEL_31: *out = v17; return 0; } LABEL_30: sess->err_state = 7; v17 = 107; goto LABEL_31; } if ( len <= 1 ) goto LABEL_27; v9 = msg[1]; sess->f34 = v9; v10 = *msg; sess->f30 = v10; v18 = msg[2]; sess->rx_count = v18; sess->f3c = msg[3]; sess->f40 = msg[5]; sess->f44 = msg[4]; if ( msg[1] != 0 || *msg != 0 ) goto LABEL_30; if ( 5 * msg[2] + 25 != len ) goto LABEL_27; v48 = msg[6]; v50 = msg[7]; v49 = msg[8]; v47 = 16; ta_memcpy(v57, msg + 9, 0x10u); ta_memcpy(sess->rx_ids, msg + 25, 5 * v18); v12 = 0; v46 = 0; } else { if ( len != 176 ) goto LABEL_27; v46 = *msg; v13 = msg[1]; ta_bounded_copy(msg, &v52, 2u); v14 = v52; v9 = (v52 & 8) != 0; sess->f34 = v9; sess->f44 = (v14 & 2) != 0; sess->f40 = v14 & 1; sess->f3c = (v14 >> 9) & 7; v15 = (v14 >> 4) & 0x1F; sess->rx_count = v15; v10 = (v14 & 4) != 0; sess->f30 = v10; v48 = msg[2]; v50 = msg[3]; v49 = msg[4]; v47 = 16; ta_memcpy(v57, msg + 5, 0x10u); ta_memcpy(sess->rx_ids, msg + 21, 5 * v15); v12 = v13 << 8; } LABEL_17: v16 = v9 == 0; if ( v9 == 0 ) v16 = v10 == 0; if ( !v16 ) goto LABEL_30; if ( (sess->f40 != 0 || sess->f44 != 0) && sess->f1c - 1 <= 1 ) { sess->f20 = 0; if ( asd_rpc_1a3(sess->devid, 1) != 0 ) return 17; } v19 = v48 | (v50 << 8) | (v49 << 16); seq_valid = sess->seq_valid; if ( v19 != 0 && seq_valid == 0 || seq_valid == 1 && v19 < sess->seq_num ) { sess->err_state = 7; v17 = 108; goto LABEL_31; } rx_count = sess->rx_count; sess->seq_num = v19; sess->seq_valid = 1; v22 = 5 * rx_count; ta_memcpy(v58, sess->rx_ids, 5 * rx_count); if ( sess->topology_type != 6 ) { v26 = v47; v58[v22] = v46 | v12; v58[v22 + 1] = HIBYTE(v12); v28 = 5; v29 = 2; LABEL_46: v31 = v29 + v22; v27 = v22 + v28; v58[v31] = v48; v32 = &v58[v31]; v32[2] = v49; v32[1] = v50; goto LABEL_47; } v23 = *(_QWORD *)&sess->f30; v58[5 * rx_count] = sess->f3c; v24 = &v58[v22]; mode = sess->mode; v24[2] = BYTE4(v23); v24[1] = rx_count; v24[3] = v23; if ( mode != 20 ) { f44 = sess->f44; v24[5] = *(_QWORD *)&sess->f40; v28 = 9; v58[v22 + 4] = f44; v29 = 6; v26 = v47; goto LABEL_46; } v26 = v47; v27 = v22 + 4; LABEL_47: ta_memcpy(&v59, &sess->rx_ids[189], 0x20u); v60[8] = v26; ta_memcpy_aligned(v60, v57, v26); if ( hdcp_verify_mac(v58, v27, v56, &v51, 0x20u) != 0 ) { sess->err_state = 7; *out = 106; ta_memclr(v56, 0x20u); ta_memclr(v58, 0x10Cu); return 0; } if ( v51 == 32 ) { v33 = v56[5]; v34 = v56[6]; v35 = v56[7]; sess->hash[0] = v56[4]; sess->hash[1] = v33; sess->hash[2] = v34; sess->hash[3] = v35; } ta_memclr(v56, 0x20u); ta_memclr(v58, 0x10Cu); for ( i = 0; i < sess->rx_count; ++i ) { v37 = &sess->rx_ids[5 * i]; v38 = *v37; v39 = v37[3]; v40 = v37[1]; v41 = v37[2]; f50_high = v37[4]; v53 = v38 | (v40 << 8) | ((v41 | (v39 << 8)) << 16); if ( asd_rpc_303(&v53) != 0 ) goto LABEL_59; } if ( asd_rpc_1a8(sess->buf268) != 0 ) return 17; ta_memclr_unaligned(v55, 0x9Bu); f4c_high = HIBYTE(sess->f4c); f50_high = HIBYTE(sess->f50); devid = sess->devid; v53 = f4c_high | (LOBYTE(sess->f50) << 8) | ((BYTE1(sess->f50) | (BYTE2(sess->f50) << 8)) << 16); v44 = asd_rpc_1a7(devid, &v53, 1u, sess->buf268); if ( v44 != 0 || (v45 = sess->rx_count, ta_memcpy(&v53, sess->rx_ids, 5 * v45), (v44 = asd_rpc_1a7(sess->devid, &v53, v45, sess->buf268)) != 0) ) { if ( v44 != 23 ) return 17; LABEL_59: sess->err_state = 7; *out = 112; return 17; } *out = 0; return 0; } /* ================================================================ */ /* hdcp_subcmd_dispatch @ 0x402910 */ int __fastcall hdcp_subcmd_dispatch(struct hdcp_session *a1, int *a2, unsigned __int8 *a3, unsigned int a4, int *a5) { unsigned int v5; // r5 int v6; // r1 int v7; // r1 int v8; // r0 v5 = a2[1]; if ( v5 <= a4 ) { v7 = *a2; if ( v7 == 1 ) { v8 = 2; } else if ( v7 == *a3 ) { switch ( v7 ) { case 3: return sub_4023DC((int)a1, a3 + 1, v5 - 1, a5); case 6: return sub_4028B0((int)a1, (char *)a3 + 1, v5 - 1, a5); case 7: return sub_4025AC((int)a1, (int)(a3 + 1), v5 - 1, a5); case 8: return sub_4027E0((int)a1, (int)(a3 + 1), v5 - 1, a5); case 10: return sub_4029F2((int)a1, (int)(a3 + 1), v5 - 1, a5); case 12: return hdcp_subcmd12_rxinfo(a1, a3 + 1, v5 - 1, a5); case 13: v6 = 1; if ( a1 == nullptr || a5 == nullptr ) return v6; *a5 = 100; if ( v5 == 1 ) { v6 = 0; *a5 = 0; return v6; } a1->err_state = 7; v8 = 109; break; case 17: JUMPOUT(0x402E90); case 18: return sub_402A4C((int)a1, a3 + 1, v5 - 1, a5); case 20: return sub_402380((int)a1, a3 + 1, v5 - 1, a5); default: v8 = 105; break; } } else { a1->err_state = 7; v8 = 102; } v6 = 0; *a5 = v8; } else { a1->err_state = 7; *a5 = 101; return 21; } return v6; } /* ================================================================ */ /* hdcp_cmd0F_handler @ 0x4021a0 */ int __fastcall hdcp_cmd0F_handler(const void *a1, int a2) { int v4; // r6 unsigned int v5; // r5 int v6; // r11 struct hdcp_session *v7; // r10 unsigned int active; // r0 bool v9; // zf int v11; // r2 _DWORD *v12; // r2 int v13; // t1 int v14; // r2 _DWORD *v15; // r7 int v16; // r1 int v17; // r2 int v18; // r0 _DWORD *v19; // [sp+8h] [bp-26Ch] int v20; // [sp+Ch] [bp-268h] BYREF int v21; // [sp+10h] [bp-264h] BYREF int v22; // [sp+14h] [bp-260h] BYREF int v23; // [sp+18h] [bp-25Ch] BYREF int v24; // [sp+1Ch] [bp-258h] BYREF __int64 v25; // [sp+20h] [bp-254h] BYREF unsigned int v26; // [sp+28h] [bp-24Ch] BYREF int v27; // [sp+2Ch] [bp-248h] BYREF int v28; // [sp+30h] [bp-244h] int v29; // [sp+34h] [bp-240h] BYREF int v30; // [sp+38h] [bp-23Ch] int v31; // [sp+3Ch] [bp-238h] BYREF unsigned __int8 v32[544]; // [sp+44h] [bp-230h] BYREF int v33; // [sp+264h] [bp-10h] int v34; // [sp+268h] [bp-Ch] ta_memclr(&v26, 0x244u); v4 = 2; v25 = 0; if ( a1 != nullptr && a2 != 0 ) { ta_memcpy_aligned(&v26, a1, 0x244u); v5 = v26; if ( v26 <= 7 ) { v6 = dword_40237C; v7 = (struct hdcp_session *)(dword_40237C + 652 * v26); active = v7->active; v9 = active == 1; if ( active == 1 ) v9 = v7->state == 2; if ( v9 ) { v11 = dword_40237C + 652 * v26; v4 = 0; *(_DWORD *)(a2 + 36) = 100; *(_DWORD *)(a2 + 4) = 0; *(_DWORD *)(a2 + 8) = 0; *(_DWORD *)(a2 + 12) = 0; *(_DWORD *)(a2 + 16) = 0; *(_DWORD *)(a2 + 20) = 100; *(_DWORD *)(a2 + 24) = 100; *(_DWORD *)(a2 + 28) = 100; *(_DWORD *)(a2 + 32) = 100; v13 = *(_DWORD *)(v11 + 24); v12 = (_DWORD *)(v11 + 24); if ( v13 == 7 ) return v4; v19 = v12; v24 = 100; v22 = 100; v23 = 100; v4 = hdcp_subcmd_dispatch(v7, &v27, v32, 0x220u, &v24); if ( v4 != 0 || (v4 = hdcp_subcmd_dispatch(v7, &v29, &v32[v28], 544 - v28, &v23)) != 0 ) { v14 = v23; *(_DWORD *)(a2 + 20) = v24; *(_DWORD *)(a2 + 24) = v14; *(_DWORD *)(a2 + 28) = 100; } else { v4 = hdcp_subcmd_dispatch(v7, &v31, &v32[v28 + v30], 544 - (v28 + v30), &v22); v16 = v22; v17 = v23; *(_DWORD *)(a2 + 20) = v24; *(_DWORD *)(a2 + 24) = v17; *(_DWORD *)(a2 + 28) = v16; if ( v4 == 0 ) { v18 = v6 + 652 * v5; *(_DWORD *)(a2 + 4) = *(_DWORD *)(v18 + 36); *(_DWORD *)(a2 + 8) = *(_DWORD *)(v18 + 40); *(_DWORD *)(a2 + 12) = *(unsigned __int8 *)(v18 + 44); *(_DWORD *)(a2 + 16) = *(unsigned __int8 *)(v18 + 45); v20 = 100; v21 = 100; v4 = sub_4020E0((int)v7, v33, a2 + 56, 168, &v25, &v21); *(_QWORD *)(a2 + 40) = v25; v15 = v19; *(_DWORD *)(a2 + 32) = v21; if ( v4 == 0 ) { if ( HIDWORD(v25) >= 0xA8 ) { v4 = 21; *(_DWORD *)(a2 + 36) = 101; } else { v4 = sub_4020E0((int)v7, v34, a2 + HIDWORD(v25) + 56, 168 - HIDWORD(v25), (_DWORD *)(a2 + 48), &v20); *(_DWORD *)(a2 + 36) = v20; if ( v4 == 0 ) { if ( *v19 == 8 || *v19 == 6 ) v4 = 0; else v4 = 0; goto LABEL_15; } } } LABEL_14: *v15 = 7; LABEL_15: if ( sub_4046D8() != 0 ) return 17; *(_DWORD *)a2 = *v15; return v4; } } v15 = v19; v20 = 100; v21 = 100; goto LABEL_14; } } return 1; } return v4; } /* ================================================================ */ /* hdcp_cmd0E_open @ 0x401ebc */ int __fastcall hdcp_cmd0E_open(__int64 *a1, int *a2) { int result; // r0 int v4; // r3 _DWORD *v5; // r5 __int64 v6; // kr00_8 int i; // r2 int v8; // r6 unsigned int *v9; // r6 int v10; // r1 result = 2; if ( a1 != nullptr && a2 != nullptr ) { v4 = dword_401F54; v5 = (_DWORD *)(dword_4020DC + 1268); v6 = *a1; for ( i = 1; ; ++i ) { if ( i == 8 ) return 3; if ( *(_DWORD *)((char *)v5 + dword_401F54) == 0 ) break; v5 += 163; } v8 = dword_401F58; *a2 = i; *(_DWORD *)((char *)v5 + v8) = v6; *(_DWORD *)((char *)v5 + v4) = 1; *(_DWORD *)((char *)v5 + dword_401F5C) = 2; if ( sub_404626() != 0 ) return 17; v9 = v5 - 153; if ( HIDWORD(v6) == 1 ) { v10 = 0; } else { v10 = 1; if ( HIDWORD(v6) != 2 ) v6 = 0x200000002LL; } *(_DWORD *)((char *)v5 + dword_401F60) = v10; *(_DWORD *)((char *)v5 + dword_401F64) = v6; if ( asd_rpc_1a3(*v9, SHIDWORD(v6)) != 0 || asd_topology_query(*v9, v5 - 150) != 0 ) { return 17; } else { *(_DWORD *)((char *)v5 + dword_401F68) = 0; *(v5 - 6) = -1; *(v5 - 5) = 0; *v5 = 0; return 0; } } return result; }