For the Crackme0x02, I’ll follow two approaches. First, I’m going to find out the password through analysis. Then, I’ll modify the program in order to accept any password.
If you’re not acquainted with any of the commands used in this post, you can always take a look at Radare Basics.
Let’s start and first of all, we need to run the program.
Like the previous exercise, this one is a password challenge.
Getting the Crackme0x02 password through analysis
To start debugging this program we need to start Radare with the flags A and d. Then, we can check the strings present in data section.
None of this strings seems to be useful, so if we check the functions present in this binary we can see the main function that we can seek to. Let’s print the main.
Similarly to the previous exercise, the string printed is determine by a compare intruction. Between the scanf instruction and this compare instruction we can see some operations taking place, including one sum and one multiplication. Now, it’s time to dissect that part of the code using breakpoints.
We can see the local variable local_8h holding 0x5a value and local_ch holding 0x1ec, but let’s use afvd to confirm. For that, we need to set a breakpoint right after this last instruction, at 0x08048439 address.
After set a breakpoint we can see it in front of that address, using pdf. Then, use dc to run the program until it hits the breakpoint.
Yes, local_8h and local_ch hold those values.
The next instruction puts the value of local_ch in the edx register. Notice that this doesn’t happen for local_8h. Instead, eax loads the address of this variable using lea operator which means that eax will “point” to local_8h memory address.
Solution
From this point forward, the operations to calculate the solution are taking place.
The next instruction adds the value of edx to the value of the memory cell to where eax points to, and stores it in that same address. The value of local_ch (0x1ec) was added to local_8h (0x5a) and stored in local_8h.
Let’s check the contents of all variables again.
So far, so good. Next, the value stored in local_8h is moved to eax register. At this point, both local_8h and register eax holds the value 0x246, so the next imul instruction will raise this value to the power 2. eax register should now have the value 0x52b24. Let’s confirm using dr command.
There it is! The next two instructions will prepare the registers and variables for the cmp instruction. So, local_ch now have the solution to this challenge and eax holds the value inserted by the user (which was stored in local_4h).
We now know that the solution for this crackme must be 0x52b24 (or 338724 in decimal). Let’s check.
We’ve got it right!
Getting the Crackme0x02 password through program modification
Time for the hard part. Before I continue, let me just state that I could manipulate the code in many ways and obtain an identical result. For instance, I could replace the compare instruction by cmp eax, eax for example or I could edit the opcode before the compare instruction and save some value in eax register.
Instead, I going to overwrite the jump instruction right after the compare instruction and replace it with a nop by changing the opcodes.
For more information about the opcodes, I advise you to take a look in this website and this one.
Now, if we going to modify the program we need to open it in write mode (with the w flag). Don’t forget A flag as well. After that, you still need seek to the main function.
So, the target operation is at 0x08048451 address. To replace it let’s use wx command. By the way, the 90 that you see in the image below is the opcode for the nop operation
If the second operation is difficult to understand, check the walkthrough video at the end of this post.
The next image is just a portion of pdf command. It’s possible to see that the jump operation has been replaced.
Just to be crystal clear, it doesn’t matter the value of eax nor local_ch because no action will take place after the compare instruction.
Finally, let’s run crackme0x02 and check if we’re good.
Mission Accomplished