i64
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:
- prints the greeting,
- reads a string from standard input,
- prints
Nop :(, - 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 read-only • copy allowed0x4a2f10: 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 at0x4a2f28,rcxis the loop index,- each byte is decoded by subtracting
0x34, - the loop runs for
0x1cbytes, 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 read-only • copy allowed#!/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 read-only • copy allowedCODEBY{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