Post

Crackmes & Binary Reversing

Crackmes & Binary Reversing

  While delving into reverse engineering some time ago I encountered the concept of “crackmes”. These are compiled binaries (executable programs) that are designed to be cracked. They are essentially puzzles that are meant for learning reverse engineering and they range vastly in difficulty.

Reversing Tools

  What fascinates me about crackmes is the level of creativity and effort that is put into the advanced ones. The techniques used to make finding the “flag” or solution are very clever. While these files can be found on several sites, by far the one that is the most popular is crackmes.one. Ghidra and IDA tend to be most people’s go-to choices for reversing tools. While these are great tools, my personal favorite is radare2 alongside its GUI named iaito.


The decompiler listing in iaito

  The project has since been forked into rizin due to differences in goals amongst the dev team. Personally I haven’t spent much time using the fork or its GUI (though there don’t seem to be any major differences at the moment). What I like the most about radare2’s GUI is its minimal layout. I still use Ghidra as well as iaito sometimes due to differences in their decompilation output. My favorite feature of iaito is the callgraph. It makes it easier for me to understand the order in which things are executed. It’s pretty much a map of all of the program’s functions and is akin to stepping through a program visually rather than manually (as one does with a debugger such as gdb).



The callgraph listing in iaito

  Reverse engineering is a skill that can be applied for both legitimate and illegitimate means. Like the term “hacking” in general, it has unfairly garnered a negative reputation. One of the best uses of RE that comes to mind is reversing a program in order to create a free and open-source equivalent. This is how some of the GNU coreutils were developed. More recently a lot of people have perhaps associated RE with illicit or illegitimate purposes due to Nintendo suing people who develop emulators. It’s also associated with software cracking in general. Those developers undoubtedly learned to reverse binaries through crackmes and similar means.

Basic Crackme Solution

  In this section I’ll provide a rundown of the overall steps involved in cracking a basic binary. It is helpful to understand the basics of assembly language, at least conceptually, in order to be good at reverse engineering. Below is a list of basic assembly opcodes as well as a brief explanation corresponding to each of them:

The reference above uses the AT&T syntax (meaning that the source operand is on the left and the destination operand is on the right).
The Intel syntax is different, but both are commonplace.


The binary I will be using is called “one”. I downloaded the file a long time ago so I no longer have the direct link from crackmes, but it can be downloaded from here. Below is the SHA-256 signature for the file:
b3b7ff77796617e36036550cd17f03bc96e9d062edc3c1570e81048653d19b3d     one


  What I typically like to do is use ghidra’s decompiler, since its output tends to be more accurate, in tandem with radare’s callgraph. This approach also provides a broad overview of what’s going on. The disassembly is not all that different between the two programs. Ghidra can be configured to display output in AT&T or Intel syntax depending on which you prefer.

Graph of the crackme file inside of iaito Decompiled C code output of the crackme file inside of ghidra

  Already we can see in the decompiled C code above a dead giveaway. Specifically, it’s the following conditional statement:

1
2
3
4
__s = "Serial number is invalid. Please try again.";
if (cVar1 != '\0') {
    __s = "Serial number is valid!";
  }


  This means that the variable __s is a status message. There are other similar hints about what variables and functions do, so I’ve renamed them accordingly in ghidra. For example, keyStr is the user input that gets saved as a string. keyLen is the length of keyStr. check_key is a function that does exactly what one would expect. statusMsg is the status message that the user sees, informing them if the serial number is valid or not.
Decompilation of the main function

This post is licensed under CC BY 4.0 by the author.