Entry Level Keygen-Me 0.01a |
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. |