Upload:
6:03 PM 08/04/2019
Description
Just a simple (or maybe not) KeygenMe which uses one little trick to hide its behaviour from the decompiler. Once you figure out the trick, it should be pretty simple. No antidebug or protection measures. Enjoy the debugging!
Note: For a single login, there are multiple valid passwords (infinite even!). It's sufficient to generate a single one.
arminblack on 2:22 AM 08/23/2019: ez !
ryancor on 5:16 PM 09/01/2019: can someone post a solution to this challenge? something about this doesn't make any f***ing sense.
Flawww on 3:11 PM 09/29/2019: POTENTIAL SPOILERS BELOW :)
I don't know if I'm just really stupid rn but I can't seem to wrap my head around this. I've gotten to this quite easily, but I have no idea how to attack this:
return (password_hash & 0x7FF ^ (v5 + v6 + v7) & 0x7FF) == (username_sum & 0x7FF);
v5, v6, v7 all seem to be uninitialised stack variables with seemingly random values. (Given the same username/password on several runs these differ each time). I don't see any reasonable way to keygen this given that the password hash gets xor'ed with a seemingly random number?
Any hints?
coyote_0x90 on 9:25 AM 10/25/2019: I had to make one patch to be able to get this to work.
Login: coyote11111111
Password: aaaaaaaaaaa220
Logged in successfully.
The seemingly random values mentioned above are not entirely random. One is a pointer and maybe should not be (so I patched it out), one always seems to be 0, and one is a different hash of the login, which yields a negative number. This code successfully finds that different hash:
int getNegativeHash(string input)
{
int hash = 0xFFFFFFFC;
for (int i = 0; i
coyote_0x90 on 9:26 AM 10/25/2019: for (int i = 0; i
coyote_0x90 on 9:27 AM 10/25/2019: The problem comes about with the pointer value included. It is a pointer to the login string itself stored somewhere on the stack. That will be different every time this program executes, so it seems like a keygen would have to scan the process memory for the login string text in order to find this pointer, maybe?
return (hashcode & 0x7FF ^ (v5 + login_ptr + other_negative_hash) & 0x7FF) == (sum_login_chars & 0x7FF);
If I just patch that pointer out of this expression in the executable, I can make a keygen.
It also seems like you have to choose login strings very specifically in order to find ones that can be brute forced. Some login strings just don't seem to have a possible matching password, but I haven't invested enough time brute forcing these to be able to verify this.
fondra on 4:36 AM 10/29/2019: What's the solution gnitargetnisid?
fondra on 3:25 PM 10/29/2019: Like everyone else I can't solve this, those changing esp vars seem completely random, so how could one possibly generate a key? I took a single run, calculated the value produced those three pointers and wrote a brute-forcer. No luck. Perhaps there aren't any "anti-debugging" tricks in this, but there may be something altering these values when being debugged. My last ditch effort is to alter the code to print to console the sum value of the three pointers to see if the sum is static when not being debugged.
cyon on 4:26 PM 04/02/2022: lol just go to strings, and change from JNE to JMP where it does the check. too easy
Endst on 8:18 PM 08/15/2022: For anyone wondering, a keygen is impossible to make for this (unless you patch some code first) because of this line return (local_1c + local_20 + local_24 & 0b0000011111111111U ^
login_password_sum_xor & 0b0000011111111111) == (loginSum & 0b0000011111111111);
if you look around you will find that local_20 is the first four bytes in a pointer to your inputted username, and this will change each time the program is run.
You must me logged to submit a solution