---
# System prepended metadata

title: Write-up REEZS

---

Hello guys🤗! today i will write about a REV challenge that met at the CSCV2025 that named:***Reezs***.  

![image](https://hackmd.io/_uploads/SkxObFzAxe.png)

First when you install the file and extract the folder you will have an .exe file like this:     
![image](https://hackmd.io/_uploads/B1I12bfRel.png)
 When you run that file, you will see an CMD that told you enter the flag:
 ![image](https://hackmd.io/_uploads/r1JH3-MClx.png)
Since there were no clues at first, I typed some random input to see how the program executes. As expected, it shut down immediately.  
Then I opened IDA and loaded the file to read the main function and understand the execution flow. In IDA View-A, the main function looks like this:  

![image](https://hackmd.io/_uploads/SJ5kAWfCex.png)  

Let F5 to see that pseudocode:
```


int __fastcall main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rdx
  __int64 v4; // r8
  __m128i si128; // xmm0
  const char *v6; // rcx
  _BYTE v8[32]; // [rsp+0h] [rbp-58h] BYREF
  char Str[16]; // [rsp+20h] [rbp-38h] BYREF
  __m128i v10; // [rsp+30h] [rbp-28h]
  __int64 v11; // [rsp+40h] [rbp-18h]
  __int64 v12; // [rsp+48h] [rbp-10h]

  v10 = 0i64;
  *(_OWORD *)Str = 0i64;
  v11 = 0i64;
  sub_1400010F0("Enter flag: ", argv, envp);
  sub_140001170("%32s", Str);
  if ( strlen(Str) != 32 )
  {
    puts("No");
    if ( ((unsigned __int64)v8 ^ v12) == _security_cookie )
      return 0;
LABEL_5:
    __debugbreak();
  }
  si128 = _mm_load_si128((const __m128i *)&xmmword_14001E030);
  *(__m128i *)Str = _mm_xor_si128(_mm_load_si128((const __m128i *)Str), si128);
  v10 = _mm_xor_si128(si128, v10);
  if ( _mm_movemask_epi8(
         _mm_and_si128(
           _mm_cmpeq_epi8(*(__m128i *)Str, (__m128i)xmmword_140029000),
           _mm_cmpeq_epi8(v10, (__m128i)xmmword_140029010))) == 0xFFFF )
    v6 = (const char *)&unk_140023E7C;
  else
    v6 = "No";
  sub_1400010F0(v6, v3, v4);
  if ( ((unsigned __int64)v8 ^ v12) != _security_cookie )
    goto LABEL_5;
  return 0;
}

```    

What are the important parts of that code we should care about? Let me explain.
```

 sub_1400010F0("Enter flag: ", argv, envp);
  sub_140001170("%32s", Str);
```
This line ask us to type 32-byte strings input 32-byte strings(or we know the flag will have 32-byte strings not include the format flag)
```
 
si128 = _mm_load_si128((const __m128i *)&xmmword_14001E030);
```
This line point that it takes 16-byte constant of the **xmmord_14001E030** adress into **si128**
```

*(__m128i *)Str = _mm_xor_si128(_mm_load_si128((const __m128i *)Str), si128);
```
This line is load 16-byte of **Str** XOR with **si128** and the result is the first stage 16-byte strings of the **Str**
```

v10 = _mm_xor_si128(si128, v10);
```
**v10** at first is assigned to **0i64**, which is full of 0. If we XOR with **si128**, we will receive si128  

```
if ( _mm_movemask_epi8(
         _mm_and_si128(
           _mm_cmpeq_epi8(*(__m128i *)Str, (__m128i)xmmword_140029000),
           _mm_cmpeq_epi8(v10, (__m128i)xmmword_140029010))) == 0xFFFF )
```
This comparision can be analyze to smaller like this:
```

 _mm_cmpeq_epi8(*(__m128i *)Str, (__m128i)xmmword_140029000),
```
=>Return 16-byte, each byte = 0xFF if **(__m128i )Str == (__m128i)xmmword_140029000, else = 0x00**

```

_mm_and_si128(
```
=>Only keep if both comparisons are equal at the same position
```
_mm_movemask_epi8(
```
=>take top 16-bit of each byte,if the result is 0xFFFF it means the 16-bit verified(or all 16 bytes were equal in both comparisons).

If both of conditions are true, the program will print:
```
(const char *)&unk_140023E7C
```
That is yes:
```
.rdata:0000000140023E7C unk_140023E7C   db  59h ; Y             ; DATA XREF: main:loc_1400010CA↑o
.rdata:0000000140023E7D                 db  65h ; e
.rdata:0000000140023E7E                 db  73h ; s
.rdata:0000000140023E7F                 db    0
```


And i find this when point to **xmmword_140029010** and press X(jump to xref)

```
{
  BOOL result; // eax

  result = IsDebuggerPresent();
  if ( !result )
  {
    xmmword_140029010 = xmmword_14001E010;
    xmmword_140029000 = xmmword_14001E000;
  }
  return result;
}
```
=>If you run the binary in a debugger, those constants at **0x140029010** and **0x140029000** won’t be initialized=>an anti-debugger trick. And if you don't run in a debugger, 
**xmmword_140029010** will be **xmmword_14001E010** and   **xmmword_140029000** will be **xmmword_14001E000**

So i will use what i explained below to extract the flag:  

```
.rdata:000000014001E000 xmmword_14001E000 xmmword 939FCF9C9B9998C99DC8C9989ECFCB9Ah
.rdata:000000014001E010 xmmword_14001E010 xmmword 9F9D9D9DCB989A9B999A98CF9DCFCFCFh
.rdata:000000014001E030 xmmword_14001E030 xmmword 0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh
```
+The first stage we take first 16-bytes of **xmmword_14001E000** change into hex, then XOR with **xmmword_14001E030**

The the first 16-byte of **xmmword_14001E000** is:
```
unsigned char ida_chars[] = {
  0x9A, 0xCB, 0xCF, 0x9E, 0x98, 0xC9, 0xC8, 0x9D,
  0xC9, 0x98, 0x99, 0x9B, 0x9C, 0xCF, 0x9F, 0x93
};

```
XOR with 0xaa(**xmmword_14001E030**) into hex:
```
30 61 65 34 32 63 62 37 63 32 33 31 36 65 35 39

```
ASCII:
```
0ae42cb7c2316e59

```
+The second stage we take first 16-bytes of **xmmword_14001E010** change into hex, then XOR with **xmmword_14001E030**

The the first 16-byte of **xmmword_14001E000** is:
```
unsigned char ida_chars[] = { 0xCF, 0xCF, 0xCF, 0x9D, 0xCF, 0x98, 0x9A, 0x99, 0x9B, 0x9A, 0x98, 0xCB, 0x9D, 0x9D, 0x9D, 0x9F };

```
XOR with 0xaa(**xmmword_14001E030**) into hex:
```
65 65 65 37 65 32 30 33 31 30 32 61 37 37 37 35

```
ASCII:
```
eee7e203102a7775

```
And the flag is CSCV2025{0ae42cb7c2316e59eee7e203102a7775}

That's all of this challenge. Thanks for reading😘!