/* merit 24.0.0.53 (7bc0749b) -- named functions * generated by fw/ta_re.py -- do not edit * reference: merit_24.0.4.42_444eceee.elf * functions: 36 total in build, 29 named, 7 anonymous * porting tiers: {"DISPATCH": 2, "EXACT": 9, "FUZZY": 0, "MNEM": 11, "ambiguous": 4, "cmd_protos": 6, "comments": 0, "dispatch_conflict": 0, "none": 10, "protos": 6, "relabelled": 0, "types": 1} * * Addresses are omitted and functions are ordered by NAME so that the same * function lines up across versions. See the .index.json sidecar for * name -> address. * * CAUTION on ported names: a name is only an identity claim at tier=EXACT. * At tier=MNEM/FUZZY the bytes differ from the reference, so any ADDRESS or * CONTENT HASH embedded in the name (e.g. *_4025F8, gcp_lib__*) still * refers to the REFERENCE build and does not describe this one. */ /* ==== merit_TA_CloseSessionEntryPoint [tier=ENTRY size=2] ==== */ void merit_TA_CloseSessionEntryPoint() { ; } /* ==== merit_TA_CreateEntryPoint [tier=MNEM size=16] ==== */ int merit_TA_CreateEntryPoint() { merit_lib_zero_fill_bytes(result: (int *)off_401DE8, a2: 0x4141u); return 0; } /* ==== merit_TA_DestroyEntryPoint [tier=ENTRY size=2] ==== */ void merit_TA_DestroyEntryPoint() { ; } /* ==== merit_TA_InvokeCommandEntryPoint [tier=ENTRY size=132] ==== */ int __fastcall merit_TA_InvokeCommandEntryPoint(int a1, int a2, char a3, struct merit_req **a4) { int result; // r0 struct merit_req *v6; // r5 int v7; // r0 unsigned int v8; // r0 result = dword_401E74 + 6; if ( (a3 & 0xF) == 7 && a4 != nullptr ) { if ( (unsigned int)a4[1] >= 0x2024 ) { v6 = *a4; if ( *a4 != nullptr ) { switch ( *(_DWORD *)v6 ) { case 1: v7 = merit_cmd01(ctx: *a4, params: (struct ta_params *)dword_401E74); break; case 2: v7 = merit_cmd02(ctx: *a4, params: (struct ta_params *)dword_401E74); break; case 3: v7 = merit_cmd03(ctx: *a4, params: (struct ta_params *)dword_401E74); break; case 4: v7 = merit_cmd04(ctx: *a4, params: (struct ta_params *)dword_401E74); break; case 5: v7 = merit_cmd05(ctx: *a4, params: (struct ta_params *)dword_401E74); break; case 6: v7 = merit_cmd06(ctx: *a4, params: (struct ta_params *)dword_401E74); break; default: v7 = 258; break; } *((_DWORD *)v6 + 2) = v7; v8 = (unsigned int)a4[1]; *(_DWORD *)v6 = v8; *((_DWORD *)v6 + 1) = v8 | 0x80000000; return 0; } else { return dword_401E74; } } else { return dword_401E74 + 16; } } return result; } /* ==== merit_TA_OpenSessionEntryPoint [tier=EXACT size=4] ==== */ int merit_TA_OpenSessionEntryPoint() { return 0; } /* ==== merit_cmd01 [tier=DISPATCH size=44] ==== */ int __fastcall merit_cmd01(void *ctx, struct ta_params *params) { _BYTE *v2; // r2 int i; // r1 v2 = (char *)&(*off_401DE8)[64] + 1; for ( i = 1; ; ++i ) { if ( i == 65 ) return 256; if ( *v2 == 0 ) break; v2 += 257; } *v2 = 1; *((_DWORD *)ctx + 1033) = i; return 0; } /* ==== merit_cmd02 [tier=MNEM size=120] ==== */ 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(result: &v6, a2: 0x28u); if ( merit_sysdrv_rpc_200() != 0 ) return 576; v4 = *((_DWORD *)ctx + 4); if ( v4 == 2 ) { *off_401DC0 = 2; v5 = 3947; goto LABEL_7; } if ( v4 == 1 ) { *off_401DC0 = 1; v5 = 3944; LABEL_7: *((_DWORD *)ctx + 1033) = v5; return 0; } return 544; } /* ==== merit_cmd03 [tier=MNEM size=208] ==== */ int __fastcall merit_cmd03(void *ctx, struct ta_params *params) { int v3; // r5 int v5; // [sp+0h] [bp-2Ch] BYREF v3 = *((_DWORD *)ctx + 4); merit_lib_zero_fill_words(result: &v5, a2: 0x28u); if ( (unsigned int)(v3 - 1) > 0x3F || *((_BYTE *)off_401DE8 + 257 * v3) == 0 ) return 259; if ( merit_sysdrv_rpc_200() != 0 ) return 576; merit_sysdrv_rpc_35(); *((_DWORD *)ctx + 1037) = 16; merit_lib_thunk_tailjump(); if ( *off_401DC0 == 2 ) { *((_DWORD *)ctx + 2025) = 3947; goto LABEL_10; } if ( *off_401DC0 == 1 ) { *((_DWORD *)ctx + 2025) = 3944; LABEL_10: merit_lib_thunk_tailjump(); } return 0; } /* ==== merit_cmd04 [tier=MNEM size=186] ==== */ int __fastcall merit_cmd04(void *ctx, struct ta_params *params) { int v2; // r7 int *v3; // r8 int *v4; // r6 int v6; // r0 int v7; // r1 int result; // r0 char *v9; // r5 int v10; // r0 int v11; // r1 _BYTE *v12; // r5 unsigned int v13; // [sp+4h] [bp-108h] BYREF _DWORD v14[8]; // [sp+8h] [bp-104h] BYREF int v15; // [sp+28h] [bp-E4h] int v16; // [sp+2Ch] [bp-E0h] int v17; // [sp+108h] [bp-4h] v4 = off_401CE0; v17 = *off_401CE0; v6 = *((_DWORD *)ctx + 4); if ( (unsigned int)(v6 - 1) <= 0x3F && (v3 = (int *)off_401DE8, v2 = 257 * v6, *((_BYTE *)off_401DE8 + 257 * v6) != 0) ) { merit_lib_zero_fill_words(result: v14, a2: 0x100u); v7 = *((_DWORD *)ctx + 69); v13 = 256; if ( sub_401468(a1: (int)ctx + 20, a2: v7, a3: (int)v14, a4: &v13) == 0 ) goto LABEL_8; result = 267; } else { result = 259; } while ( *v4 != v17 ) { ((void (__fastcall *)(int, int))loc_402110)(a1: result, a2: *v4 - v17); LABEL_8: v9 = (char *)v3 + v2; if ( sub_40205E(a1: (char *)v3 + v2 + 1, a2: v14, a3: 16) != 0 ) { result = 560; } else { merit_lib_thunk_tailjump(); v10 = v15; v11 = v16; v9[33] = v15; v12 = v9 + 33; v12[4] = v11; v12 += 4; v12[3] = HIBYTE(v11); v12[2] = BYTE2(v11); v12[1] = BYTE1(v11); *(v12 - 1) = HIBYTE(v10); *(v12 - 2) = BYTE2(v10); *(v12 - 3) = BYTE1(v10); result = 0; } } return result; } /* ==== merit_cmd05 [tier=DISPATCH size=324] ==== */ int __fastcall merit_cmd05(void *ctx, struct ta_params *params) { int *v2; // r6 unsigned int v3; // r7 int *v4; // r10 char *v5; // r5 int v6; // r4 int result; // r0 unsigned __int8 *v8; // r9 int *v9; // r11 int *v10; // r0 bool v11; // zf int v12; // r3 int v13; // r7 int v14; // r0 __int128 v15; // [sp+8h] [bp-14h] BYREF int v16; // [sp+18h] [bp-4h] v4 = off_401CE0; v5 = (char *)ctx; v16 = *off_401CE0; v6 = *((_DWORD *)ctx + 4); if ( (unsigned int)(v6 - 1) <= 0x3F && (v2 = (int *)off_401DE8, v3 = 257 * v6, *((_BYTE *)off_401DE8 + 257 * v6) != 0) ) { if ( ((int (__fastcall *)(int, char *, int, char *))loc_401348)( a1: v6, a2: (char *)ctx + 20, a3: 4112, a4: (char *)ctx + 20) == 0 ) goto LABEL_8; result = 261; } else { result = 259; } LABEL_6: while ( *v4 != v16 ) { ((void (__fastcall *)(int, int))loc_402110)(a1: result, a2: *v4 - v16); LABEL_8: v8 = (unsigned __int8 *)v2 + v3 + 33; if ( *((_DWORD *)v5 + 17) == (*v8 | (*((unsigned __int8 *)v2 + v3 + 34) << 8) | ((*((unsigned __int8 *)v2 + v3 + 35) | (*((unsigned __int8 *)v2 + v3 + 36) << 8)) << 16)) ) { if ( merit_memcmp_be(a1: (unsigned int *)off_401CE4, a2: (unsigned int *)v5 + 13, a3: 0x10u) == 0 ) { v3 = *((_DWORD *)v5 + 19); v9 = (int *)off_401CE8; v10 = nullptr; while ( 1 ) { v2 = v10 + 4; if ( v10 == (int *)128 ) break; v11 = merit_memcmp_be(a1: (unsigned int *)((char *)v9 + (_DWORD)v10), a2: (unsigned int *)v5 + 20, a3: v3) == 0; v10 = v2; if ( v11 ) { v12 = *((_DWORD *)v5 + 10); v2 = *((int **)v5 + 11); v13 = *((_DWORD *)v5 + 12); *((_DWORD *)v5 + 1038) = *((_DWORD *)v5 + 9); *((_DWORD *)v5 + 1039) = v12; *((_DWORD *)v5 + 1040) = v2; *((_DWORD *)v5 + 1041) = v13; *((_DWORD *)v5 + 1042) = dword_401CEC; *((_DWORD *)v5 + 1037) = 20; merit_lib_zero_fill_words(result: (_DWORD *)v5 + 1043, a2: 0xFD8u); v5 += 4132; v3 = (unsigned int)&v15; if ( ((int (__fastcall *)(char *, int, __int128 *, int))loc_40130C)(a1: v5, a2: 4096, a3: &v15, a4: v6) != 0 ) { result = 266; } else { *(_OWORD *)v5 = v15; v5 += 16; v14 = ((*v8)++ | (v8[1] << 8) | ((v8[2] | (v8[3] << 8)) << 16)) + 1; v8[2] = BYTE2(v14); v8[3] = HIBYTE(v14); v8[1] = BYTE1(v14); result = 0; } goto LABEL_6; } } } result = 262; } else { result = 260; } } return result; } /* ==== merit_cmd05__h2 [tier=MNEM size=36] ==== */ int merit_cmd05__h2() { _DWORD v5[12]; // [sp+8h] [bp-78h] BYREF merit_lib_zero_fill_words(result: v5, a2: 0x20u); __asm { SVC 0xF2 } return 1; } /* ==== merit_cmd06 [tier=MNEM size=44] ==== */ 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_401DE8 + v3) == 0 ) return 259; if ( *((_BYTE *)off_401DE8 + v3) == 1 ) merit_lib_zero_fill_bytes(result: (_BYTE *)off_401DE8 + v3, a2: 0x101u); return 0; } /* ==== merit_lib_thunk_tailjump [tier=EXACT size=4] ==== */ void merit_lib_thunk_tailjump() { JUMPOUT(0x401702); } /* ==== merit_lib_zero_fill_bytes [tier=EXACT size=68] ==== */ _BYTE *__fastcall merit_lib_zero_fill_bytes(_BYTE *result, unsigned int a2) { int v2; // r12 _BYTE *v3; // r0 if ( a2 >= 4 ) { if ( ((unsigned __int8)result & 3) != 0 ) { v2 = 4 - ((unsigned __int8)result & 3); if ( v2 != 2 ) *result++ = 0; if ( v2 >= 2 ) *(_WORD *)result = 0; } JUMPOUT(0x401128); } if ( __CFSHL__(a2, 31) ) { *result = 0; v3 = result + 1; *v3 = 0; result = v3 + 1; } if ( (a2 & 1) != 0 ) *result++ = 0; return result; } /* ==== merit_lib_zero_fill_words [tier=EXACT size=78] ==== */ _DWORD *__fastcall merit_lib_zero_fill_words(_DWORD *result, unsigned int a2) { bool v2; // cf unsigned int v3; // r1 _DWORD *v4; // r0 int v5; // r1 int v6; // r1 v2 = a2 >= 0x20; v3 = a2 - 32; do { if ( !v2 ) break; *result = 0; result[1] = 0; result[2] = 0; result[3] = 0; v4 = result + 4; *v4 = 0; v4[1] = 0; v4[2] = 0; v4[3] = 0; result = v4 + 4; v2 = v3 >= 0x20; v3 -= 32; } while ( v2 ); v2 = __CFSHL__(v3, 28); v5 = v3 << 28; if ( v2 ) { *result = 0; result[1] = 0; result[2] = 0; result[3] = 0; result += 4; } if ( v5 < 0 ) { *result = 0; result[1] = 0; result += 2; } v2 = __CFSHL__(v5, 2); v6 = 4 * v5; if ( v2 ) *result++ = 0; if ( v6 != 0 ) { if ( v6 < 0 ) { *(_WORD *)result = 0; result = (_DWORD *)((char *)result + 2); } if ( (v6 & 0x40000000) != 0 ) { *(_BYTE *)result = 0; return (_DWORD *)((char *)result + 1); } } return result; } /* ==== merit_memcmp_be [tier=EXACT size=88] ==== */ int __fastcall merit_memcmp_be(unsigned int *a1, unsigned int *a2, unsigned int a3) { unsigned int v3; // r4 unsigned int v4; // r3 int v6; // r3 int v7; // t1 int v8; // t1 int v9; // r3 int v10; // r3 int v11; // t1 int v12; // t1 if ( ((unsigned int)a1 | (unsigned int)a2) << 30 == 0 ) { while ( a3 >= 4 ) { v3 = *a1++; v4 = *a2++; a3 -= 4; if ( v3 != v4 ) { if ( bswap32(v3) <= bswap32(v4) ) return -1; else return 1; } } } if ( a3 == 0 ) return 0; if ( a3 << 31 == 0 ) goto LABEL_11; ++a3; do { v11 = *(unsigned __int8 *)a1; a1 = (unsigned int *)((char *)a1 + 1); v10 = v11; v12 = *(unsigned __int8 *)a2; a2 = (unsigned int *)((char *)a2 + 1); v9 = v10 - v12; if ( v9 != 0 ) break; a3 -= 2; if ( a3 == 0 ) break; LABEL_11: v7 = *(unsigned __int8 *)a1; a1 = (unsigned int *)((char *)a1 + 1); v6 = v7; v8 = *(unsigned __int8 *)a2; a2 = (unsigned int *)((char *)a2 + 1); v9 = v6 - v8; } while ( v9 == 0 ); return v9; } /* ==== merit_sysdrv_rpc_1 [tier=MNEM size=60] ==== */ int merit_sysdrv_rpc_1() { _DWORD v5[12]; // [sp+8h] [bp-78h] BYREF merit_lib_zero_fill_words(result: v5, a2: 0x20u); __asm { SVC 0xF2 } return 1; } /* ==== merit_sysdrv_rpc_10 [tier=EXACT size=52] ==== */ int merit_sysdrv_rpc_10() { __asm { SVC 0xF2 } return 1; } /* ==== merit_sysdrv_rpc_200 [tier=SVCOP size=32] ==== */ int merit_sysdrv_rpc_200() { _DWORD v5[6]; // [sp+0h] [bp-18h] BYREF merit_lib_zero_fill_words(result: v5, a2: 0x18u); __asm { SVC 0xF2 } return 2; } /* ==== merit_sysdrv_rpc_201 [tier=SVCOP size=32] ==== */ int merit_sysdrv_rpc_201() { _DWORD v5[6]; // [sp+0h] [bp-18h] BYREF merit_lib_zero_fill_words(result: v5, a2: 0x18u); __asm { SVC 0xF2 } return 2; } /* ==== merit_sysdrv_rpc_3 [tier=SVCOP size=42] ==== */ int merit_sysdrv_rpc_3() { _DWORD v5[12]; // [sp+8h] [bp-78h] BYREF merit_lib_zero_fill_words(result: v5, a2: 0x20u); __asm { SVC 0xF2 } return 1; } /* ==== merit_sysdrv_rpc_30 [tier=MNEM size=50] ==== */ int merit_sysdrv_rpc_30() { _DWORD v5[12]; // [sp+8h] [bp+8h] BYREF merit_lib_zero_fill_words(result: v5, a2: 0x20u); __asm { SVC 0xF2 } return 1; } /* ==== merit_sysdrv_rpc_31 [tier=MNEM size=38] ==== */ int merit_sysdrv_rpc_31() { _DWORD v5[12]; // [sp+8h] [bp-78h] BYREF merit_lib_zero_fill_words(result: v5, a2: 0x20u); __asm { SVC 0xF2 } return 1; } /* ==== merit_sysdrv_rpc_33 [tier=MNEM size=52] ==== */ int merit_sysdrv_rpc_33() { _DWORD v5[10]; // [sp+10h] [bp+10h] BYREF merit_lib_zero_fill_words(result: v5, a2: 0x18u); __asm { SVC 0xF2 } return 1; } /* ==== merit_sysdrv_rpc_35 [tier=SVCOP size=42] ==== */ int merit_sysdrv_rpc_35() { _DWORD v5[28]; // [sp+10h] [bp-70h] BYREF merit_lib_zero_fill_words(result: v5, a2: 0x18u); __asm { SVC 0xF2 } return 1; } /* ==== merit_sysdrv_rpc_9 [tier=EXACT size=64] ==== */ int merit_sysdrv_rpc_9() { __asm { SVC 0xF2 } return 1; } /* ==== merit_sysdrv_rpc_E [tier=MNEM size=46] ==== */ int merit_sysdrv_rpc_E() { _DWORD v5[10]; // [sp+10h] [bp+10h] BYREF merit_lib_zero_fill_words(result: v5, a2: 0x18u); __asm { SVC 0xF2 } return 1; } /* ==== merit_ta_main_loop [tier=EXACT size=148] ==== */ void __fastcall __noreturn merit_ta_main_loop(int *a1) { int v6; // r1 void (__cdecl *v7)(); // r12 while ( 1 ) { __asm { SVC 0xF0 } v6 = *a1; if ( *a1 == 1 ) { v7 = (void (__cdecl *)())merit_TA_CreateEntryPoint; } else { switch ( v6 ) { case 2: v7 = (void (__cdecl *)())off_40211C; break; case 3: v7 = (void (__cdecl *)())off_402120; break; case 4: v7 = (void (__cdecl *)())off_402124; break; case 5: v7 = (void (__cdecl *)())off_402128; break; default: while ( 1 ) ; } } v7(); __asm { SVC 0xF1 } } } /* ==== nullsub_3 [tier=EXACT size=2] ==== */ void nullsub_3() { ; }