// MERIT TA command surface, decompiled with restored names, prototypes and types. // Source: psp_out/versions_win/ta_0.7.0.1_444eceee.bin // Handlers resolved from fw/cmdmaps/merit.json; loc_* labels mapped to their // containing function. Generated by fw/ta_surface.py. // ================ cmd 0x1 @ 0x401900 ================ int __fastcall merit_cmd01(void *ctx, struct ta_params *params) { int v2; // r2 _BYTE *v3; // r3 int v4; // r1 v2 = 1; v3 = (char *)&(*off_401CE0)[64] + 1; v4 = dword_40192C; while ( v2 != 65 ) { if ( *v3 == 0 ) { *v3 = 1; *((_DWORD *)ctx + 1033) = v2; return 0; } v3 += 257; ++v2; } return v4; } // ================ cmd 0x6 @ 0x401930 ================ int __fastcall merit_cmd06(void *ctx, struct ta_params *params) { int v2; // r0 int v3; // r0 v2 = *((_DWORD *)ctx + 4); if ( (unsigned int)(v2 - 1) > 0x3F ) return 259; v3 = 257 * v2; if ( *((_BYTE *)off_401CE0 + v3) == 0 ) return 259; if ( *((_BYTE *)off_401CE0 + v3) == 1 ) merit_lib_zero_fill_bytes(dst: (char *)off_401CE0 + v3, len: 0x101u); return 0; } // ================ cmd 0x4 @ 0x40195c ================ // Slot lookup, CORRECTLY bounded (checked, negative). // // v5 = *(params+16) host index // guard (v5 - 1) <= 0x3F -> v5 in [1,64] // slot presence byte at off_401CE0 + 257*v5, required != 0 (liveness IS checked) // // The 1-based range is right, not an off-by-one: the allocator merit_cmd01 walks v1 = 1 // while v1 != 65 with v2 += 257 starting at base+257, so valid slots are 1..64, and // merit_TA_CreateEntryPoint zero-fills 0x4141 = 257*65 bytes, i.e. the whole array // including the unused slot 0. So index 64 is the last valid slot and the guard matches // the allocator exactly. // // Flagged by fw/ta_liveness_audit.py only because its liveness test is '!= 0' rather than // a compare against a small constant; recorded so the lead is not re-opened. int __fastcall merit_cmd04(void *ctx, struct ta_params *params) { int v2; // r7 int *v3; // r8 _DWORD *v4; // r6 int v6; // r0 int result; // r0 char *v8; // r5 int v9; // r0 int v10; // r1 _BYTE *v11; // r5 unsigned int dst[4]; // [sp+8h] [bp-104h] BYREF int v13; // [sp+28h] [bp-E4h] int v14; // [sp+2Ch] [bp-E0h] int v15; // [sp+108h] [bp-4h] v4 = (_DWORD *)off_401BD8; v15 = *(_DWORD *)off_401BD8; v6 = *((_DWORD *)ctx + 4); if ( (unsigned int)(v6 - 1) <= 0x3F && (v3 = (int *)off_401CE0, v2 = 257 * v6, *((_BYTE *)off_401CE0 + 257 * v6) != 0) ) { merit_lib_zero_fill_words(dst, len: 0x100u); if ( merit_cmd04__h1(ctx: (char *)ctx + 20, params: *((struct ta_params **)ctx + 69)) == 0 ) goto LABEL_8; result = 267; } else { result = 259; } while ( *v4 != v15 ) { ((void (__fastcall *)(int, int))loc_40202C)(a1: result, a2: *v4 - v15); LABEL_8: v8 = (char *)v3 + v2; if ( merit_lib_52b900d8_88(a1: (int)v3 + v2 + 1, a2: (int)dst, a3: 16) != 0 ) { result = 560; } else { merit_lib_thunk_tailjump(a1: (int)(v8 + 17)); v9 = v13; v10 = v14; v8[33] = v13; v11 = v8 + 33; v11[4] = v10; v11 += 4; v11[3] = HIBYTE(v10); v11[2] = BYTE2(v10); v11[1] = BYTE1(v10); *(v11 - 1) = HIBYTE(v9); *(v11 - 2) = BYTE2(v9); *(v11 - 3) = BYTE1(v9); result = 0; } } return result; } // ================ cmd 0x2 @ 0x401a18 ================ int __fastcall merit_cmd02(void *ctx, struct ta_params *params) { int v4; // r0 int v5; // r1 int v6; // [sp+0h] [bp-28h] BYREF merit_lib_zero_fill_words(dst: &v6, len: 0x28u); if ( merit_asd_rpc_200(arg: (unsigned int)&v6) != 0 ) return 576; v4 = *((_DWORD *)ctx + 4); if ( v4 == 2 ) { *off_401CB8 = 2; v5 = 3947; goto LABEL_7; } if ( v4 == 1 ) { *off_401CB8 = 1; v5 = 3944; LABEL_7: *((_DWORD *)ctx + 1033) = v5; return 0; } return 544; } // ================ cmd 0x5 @ 0x401a90 ================ int __fastcall merit_cmd05(void *ctx, struct ta_params *params) { _DWORD *v2; // r8 void *v4; // r4 int *v5; // r7 int v6; // r6 unsigned __int8 *v7; // r9 int result; // r0 int v9; // r7 int *v10; // r11 int v11; // r0 int v12; // r10 bool v13; // zf int v14; // r3 int v15; // r6 int v16; // r7 _OWORD *v17; // r5 int v18; // r0 __int128 v19; // [sp+8h] [bp-14h] BYREF int v20; // [sp+18h] [bp-4h] v2 = (_DWORD *)off_401BD8; v20 = *(_DWORD *)off_401BD8; v4 = *((void **)ctx + 4); if ( (char *)v4 - 1 <= (char *)0x3F && (v5 = (int *)off_401CE0, v6 = 257 * (_DWORD)v4, *((_BYTE *)off_401CE0 + 257 * (_DWORD)v4) != 0) ) { if ( merit_cmd05__h1(ctx: v4, params: (struct ta_params *)((char *)ctx + 20)) == 0 ) goto LABEL_10; v7 = (unsigned __int8 *)v5 + v6 + 33; if ( *((_DWORD *)ctx + 17) == (*v7 | (*((unsigned __int8 *)v5 + v6 + 34) << 8) | ((*((unsigned __int8 *)v5 + v6 + 35) | (*((unsigned __int8 *)v5 + v6 + 36) << 8)) << 16)) ) { if ( merit_lib_52b900d8_88(a1: off_401BDC, a2: (int)ctx + 52, a3: 16) == 0 ) { v9 = *((_DWORD *)ctx + 19); v10 = (int *)off_401BE0; v11 = 0; while ( 1 ) { v12 = v11 + 16; if ( v11 == 128 ) break; v13 = merit_lib_52b900d8_88(a1: (int)v10 + v11, a2: (int)ctx + 80, a3: v9) == 0; v11 = v12; if ( v13 ) { v14 = *((_DWORD *)ctx + 10); v15 = *((_DWORD *)ctx + 11); v16 = *((_DWORD *)ctx + 12); *((_DWORD *)ctx + 1038) = *((_DWORD *)ctx + 9); *((_DWORD *)ctx + 1039) = v14; *((_DWORD *)ctx + 1040) = v15; *((_DWORD *)ctx + 1041) = v16; *((_DWORD *)ctx + 1042) = dword_401BE4; *((_DWORD *)ctx + 1037) = 20; merit_lib_zero_fill_words(dst: (char *)ctx + 4172, len: 0xFD8u); v17 = (char *)ctx + 4132; if ( ((int (__fastcall *)(_OWORD *, int, __int128 *, void *))loc_4012FC)( a1: v17, a2: 4096, a3: &v19, a4: v4) != 0 ) { result = 266; } else { *v17 = v19; v18 = ((*v7)++ | (v7[1] << 8) | ((v7[2] | (v7[3] << 8)) << 16)) + 1; v7[2] = BYTE2(v18); v7[3] = HIBYTE(v18); v7[1] = BYTE1(v18); result = 0; } goto LABEL_8; } } } result = 262; } else { result = 260; } } else { result = 259; } LABEL_8: while ( *v2 != v20 ) { ((void (__fastcall *)(int, int))loc_40202C)(a1: result, a2: *v2 - v20); LABEL_10: result = 261; } return result; } // ================ cmd 0x3 @ 0x401be8 ================ int __fastcall merit_cmd03(void *ctx, struct ta_params *params) { int v3; // r5 int *v4; // r7 int v5; // r5 char *v7; // r0 int v8; // [sp+0h] [bp-2Ch] BYREF v3 = *((_DWORD *)ctx + 4); merit_lib_zero_fill_words(dst: &v8, len: 0x28u); if ( (unsigned int)(v3 - 1) > 0x3F ) return 259; v4 = (int *)off_401CE0; v5 = 257 * v3; if ( *((_BYTE *)off_401CE0 + v5) == 0 ) return 259; if ( merit_asd_rpc_200(arg: (unsigned int)&v8) != 0 ) return 576; merit_sysdrv_rpc_35(a1: (int)v4 + v5 + 1, a2: 16); *((_DWORD *)ctx + 1037) = 16; merit_lib_thunk_tailjump(a1: (int)ctx + 4132); if ( *off_401CB8 == 2 ) { *((_DWORD *)ctx + 2025) = 3947; v7 = (char *)ctx + 4152; goto LABEL_10; } if ( *off_401CB8 == 1 ) { *((_DWORD *)ctx + 2025) = 3944; v7 = (char *)ctx + 4152; LABEL_10: merit_lib_thunk_tailjump(a1: (int)v7); } return 0; }