Tags: trustzone 


First challenge in trustzone. Open task1 in ida, check strings window and see strings like `TEEC_FinalizeContext`,`TEEC_InvokeCommand`,`TEEC_CloseSession`. Google it and got [client spetsification](http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=2C3A19C13215CE2ACB0A0069B09B5039?doi= [GlobalPlatform API tee](https://globalplatform.org/wp-content/uploads/2018/06/GPD_TEE_Internal_Core_API_Specification_v1.1.2.50_PublicReview.pdf) specification with prototypes of these functions.This will help a lot with the reverse of all tasks.
TEEC_Result TEEC_InvokeCommand(
TEEC_Session* session,
uint32_t commandID,
TEEC_Operation* operation,
uint32_t* returnOrigin)
in main function rename vars and got this, TEEC_Operation is struct like this
typedef struct
uint32_t started;
uint32_t paramTypes;
TEEC_Parameter params[4];
uint32_t imp;
} TEEC_Operation;
typedef union
TEEC_TempMemoryReference tmpref;
TEEC_MemoryReference memref;
} TEEC_Parameter;
In our challenge 32bit binary hence referense and uint32_t equal add in ida.
client invoking command with id 1,remember it and open TA.
Trying open TA in ida ond see that is opening as blob. Open in hex editor and seen ELF signature, cut first 0x148 bytes(it's just sign), reopen in IDA and it's work.
On start function we see one call. Check it and found nothing
BLX sub_CF24
check with file
$ file 00dec0de-d0d0-0ebb-fade-fadedead0001.ta
00dec0de-d0d0-0ebb-fade-fadedead0001.ta: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, stripped

check strings and found some interesting `Got value: %u from NW`, Got value from normal world,maybe is one of handlers,check referene and found function `sub_114` witch called from `sub_1E4` when second arg is 1(Hmmm)
signed int __fastcall sub_1E4(int a1, int a2, int a3, _DWORD *a4)
signed int v4; // r3

if ( a2 == 1 )
v4 = dec_value(a3, a4);
v4 = 0xFFFF0006;
return v4;
signed int __fastcall dec_value(int a1, _DWORD *a2)
int v7; // [sp+10h] [bp+0h]
int v8; // [sp+14h] [bp+4h]

v8 = 3;
v7 = 0;
log_35E((int)"dec_value", 0x4D, 3, 1, "has been called");
if ( a1 != 3 )
return -65530;
log_35E((int)"dec_value", 81, 3, 1, "Got value: %u from NW", *a2);
getprop_1F96(-1, (int)"unictf.2020.data.key", (int)&v7;;
*a2 ^= v7;
log_35E((int)"dec_value", 84, 3, 1, "Return value is: %u", *a2);
return 0;
Just xoring with some value,brutefroce this value or try find `"unictf.2020.data.key"` in binary
int __fastcall getprop_1F96(int a1, int prop, int buf)
int v3; // lr
int v5; // [sp+1Ch] [bp+Ch]
int v6; // [sp+20h] [bp+10h]
int v7; // [sp+24h] [bp+14h]
int v8; // [sp+2Ch] [bp+1Ch]

v8 = v3;
v5 = 4;
if ( buf )
v6 = 1;
v7 = sub_1B26((int *)a1, prop, &v6, buf, (int)&v5;;
if ( v6 != 1 )
v7 = 0xFFFF0005;
v7 = 0xFFFF0006;
return v7;
int __fastcall sub_1B26(int *a1, int a2, _DWORD *a3, int a4, int a5)
int v9; // r0
int v15; // [sp+20h] [bp+4h]
int v16; // [sp+24h] [bp+8h]
unsigned int v17; // [sp+28h] [bp+Ch]
int v18; // [sp+2Ch] [bp+10h]
unsigned int v19; // [sp+30h] [bp+14h]
int *v20; // [sp+34h] [bp+18h]
unsigned int i; // [sp+38h] [bp+1Ch]
int v22; // [sp+3Ch] [bp+20h]

v22 = sub_1964((int)a1, &v18, &v17);
return v22;
signed int __fastcall sub_1964(int a1, _DWORD *a2, _DWORD *a3)
switch ( a1 )
case (int)0xFFFFFFFF:
*a2 = &off_10238;
*a3 = 9;
return 0;
case (int)0xFFFFFFFE:
*a2 = 0;
*a3 = 0;
return 0;
case (int)0xFFFFFFFD:
*a2 = &off_102A4;
*a3 = 3;
return 0;
return -65528;
And got offset with props defined, props table have struct like this
struct prop{
char* name;
uint32_t type;
char* value;
We got xor key! Just xor bytes from client and get flag `unictf{b4by_TA}`
.data:00010298 DCD aUnictf2020Data_1 ; "unictf.2020.data.key"
.data:0001029C DCD 1
.data:000102A0 DCD unk_D990
.rodata:0000D990 unk_D990 DCB 0x41 ; A

flag = [0x34,0x2f,0x28,0x22,0x35,0x27,0x3a,0x23,0x75,0x23,0x38,0x1e,0x15,0x00,0x3c,0x41]
for i in flag: