← Back to Writeups
CUSTOMEasyReversing

i64

XESXOR9/2/20263 min read
#reversing#custom#easy#ida_database_analysis#mapped_byte_recovery#hidden_code_discovery#bytewise_subtraction_decoding

i64

Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: ida_database_analysis, mapped_byte_recovery, hidden_code_discovery, bytewise_subtraction_decoding

Summary

Walkthrough of the CUSTOM Reversing i64. Task: only an IDA Pro .i64 database for a PE64 executable is provided, and the visible main function is a fake checker that always prints Nop :(. Solution: recover mapped bytes from the database, foll

Description

Мой коллега не доделал анализ исполняемого файла на наличие флага. Я знаю, ты поможешь ему =D

English summary: we are given only an IDA Pro 64-bit database, not the original executable. The visible main function is a decoy, so the real task is to recover hidden bytes from the database and find where startup or exit code reaches them.

Analysis

The archive task_ida.zip contains only task.exe.i64, an IDA database. Using python-idb, we can still recover useful metadata and mapped bytes from the ID1 section. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Recovered metadata shows the original program was a PE AMD64 executable with image base 0x400000, and the database records the original path as C:\Users\fff\Desktop\task.exe.

The first obvious place to inspect is main at 0x401550. Strings around it look exactly like a normal beginner flag checker:

  • Hello, Codeby!
  • Enter the flag:
  • Nop :(

But the disassembly proves that main only:

  1. prints the greeting,
  2. reads a string from standard input,
  3. prints Nop :(,
  4. returns.

There is no comparison, no transformation, and no success path. So main is a deliberate dead end. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

The important pivot is the CRT exit path. The function _cexit at 0x416f20 is not a normal implementation at all: it is just a trampoline that jumps to 0x4a2f10. That address is named _cexit_0 in the database. The startup flow around 0x4013e5 calls 0x416f20 after main returns, which means this hidden stub executes on program exit.

The hidden stub at 0x4a2f10 is the real decoder:

asm
0x4a2f10: lea rbx, [rip + 0x11]
0x4a2f17: xor rcx, rcx
0x4a2f1a: sub byte ptr [rbx + rcx], 0x34
0x4a2f1e: inc rcx
0x4a2f21: cmp rcx, 0x1c
0x4a2f25: jl 0x4a2f1a
0x4a2f27: ret

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

This is very compact but very clear:

  • lea rbx, [rip + 0x11] points to the byte array starting at 0x4a2f28,
  • rcx is the loop index,
  • each byte is decoded by subtracting 0x34,
  • the loop runs for 0x1c bytes, which is exactly 28 characters.

So the task is really about finding hidden patched bytes in the IDA database, not about the fake input prompt. The final flag string even comments on that design: REDACTED.

Solution

After recovering the mapped bytes from the ID1 section, take the 28 encoded bytes starting at 0x4a2f28 and apply the same logic as the stub: subtract 0x34 from each byte modulo 256. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

A minimal recovery script is enough:

python
#!/usr/bin/env python3

encoded = bytes([
    # 28 raw bytes from 0x4a2f28 in recovered mapped memory
    0x77, 0x83, 0x78, 0x79, 0x76, 0x8d, 0xaf, 0xa6,
    0x77, 0x86, 0x79, 0x86, 0x88, 0x63, 0x94, 0x74,
    0xa8, 0x77, 0x8c, 0x7c, 0x79, 0x88, 0x63, 0x76,
    0xad, 0x88, 0x66, 0xb1,
])

decoded = bytes((b - 0x34) & 0xff for b in encoded)
print(decoded.decode())

Running it prints:

text
CODEBY{REDACTED}

The key lesson is that an IDA database can still contain enough mapped bytes to recover hidden logic, even when the original executable is missing. Here the visible checker is fake, while the real flag sits in encoded bytes behind a tiny decoder reached from the CRT exit trampoline. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering ida_database_analysis, mapped_byte_recovery, hidden_code_discovery, bytewise_subtraction_decoding was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-04-06 • CUSTOM • i64 • Difficulty: Easy