When we check the available functions, we’re able to notice that the names have changed again, as they are similar to the native functions.
Another detail is that there are no strings visible in the code. Although, we can see there are strings in this little program if we list them all.
So, how are they being printed???
If the code wasn’t the same as Crackme0x08, this little trick could have been more difficult to spot. We can only identify strings being printed because of the call to the printf function (the native one). Before of those calls, we always see an address being loaded to EAX register, and then passed to the printf function throughout the stack. Also, we always see a numeric value being subtracted to EBX register, which means that EBX is used as a base pointer.
At the beginning of every function we see a call to fcn.08048766 function, which changes the value of EBX. So after that call, EBX will have the base value from where will be calculated all the addresses that contains our strings.
Let me now guide you step by step so you can understand where the strings are located. Let’s start with sub.strlen_616 function.
This function corresponds to sym.check, from the previous exercise.
Here we see two printf calls and the base value of EBX, after the changes at the beginning of this function occur, is 0x08049ff4.
0x08049ff4 – 0x17a2 = 0x08048852
If we check what’s in that address, using pf command, we get the following output.
As you should remember, %d is a format that will be passed to the sscanf native function. Let’s see the next string.
0x08049ff4 – 0x1791 = 0x08048863 => wtf?
This function corresponds to sym.che, from the previous exercise.
0x08049ff4 – 0x17b7 = 0x0804883d => Password Incorrect!
This function corresponds to sym.parell, from the previous exercise.
The first string is already translated. It’s the %d.
0x08049ff4 – 0x179f = 0x08048855 => Password OK!
This function corresponds to sym.dummy, from the previous exercise.
0x08049ff4 – 0x17bc = 0x08048838 => LOLO
To finish this translation, let’s also do this for the strings in the main function.
0x08049ff4 – 0x178b = 0x08048869 => IOLI Crackme Level 0x09
0x08049ff4 – 0x1772 = 0x08048882 => Password:
0x08049ff4 – 0x1767 = 0x0804888d => %s
You can confirm all the addresses in the second image of this post, the one that corresponds to iz command.
And again, the solution for crackme0x09 is this set of conditions:
- We must sum the digits of the number provided, from the left to right, until we get 0x10
- We must set the environment variable LOL
- The number must be even
- The number must be less or equal than 2,147,299,998
Modifying Crackme0x09 to accept any password
Once more, I’m going to be super lazy and make the program jump right to the “Password OK!” after receiving the input. Let’s do it.
That address right after the unconditional jump is the first instruction to print the “Password OK!”.
Time to see if that worked.