In this post, we will explore a wonderful and powerful reverse engineering tool – Radare2, and see how we can patch binaries that we crack. In a previous post by ParanoidNinja, he explained how to patch a binary in Windows x64. You can have a read at that as well at
This post follows a simple program from our previous post for reversing Windows binaries that used XOR encryption, and how we can patch the binary to always work even with wrong password.
Executing the program.
The objective is to crack the binary to print “Correct password“. We know this from the previous post. Moving on…
Let’s make a copy of the executable, and load it into radare2.
$ cp crackMe_xor crackMe_xor_patch
$ r2 -Aw crackMe_xor_patch
The A flag stands for the aaa command in radare2, it will automatically analyze the executable for symbols, length of instruction in bytes, references, function calls, and, renames function names to human readable format. The w flag opens the binary in writable mode, it is required since we will modify the binary and apply the patch to it.
Let us find the string “Correct password”, and work our way to finding a path through which we can reach that print statement. The iz command will display strings in the data section.
The “Correct password” string is at offset 0xe38. Search the binary for references to this offset using /c command followed by the pattern to match, that is the offset in our case.
The string is referenced at address 0x400b08. Let us seek to that position using s <offset> command, and see what function it is, using the pdf command. The pdf command prints a function from the current address location of r2, unless any function name or address is specified with an @ prefix.
We are inside the CheckPass function. Let us switch to graphical view to understand the flow of the function, using VV comand.
Our string is referenced in the add x1, x0, 0xe38 instruction in the instruction block starting from 0x400b04. The last instruction before entry into the block is from a b.eq (branch if equal) instruction which would jump to instruction block from 0x400b34 if value of w0 is equal to 0. And we can see that the adjacent instruction block from 0x400b34 has a reference to offset 0xe50 which is a reference to “Incorrect password”, as we know from the 4th image from above.
Since, our objective is to always print “Correct Password”, we will modify the branch (b.eq) instruction to a NOP instruction. This will ensure control of the program passes through the “Correct Password” block everytime. Let’s quit from graphical view to Visual view, by pressing q once, and then we’ll switch to disas view by pressing p, if we are presented with some other view. The different views available are: hex, disas, debug, words, buffer. etc.
We will move up to the b.eq 0x400b34 instruction, using up arrow key, located at address 0x00400b00. Now that we are in position, we will press A to enter assemble mode. Here we will write our instruction, and hit enter.
Press Y to save changes. This will overwrite our binary. Remember that we had opened our binary in read-write mode. Once saved, press q twice to exit visual mode and r2.
To check the difference between the original binary and the patched binary, we will use radiff2.
$ radiff2 crackMe_xor crackMe_xor_patch
It is evident that the only difference between the two binaries is the change we made from a b.eq instruction to a nop instruction. Now we will run our patched binary.
Voila! We have successfully patched our binary to print “Correct Password” with any 10 characters. With this, you can get an idea of how to go about performing more complex patching and cracking tasks. Let’s wrap up this post here, and we’ll continue to dive into other topics in the upcoming posts.