Introduction to Reverse Engineering and Radare2

September 11, 2018
Profile Icon

Jason Franscisco

What is Reverse Engineering

Reverse Engineering (RE) is an ad hoc and creative process of extracting the knowledge of design and implementation information from anything we use in reality. Similarly, reversing a software is a practice of analysing the software to examine its internals when we don't have the source code and utilizing the knowledge we make fun from it in a beneficial manner.

Why Reverse Engineering a Software

In today's world, there are many reasons for reversing a software. These days the primary purposes of reversing a binary or software are to develop competing products or cracking the existing commercial software. Reversing is very popular when it comes to crackers that defeat various copy protection mechanisms of the software available. Software Reverse Engineering comes in various forms; a malware analyst needs to perform RE to analyse things like malicious software, a Worm or a Trojan which are wide spread. A cryptanalyst will choose reverse engineering to learn cryptographic algorithms and subsequently attempt different ways to crack the encryption/decryption algorithms. In addition, tech companies, that develop million dollar products, will employ a reverse engineer to audit the software to comply with digital rights management (DRM). In all the above cases, we really don't need the source code of the software. In fact, if we have the source code we don't even need to conduct RE.

What is Radare2

radare2 is an open source reverse engineering framework used for static and dynamic analysis, digital forensics or software exploitation supporting multiple platforms, architectures and binary formats. Radare2 is shipped with a few other important tools for file metadata extraction, base conversion, unified binary diffing and many others. This program, is not only a great disassembler but also a good debugger, especially when you love working on CLI (command-line interface). Mastering radare2 is not simple since one must remember a multitude of commands in order to use it. But again, it has intuitive command-line control to write, as compared to writing code using the IDA bindings. If you are familiar with IDA Pro or Hopper and you are a CTF player then you should try radare2.

At Loginsoft, we believe that radare2 is an essential tool for reverse engineering any software. In this series of articles, we are going to walk you through the basics of software reverse engineering using radare2 by analysing the crackme challenge (crackme0x04) which can be downloaded here.

Installing radare2 on Linux

We can install radare2 either by cloning from Github repository or from the package managers like (apt install, yum install, brew install). We recommend cloning GitHub repo as following


