Again there is a sym.check function called inside main. pdf @ sym.check:
0x0804851a 837df810 cmp dword [var_8h], 0x10
Spot the comparison. 0x10 is int 16. Similar to the last crackme (0x04), let’s try 88 as the password (8+8=16):
./crackme0x05
IOLI Crackme Level 0x05
Password: 88
Password OK!
However, trying the other possibilities: 97, 79, 907 does not seem to work, but 970 works:
./crackme0x05
IOLI Crackme Level 0x05
Password: 97
Password Incorrect!
./crackme0x05
IOLI Crackme Level 0x05
Password: 970
Password OK!
I want to continue looking at the function to see why it’s causing this.
At 0x08048526, sym.check calls sym.parell. Inside sym.parell:
and eax, 1 gets the first bit of eax (the least significant bit);
test eax, eax is the same as and eax, eax (bitwise and) except that it doesn't store the result in eax. So eax isn't affected by the test, but the zero-flag is. The jne branch will be taken if not equal (zero-flag=0) --> i.e. when ZF=1 --> and ZF=1 if eax contains 1. Conversely if eax contains zero, ZF=0, the jump via jne will not happen.
Therefore, in the sym.parell function, the program reads the user input as a whole integer. As long as the input number is even number, it will output “correct password”.
0x0804851e 750b jne 0x804852b (sym.check
0x080484ea 7346 jae 0x8048532 (sym.check
0x080484ac 7518 jne 0x80484c6 (sym.parell
I try to change the instruction at 0x080484ac to a nop so it will not jump and print str.Password_OK, but failed. Turns out we need to edit all of the above three addresses to a nop in order to make the program accept any password: wx 9090 @ address
./crackme0x05
IOLI Crackme Level 0x05
Password: ok
Password OK!