← Back to Writeups
CUSTOMEasyReversing

patch5

XESXOR9/2/20263 min read
#reversing#custom#easy#runtime_decrypted_shellcode#stack_string_analysis#static_shellcode_recovery#xor_decryption

patch5

Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: runtime_decrypted_shellcode, stack_string_analysis, static_shellcode_recovery, xor_decryption

Summary

Walkthrough of the CUSTOM Reversing patch5. Task: Windows PE32 crackme (task5.exe) that copies encrypted shellcode from .data, XOR-decrypts it at runtime, marks it RWX and calls it as a function to validate argv[1]. Solution: statically XOR the

Description

task5.exe — a Windows console crackme. Run it with a single argument; on the correct input it prints the key.

English summary: A PE32 (MSVC) console binary stores XOR-encrypted x86 shellcode in its .data section. At runtime it decrypts the shellcode, makes it executable, and calls it as a function to validate the command-line argument. The goal is to recover the password and the embedded key without executing it on Windows.

Analysis

The binary (task5.exe, PE32 x86, MSVC console) is a self-decrypting crackme. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

main @ 0x004012b0:

  1. Requires argc > 1.
  2. Computes strlen(argv[1]) via fcn.00404070 (standard MSVC strlen using the 0x7efefeff / 0x81010100 word trick). Exits if length is 0.
  3. VirtualAlloc of a 0x1000-byte page with PAGE_EXECUTE_READWRITE (0x40).
  4. Copies 34 (0x22) dwords from .data at 0x418000 into the buffer (mov eax,[eax*4+0x418000]; mov [edx+ecx*4],eax).
  5. Calls fcn.00401260(buffer, 0x22) — the decryptor.
  6. VirtualProtect to RWX, then calls the buffer as a function, pushing argv[1] and strlen(argv[1]).
  7. test eax,eax; on non-zero (success) prints the output buffer with "%s" (format string at 0x418088), then VirtualFree. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Decryptor fcn.00401260(ptr, count):

  • key = 0xcafebabe (local mov dword [ebp-8], 0xcafebabe).
  • For each of count (0x22 = 34) dwords: xor dword[i], 0xcafebabe.
  • Simple per-dword XOR decryption of the copied shellcode.

Decrypting statically (34 dwords XOR 0xcafebabe) yields 136 bytes of x86 shellcode:

push ebp; mov ebp,esp; push edi
mov eax,[ebp+0xc]              ; arg2 = strlen
cmp eax, 8
jne fail
mov edi,[ebp+8]               ; arg1 = input string
cmp dword[edi], 0x73697469    ; 'itis'
jne fail
cmp dword[edi+4], 0x79736165  ; 'easy'
jne fail
; success: write message into output buffer ([ebp+0x10])
; "Cong","ratu","lati","ons!","!! T","he k","ey i","s #D","EADB","EEF#", 0
mov eax,1
...
fail: xor eax,eax
ret

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

The check requires an 8-character input equal to the stack-strings 'itis' + 'easy' = itiseasy. On success the shellcode writes Congratulations!! The key is REDACTED into the output buffer.

Solution

No Windows execution needed — just XOR-decrypt the .data dwords and read the recovered shellcode.

python
#!/usr/bin/env python3
import struct

# 34 encrypted dwords from .data @ 0x418000 (extracted from task5.exe)
# Read the raw 136 bytes directly from the PE .data section, then XOR.
with open("data_blob.bin", "rb") as f:      # 34*4 = 136 bytes from 0x418000
    enc = f.read(34 * 4)
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

KEY = 0xcafebabe
dwords = struct.unpack("<34I", enc)
dec = b"".join(struct.pack("<I", d ^ KEY) for d in dwords)

with open("shellcode.bin", "wb") as f:
    f.write(dec)

# Recover the stack-string password and key from the decrypted bytes
print("password bytes present:", b"itis" in dec, b"easy" in dec)
print("key present:", b"REDACTED" in dec)
# Disassemble with: r2 -a x86 -b 32 -c 'pd 60' shellcode.bin

Running task5.exe itiseasy (or reading the decrypted shellcode statically) yields:

Congratulations!! The key is REDACTED

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Key Takeaways / Lessons

  • Mastering runtime_decrypted_shellcode, stack_string_analysis, static_shellcode_recovery, xor_decryption was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-06-25 • CUSTOM • patch5 • Difficulty: Easy