#cloning from Github repository
git clone https://github.com/radare/radare2
#change the current the working directory
cd radare2
# run install.sh
sudo sys/install.sh
.code-container { position: relative; margin-top: 20px;}.copy-btn { position: absolute; right: 8px; top: 20px; /* Adjust as needed to position above the code block */ padding: 6px 12px; cursor: pointer; background-color: #777777; /* Button background color */ color: white; /* Button text color */ border: none; border-radius: 4px; font-size: 12px;}.code-block { font-family: monospace; background-color: rgba(255, 255, 255, 1); padding: 24px; margin-top: 12px; margin-bottom: 12px; border-radius: 8px; overflow-x: auto;}


Radare2 can be installed on Windows platform just by downloading the executable (https://www.radare.org/r/)

Set of utilities comes with radare2

1. rax2 - A base converter utility

rax2 -s 0x61646164 returns 'adad'

2. rabin2 - Binary program info extractor

rabin2 -e $binary: Show the entrypoints

rabin2 -i $binary: Returns information about the binary

3. radiff2 - unified binary diffing utility

radiff2 $original_binary $modified_binary

4. radare2 (r2) - Main binary for reversing the software

r2 -w $binary - Running the binary in writable format

Cracking the Challenge crackme0x04

Once we have the binary downloaded, we need to learn the behaviour by dynamic analysis; run it with different set of inputs in order to do this.

Now, it is very clear that a simple ordinary brute force technique is not going to work to capture the flag. It's time to utilize radare2 libraries to extract the information of the binary 'crackme0x04'. Using rabin2, retrieve information out of a binary like strings, sections, entry points.

This tells us that this program will run on Linux and it was coded in the C programming language. We can also see the bin-type being “elf”. And there are few strings used in the binary. Let’s roll up radare2 (r2), the main binary.

‘r2’ command takes path of the binary as an argument along with few useful switches (‘-w’,’-d’) which will be covered in the next article. Following the syntax ‘r2 ./crackme0x04’ will bring up the binary on neat and intuitive radare2 CLI.

One of the most important commands in radare2 is '?'. It not only lists all the commands available but also works with almost every subcommand. For any binary which we want to dissect, ir can be analysed by the command 'aaa'. In our case, to find the list of functions in the binary and the address of entry point and main function, we use the commands

  • 'afll' - List the available functions
  • 'ie' - Returns the address of the entrypoint
  • 'iM' - Returns the address of the main function

By observing the functions listed above, we can see several functions 'printf', 'scanf', 'main', 'check' being used in the binary. On performing dynamic analysis initially, the function 'sym.check' seems interesting. We can use command 'axt $address' to check where exactly the code was referenced. The function 'check' is called in the 'main' function at the address '0x8048559'. From this we can determine whether or not the validation part exists in the function. Let's dig into the function using the command seek 's'. As previously mentioned, we can view a list of subcommands by using '?' as a suffix to the seek command.

Now the fun part comes with disassembling the function 'check'. Radare2 provides another command to print disassembly code of the function using 'pdf'. 'pdf @ main' will analyse the main function and print its disassembly. Similarly, 'pdf @ sym.check' prints its disassembly of the 'check' function.


[0x080483d0]> pdf @ sym.check
/ (fcn) sym.check 133
| sym.check (int arg_8h);
| ; var int local_dh @ ebp-0xd
| ; var int local_ch @ ebp-0xc
| ; var int local_8h @ ebp-0x8
| ; var int local_4h @ ebp-0x4
| ; arg int arg_8h @ ebp+0x8
| ; var int local_4h_2 @ esp+0x4
| ; var int local_8h_2 @ esp+0x8
| ; CALL XREF from 0x08048559 (sym.main)
| 0x08048484 55 push ebp
| 0x08048485 89e5 mov ebp, esp
| 0x08048487 83ec28 sub esp, 0x28 ; '('
| 0x0804848a c745f8000000. mov dword [local_8h], 0
| 0x08048491 c745f4000000. mov dword [local_ch], 0
| ; JMP XREF from 0x080484f9 (sym.check)
| .-> 0x08048498 8b4508 mov eax, dword [arg_8h] ; [0x8:4]=0
| | 0x0804849b 890424 mov dword [esp], eax ; const char * s
| | 0x0804849e e8e1feffff call sym.imp.strlen ; size_t strlen(const char *s)
| | 0x080484a3 3945f4 cmp dword [local_ch], eax ; [0x13:4]=256
| ,==< 0x080484a6 7353 jae 0x80484fb
| || 0x080484a8 8b45f4 mov eax, dword [local_ch]
| || 0x080484ab 034508 add eax, dword [arg_8h]
| || 0x080484ae 0fb600 movzx eax, byte [eax]
| || 0x080484b1 8845f3 mov byte [local_dh], al
| || 0x080484b4 8d45fc lea eax, dword [local_4h]
| || 0x080484b7 89442408 mov dword [local_8h_2], eax
| || 0x080484bb c74424043886. mov dword [local_4h_2], 0x8048638 ; [0x8048638:4]=0x50006425 ; "%d"
| || 0x080484c3 8d45f3 lea eax, dword [local_dh]
| || 0x080484c6 890424 mov dword [esp], eax ; ...
| || 0x080484c9 e8d6feffff call sym.imp.sscanf ; int sscanf(const char *s,
| || 0x080484ce 8b55fc mov edx, dword [local_4h]
| || 0x080484d1 8d45f8 lea eax, dword [local_8h]
| || 0x080484d4 0110 add dword [eax], edx
| || 0x080484d6 837df80f cmp dword [local_8h], 0xf ; [0xf:4]=0x3000200
| ,===< 0x080484da 7518 jne 0x80484f4 | ||| 0x080484dc c704243b8604. mov dword [esp], str.Password_OK__n ; [0x804863b:4]=0x73736150 ; "Password OK!\n" ; const char * format | ||| 0x080484e3 e8acfeffff call sym.imp.printf ; int printf(const char *format) | ||| 0x080484e8 c70424000000. mov dword [esp], 0 ; int status | ||| 0x080484ef e8c0feffff call sym.imp.exit ; void exit(int status) | `---> 0x080484f4 8d45f4 lea eax, dword [local_ch]
| || 0x080484f7 ff00 inc dword [eax]
| |`=< 0x080484f9 eb9d jmp 0x8048498 | `--> 0x080484fb c70424498604. mov dword [esp], str.Password_Incorrect__n ; [0x8048649:4]=0x73736150 ; "Password Incorrect!\n" ; const char * format
| 0x08048502 e88dfeffff call sym.imp.printf ; int printf(const char *format)
| 0x08048507 c9 leave
\ 0x08048508 c3 ret
[0x080483d0]>
.code-container { position: relative; margin-top: 20px;}.copy-btn { position: absolute; right: 8px; top: 20px; /* Adjust as needed to position above the code block */ padding: 6px 12px; cursor: pointer; background-color: #777777; /* Button background color */ color: white; /* Button text color */ border: none; border-radius: 4px; font-size: 12px;}.code-block { font-family: monospace; background-color: rgba(255, 255, 255, 1); padding: 24px; margin-top: 12px; margin-bottom: 12px; border-radius: 8px; overflow-x: auto;}

In addition to the command ‘pdf’, radare2 has a great feature called Visual Mode which can be seen by running ‘V’ command. To view various modes we can use the command ‘p/P’ as shown below:

Observing the above disassembled code, we can see a comparison happening 'cmp dword [local_8h], 0xf' at the address '0x080484d6' after the call 'sscanf'. We can crack this challenge by analysing the instruction 'cmp dword [ebp-0x8], 0xf' (which compares the sum of input with 15 in decimal); once it matches, it prints the text "Password OK!"

Another way we can do this is by modifying the binary at address '0x080484da' by overwriting with NOP (\x90) to avoid the conditional jump and to print "Password OK!" on any input that user provides. In order to do that, we must run the binary with writable mode (-w) using radare2. Here comes the final solution.

Challenges like 'crackme' will help us learn how to reverse software. We will look at a few other features of radare2 by cracking another challenge in the next article. We hope this guide has given you a better understanding of radare2.

Reference:

Radare2 book: https://www.radare.org/get/radare.pdf
Github: https://github.com/radare/radare2

Credit: ACE Team - Loginsoft

Explore Cybersecurity Platforms

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.

Learn more
white arrow pointing top right

Signup to our Newletter

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

IN-HOUSE EXPERTISE

Latest Articles

Get practical solutions to real-world challenges, straight from experts who conquered them.

View all our articles
The Rise of INTERLOCK Ransomware

November 13, 2024

Fortifying the Cloud: A Guide to Securing Vulnerable Cloud Environments

October 23, 2024

The Emergence of Mallox v1.0

September 25, 2024