Reversing a Keygen Check: CantCrack.exe
A short, satisfying crackme. The name is a dare; the check turns out to be a fixed-format string split into three chunks, each XOR'd against a different key. Here's the walk from "no idea" to a valid key, recovered entirely by hand.
Start with strings
Loaded it in IDA and checked strings first — almost always the fastest way in. The success and failure messages were both sitting right there in the binary, which gives you an anchor: find where the "congratulations" string is used and you're standing next to the logic that decides you won.
Following the cross-reference from that string landed straight in main. Decompiled, it's refreshingly direct:
- copies a hardcoded string
"YYXVRsqswKSP"into a buffer, - reads your input,
- calls a compare function,
- prints win or lose based on the result.
All the interesting logic is in that compare function.
The format check
The comparison routine first validates the shape of the input before it looks at any content:
- input must be 14 characters,
- position 5 must be
-, - position 10 must be
-.
So the key has the form XXXXX-XXXX-XXX. That neatly splits the hardcoded string into three segments, and each is checked against your input after being XOR'd with its own key byte.
Undoing the XOR
Segment 1 (first 5 chars) — take "YYXVR" XOR 0x37:
Y ^ 0x37 = n
Y ^ 0x37 = n
X ^ 0x37 = o
V ^ 0x37 = a
R ^ 0x37 = e -> "nnoae"
Segment 2 (next 4 chars, between the dashes) — "sqsw" XOR 0x41:
s ^ 0x41 = 2
q ^ 0x41 = 0
s ^ 0x41 = 2
w ^ 0x41 = 6 -> "2026"
Segment 3 (last 3 chars) — "KSP" XOR 0x23:
K ^ 0x23 = h
S ^ 0x23 = p
P ^ 0x23 = s -> "hps"
The key
Stitch the three decoded segments back together with the required dashes:
nnoae-2026-hps
Ran the binary with that as input and it printed the success message. Done.
Takeaways
The general shape here is extremely common in crackmes: a fixed transform applied to a known constant, compared against user input. Once you see it's XOR against a constant, the check is symmetric — the same operation that hides the answer reveals it. The only real work is reading the disassembly carefully enough to pull out the three keys and the segment boundaries. Strings → xref → decompile → invert the transform is a workflow that cracks a surprising fraction of these on the first sitting.