crackmes.one

Writeup for Entry Level Keygen-Me 0.01a

Author: EvESpirit
Date: 2025-05-31 01:30
Summary: Lovely challenge! Straightforward main, which called the function sub_4011A0(_DWORD *this, char *Str) - a regex validator. Strict format checking as expected, if it's not "NNNNN-TOM-NNNNNNN-NNNNN", we're going nowhere. If it's valid, we go to sub_401220. sub_401220 is our validator. First check takes the first 5-digit part of your serial, and checks divisibility by 7. Second check creates a small 3-character string made from the last digit of the first checkee from earlier, the 6th character of our input which automatically means it has to be a dash due to the validator regex, and the 7th character of our input which automatically means it has to be T for the same reason. After this, we get this check: if (sub_401C40(temp_str, "000")) { /* fail */ } else { /* success */ } sub_401C40(temp_str, "000") is called, and if it doesen't return a 0, we fail. Perfect opportunity for binary patching? Yes, but we soldier on. sub_401C40 was a bitch. sub_401C40(char* 3_char_string, char* literal_000) just calls sub_40D5C0(literal_000). 3_char_string seems to be ignored as the this pointer for sub_40D5C0 which is __thiscall. Instead, literal_000 becomes this, and 3_char_string is passed as the first actual argument on the stack. Then we calculate len(3_char_string). This, obviously, always comes out as 3. Then we try to get some out-of-bounds garbage. Suprisingly enough, consistent garbage. The subsequent std::_Traits_equal is probably just a string comp, possibly for char16_t - but most importantly, it compares to our 3_char_string. It seems that std::_Traits_equal in this specific context, with the OOB read and potential type confusion, effectively considers 3_char_string "not equal" to its internal representation of "000" only when the first character of 3_char_string is '0'. TL;DR: Your serial must be NNNNN-TOM-NNNNNNN-NNNNN. The first 5-digit part (NNNNN) must be divisible by 7. The last digit of that first 5-digit part must be '0'. The other two numeric parts can be anything. From this point, it's extremely easy to write a script to give you a bunch of keys. They all return the same flag - WPVUF@PMFMVMLUCD.

Loading writeup...