callmebaby
callmebaby
Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: byte_deref_search, decoy_function_filtering, strcmp_check_reversal, xor_constant_recovery
Summary
Walkthrough of the CUSTOM Reversing callmebaby. Task: 64-bit ELF crackme with 1000 decoy C++ Validate functions chained via calls (function-flood anti-analysis), the 'call me maybe' theme. Solution: programmatically find the only function that dere
Description
Just call me maybe
USAGE: %s <flag to check>
A 64-bit ELF callmebaby.elf (x86-64, dynamically linked, not stripped). It
takes the flag as argv[1] and prints Valid or Invalid. The flag is then
submitted to the platform via a POST flag parameter.
Goal: recover the flag accepted by the checker.
Analysis
The binary is a classic function-flood / decoy-chain anti-analysis crackme:
- It defines 1000 functions named
_Z18Validate<10 hexchars>Pc, i.e. the C++ mangled form ofValidateXXXXXXXXXX(char*). maincalls exactly one of them (Validate6c4b677a46) passingargv[1].- Each
Validatefunction is noise: it makes several junkrand()calls, thencalls the nextValidatefunction and returns its boolean result. This builds a 1000-deep call chain — the "call me maybe" theme — where 999 functions do nothing meaningful.
Tracing the entire chain by hand is the trap. The shortcut: only one function
actually touches the input. Every decoy ignores argv[1] entirely. So scan
the full disassembly for the single function that dereferences an input byte and
compares it — i.e. the one containing a movzx of [rax] together with a
cmp/strcmp.
bash read-only • copy allowedobjdump -d -M intel callmebaby.elf > callmebaby.asm # find the only function with a byte deref + comparison of the input grep -nE 'movzx|strcmp|cmp.*\[rax\]' callmebaby.asm
That points to Validate553575746b @ 0x416802 — the real checker.
The real checker (Validate553575746b @ 0x416802)
- Loads a 13-byte constant from
.rodataat vaddr0x427f44. - Loops
i = 0 .. 0xc(13 iterations), building a local buffer:local[i] = const[i] XOR 0x37. strcmp(input, local_buffer)→Valid(.rodata 0x427f53) if equal, elseInvalid(0x427f59).
The 13 constant bytes at 0x427f44:
06 00 68 06 02 68 04 03 02 7e 7e 7e 4e
Solution
The flag is simply each constant byte XOR 0x37.
python read-only • copy allowed#!/usr/bin/env python3 t = [0x06, 0x00, 0x68, 0x06, 0x02, 0x68, 0x04, 0x03, 0x02, 0x7e, 0x7e, 0x7e, 0x4e] print(''.join(chr(b ^ 0x37) for b in t)) # REDACTED
Verified by running the binary directly:
bash read-only • copy alloweddocker run --rm --platform linux/amd64 -v "$PWD:/w" -w /w ubuntu:22.04 \ ./callmebaby.elf "REDACTED" # => Valid
Both the bare value and the flag{...}-wrapped form were accepted by the server.
Key Takeaways / Lessons
- Mastering byte_deref_search, decoy_function_filtering, strcmp_check_reversal, xor_constant_recovery was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-06-15 • CUSTOM • callmebaby • Difficulty: Easy