ApriorIT

Reversing is complex. Yet software developers often turn to reverse engineering when faced with a challenging task: enhancing software security, making software compatible with third-party components, maintaining legacy code, and so on.

At Apriorit, we have more than a decade of reverse engineering experience. Over the years, our researchers have collected a rich selection of efficient tools for reverse engineering.

In this article, we describe the main tools our software reversers rely on in their work and show practical examples of how to use them. This article will be useful for readers who are familiar with assembly language and network interaction principles and who have experience programming for Windows using API functions.

Contents:

Applications for software reverse engineering

Practical example of working with reversing tools

Conclusion

There are so many different software applications where the source code is hidden from sight. But there are a number of situations when we do need to understand the logic of how a certain platform or application functions, its algorithms, and specifics. That’s when legal software reversing — a service provided by Apriorit for more than a decade — is needed.

Related services

Professional Reverse Engineering[a]

The efficiency of the reversing process depends heavily on two factors:

  1. The expertise of the reverse engineer
  2. The set of tools and techniques used

To learn more about the skills you might need and the specifics of Windows software reversing, check out our previous article describing the reversing process step by step. In this post, we discuss some of the best Windows reverse engineering tools. 

In the second half of the article, you’ll find a brief example of how to use each of these tools in practice.

Applications for software reverse engineering

It’s hard to name the best software reverse engineering program – there are quite a few of them, and each resolves a specific task in the multistep reversing process. Below, we overview the nine main tools used for reverse engineering by Apriorit researchers:

  1. IDA Pro, Hex Rays
  2. CFF Explorer
  3. API Monitor
  4. WinHex
  5. Hiew
  6. Fiddler
  7. Scylla
  8. Relocation Section Editor
  9. PEiD

Let’s get started.

1. IDA Pro, Hex Rays

IDA Pro is one of the best and most popular reverse engineering software tools. It’s an interactive disassembler that has a built-in command language (IDC) and supports a number of executable formats for various processors and operating systems. IDA Pro also has a great number of plugins that can extend the disassembler’s functionality even further.

The main advantage of IDA Pro is that it allows you to interactively change any element of the displayed data:

best reverse engineering tools

Screenshot 1. IDA Pro interface

Aside from the disassembler itself, let’s also look closer at some IDA plugins.

Hex-Rays Decompiler

This plugin can turn native processor code into a more readable, C-like version. The Hex-Rays Decompiler produces rather accurate C code comparable to that produced by a human reverse engineer. It correctly decompiles code produced by various C++ compilers, no matter the architecture. However, Hex-Rays Decompiler might have issues with processing complex assembler code, where the original code was specifically modified by adding the inline assembler or some manual optimization was made. 

Lighthouse

This plugin enables you to mark the execution path within the disassembler. As a result, you can understand which pieces of code are taking part in the execution and if they are involved in some algorithm or feature.

Basically, this plugin loads reports of code coverage tools into the IDA database and marks pieces of code depending on how many times they were executed. This makes it clear which part of the code is worth your attention while browsing the disassembly.

ClassInformer

This plugin is intended to be used on binaries built by Visual Studio and searches for RTTI information stored in the data section of the executable file. RTTI information allows the plugin to find the class names and virtual methods of C++ classes and name them for the user. Also, ClassInformer can present you with a list of found classes.

BinDiff by zynamix

This tool uses the IDA engine to compare binaries as assembler code instead of a stream of bytes. BinDiff can pinpoint differences in the code of two versions of the same program (down to changes in a specific function) as a list of instructions which were added, removed, or replaced. Changes can also be represented as code flow graphs.

IDA-Function-Tagger

This plugin analyzes imported functions and functions that call them and then groups them by tags: cryptography-related, registry-related, network-related, etc. Such grouping makes it easier to find the part of the code responsible for specific operations.

ida-x86emu

This plugin emulates the execution of disassembled code without the need to run the application under analysis in a debugger. Using this plugin, you can emulate the result of executing any piece of code without the risk of modifying something in the system. All you need to do is specify the start values of CPU registers. Then you can do a step-by-step execution.

Read also:
How to Reverse Engineer an iOS App and macOS Software

2. CFF Explorer

CFF Explorer is a suite of tools for portable executable (PE) editing which includes:

best reverse engineering tools

Screenshot 2. CFF Explorer interface

3. API Monitor

API Monitor is an application for intercepting API function calls made by apps and services. This tool can also display input and output data. 

By default, API Monitor contains definitions for over 13,000 API functions and more than 1,300 COM interface methods.

best reverse engineering tools

Screenshot 3. API Monitor’s API Capture Filter interface

4. WinHex

WinHex is a hex editor that provides a rich set of features and development tools for Windows. 

WinHex can display checksums or code of software files, which is something a regular text editor is unable to do.

best reverse engineering tools

Screenshot 4. WinHex interface

5. Hiew

Hiew is a binary file editor focused on working with code. It has a built-in disassembler for x86, x86-64, and ARM as well as an assembler for x86 and x86-64.

The main features of Hiew include:

best reverse engineering tools

Screenshot 5. Hiew interface

6. Fiddler

Fiddler is a proxy that you can use to intercept HTTP/HTTPS traffic going between your application and the server, monitor it, and analyze it. Fiddler can intercept HTTP/HTTPS traffic system-wide. You can also add plugins (e.g. wbxml view, which can decode wbxml) and display requests/responses in different views.

best reverse engineering tools

Screenshot 6. Fiddler interface

Fiddler has a built-in hex editor and can generate requests based on a selected request or create a custom request. In addition, the Request to Code plugin allows you to get ready code that executes requests in C#, Visual Basic, or Python.

Read also:
Using Web Debugging Proxies for Application Testing

7. Scylla

Scylla is an application for dumping a running application process and restoring the PE import table. With its help, you can get a totally restored PE file that can be run by the operating system.

best reverse engineering tools

Screenshot 7. Scylla interface. Image credit: Stack Exchange

8. Relocation Section Editor

Relocation Section Editor is an application used for editing the relocation table in PE files. The main purpose of this tool is to modify the relocation table in case of patching relocatable pieces of code. But it’s often used to remove the relocation table altogether when restoring a protected file.

A protected file actually contains the relocation table for the unpacker code only. The relocation table for the real code is usually hidden within the unpacker data. Thus, in case a dump is being recovered, there are two ways to restore the missing relocation table for the real code: 

  1. Force the application to be loaded at two different base addresses, then compare the dumps to see which parts of the code are being patched and make a new relocation table.
  2. Remove the relocation table completely and specify in the PE file header that the file is not relocatable.
best reverse engineering tools

Screenshot 8. Relocation Section Editor interface

9. PEiD

PEiD is one of the best reverse engineering tools to detect the packer. By analyzing entropy, PEiD can detect whether an application is packed.

There are also various useful plugins that help to analyze PE files. For instance, the KANAL (Krypto Analyzer for PEiD) plugin analyzes a PE file for the presence of known encryption algorithms.

best reverse engineering tools

Screenshot 9. PEiD interface

These are the nine tools that reverse engineers at Apriorit often turn to when working on Windows reversing projects. As you can see, each of these pieces of software for reverse engineering solves a very unique, specific set of tasks. In the next section, we provide practical examples that display the role and importance of each of these tools in Windows reversing.

Practical example of working with reversing tools

Let’s see how we can use each of these tools to research a Windows application. As an example, we are going to use a test application that you can download and analyze on your own.

1. Opening the researched executable with IDA Pro

Let’s load our test application to IDA Pro. We receive the following message:

best reverse engineering tools

Screenshot 10. Error message displayed by IDA Pro

This means that something has gone wrong with the application: its import table can’t be found. At this point, we only need to press the OK button. Once we do that, IDA Pro provides us with the following results of application analysis:

best reverse engineering tools

Screenshot 11. Application analysis results in IDA Pro 

best reverse engineering tools

Screenshot 12. Test application's import table 

As you can see, the import table is almost empty. Its upper part shows that it was possible to detect a small piece of code (the blue part), and the left part shows which functions were detected (in our case, very few). 

There is also a set of undetected bytes above the start function. We suppose that the application is packed by means of some packer. PEiD will help us determine which packer was used.

Read also:
Anti Debugging Protection Techniques with Examples

2. Getting information about the packer with PEiD

Now, we need to load our application in PEiD.

best reverse engineering tools

Screenshot 13. Application info displayed in PEiD

In Screenshot 13 above, you can see that the Entry Point is located in the UPX1 section. However, this fact alone doesn’t really tell us much, so we need to run a scan. 

To start the scanning process, go to Options, choose Hardcore Scan, and click Save:

best reverse engineering tools

Screenshot 14. Configuring the scanning process in PEiD

Next, select the folder where the application is located. After scanning is complete, we receive the following result:

best reverse engineering tools

Screenshot 15. The result of application scanning with PEiD

As you can see from Screenshot 15, the application is packed using the UPX tool. To unpack it, we are going to use CFF Explorer.

3. Unpacking the application with CFF Explorer

To unpack our sample application with CFF Explorer, we need to go to the UPX Utility page in the main menu of CFF Explorer and press the Unpack button:

best reverse engineering tools

Screenshot 16. Unpacking the application in CFF Explorer

After that, we can upload the already unpacked application to IDA Pro and restore the assembler code.

We upload our application to IDA Pro once more, and when the system asks us whether to upload symbols from the server, we agree. Here is the result of application analysis in IDA Pro:

best reverse engineering tools

Screenshot 17. IDA Pro analysis results for the unpacked application 

best reverse engineering tools

Screenshot 18. The import table of the unpacked application

You can see in Screenshot 17 that we now have some readable code, more detected functions, and an import table (Screenshot 18). At this point, we can run the application and debug it in IDA Pro. In the disassembler, select Debugger > Select Debugger > Local Win32 debugger and then press F9. After that, we receive the following warning message:

best reverse engineering tools

Screenshot 19. Debugger detection message

Our tested application detected that it was debugged. To continue with our analysis, we need to disable debugger detection first.

See the import table:

best reverse engineering tools

Screenshot 20. The NtQueryInformationProcess function

At once, we can notice the NtQueryInformationProcess function. After clicking on it, we get the following list of xref functions:

best reverse engineering tools

Screenshot 21. xref functions of the NtQueryInformationProcess function

Clicking on the function, we can see where it’s called. The third parameter is an output parameter. If it equals 1, then a debugger is attached to the application; if it equals 0, there’s no debugger attached to the app.

Let’s see where the result of this function is written:

best reverse engineering tools

Screenshot 22. Analysis of the NtQueryInformationProcess function

As you can see in Screenshot 22, the third parameter contains the address of the local variable (var_8). After a function call, the result of the function is checked (test eax, eax). Then the value of var_8 is checked, and if it’s not 0, the value is written to the byte_131443C variable.

Let’s check if the byte_131443C variable is used somewhere else in this function:

best reverse engineering tools

Screenshot 23. Checking where else the byte_131443C variable is used

We’ll start from the end. This value contains the result from al (lower bytes). Before that, the esi result is written to eax, and 1 is written to esi. Above, we see the condition for writing 1 to esi: if ecx + 2 does not equal 0. The value in ecx is large fs:30h (and then + 2). It verifies that a debugger’s presence has bypassed the IsDebuggerPresent function (a field of undocumented PEB structure). 

Let’s rename this variable. To do so, press N or right-click on the function and select Rename

Now we need to check if the g_isDebbugerPresent variable is used anywhere else:

best reverse engineering tools

Screenshot 24. Details of the g_isDebbugerPresent variable

There is “…” in the end, so this variable is used in more than one place. Place the cursor over it and click X, or right-click and select Jump to xref to operand:

best reverse engineering tools

Screenshot 25. Places where the g_isDebbugerPresent variable is used 

We already know the first four places where this variable is used, but not the last one. Let’s find it:

best reverse engineering tools

Screenshot 26. Details of IsDebuggerPresent function’s use

In Screenshot 26, we see that the variable checks if esi equals 0, and if it doesn’t, we receive the message that there is a debugger.

Gladly, this verification can be removed. We’ll consider one way to do that a bit later, when we get to working with the Hiew tool.

It’s noteworthy that IDA Pro also allows for patching memory and code. In order to quickly find the needed piece of code, we’ll run the Rebase program in IDA Pro to get the same offset as in Hiew. In IDA Pro, select Edit > Segments > Rebase program and enter the value 0x400000 in the opened window:

best reverse engineering tools

Screenshot 27. The Rebase program in IDA Pro

Let’s get the address of the code that performs the comparison. As you can see from Screenshot 28 below, the address is 0х401329:

best reverse engineering tools

Screenshot 28. Code that compares the g_isDebbugerPresent variable’s values

We need to write down this address, as we are going to use it later in Hiew.

4. Modifying the executed statements in Hiew

Now we need to load our application in Hiew. First, it looks as follows:

best reverse engineering tools

Screenshot 29. View of the test application in Hiew

We can switch to the Decode mode by pressing F4 > Decode. Now we have to find the address we received in IDA Pro — 0х401329. Press F5 and set the address this way:

best reverse engineering tools

Screenshot 30. Setting the code address in Hiew 

At this point, we get code that compares the values of our g_isDebbugerPresent variable:

best reverse engineering tools

Screenshot 31. Code for comparing the g_isDebbugerPresent variable

Now we can replace this code with, say, jmp to a specific address so that this condition will never be satisfied (in real applications, it can be an exception to immediately close the application).

Press F3 and then F2 to switch to the Edit mode. Enter the address of the next command after if. Add “.” in the beginning of the address so it will be relative:

best reverse engineering tools

Screenshot 32. Changing the code for the g_isDebbugerPresent variable 

After editing, our modified command is highlighted in yellow. Press F9 to update and save the application.

If we try to run our test application now, it crashes.

When looking at the assembler code, we see that the new jmp will result in calling esi further down the code, and esi will contain garbage instead of the MessageBox function address. Since we’re jumping over the address 401330, we’re skipping mov esi, ds: MessageBox. Thus esi will not be initialized, and the application will crash at 401366.

best reverse engineering tools

Screenshot 33. The part of the code where the application crashes 

Therefore, let’s swap jmp and the mov instruction, which puts the MessageBox address to esi. Now, we should set the relative address in jmp to 14, but no longer to 1E, because the command has become closer to the command we are going to.

best reverse engineering tools

Screenshot 34. Setting the relative address in jmp 

Now, to make jmp, we need to save the MessageBox address to esi.

Let’s run IDA Pro again and go to the g_isDebbugerPresent variable’s address:

best reverse engineering tools

Screenshot 35. The g_isDebbugerPresent variable’s address in IDA Pro

In Screenshot 35, you can see that there is an unconditional jump. If we run the application via the debugger, the application will crash because the previous command contains an absolute address, and after the application starts, the loader passes the relocation table and adds delta to each value to make all addresses valid. What we need to do now is remove this value from the relocation table.

Let’s load the original file to IDA Pro, find cmp (which was deleted earlier), and enable the option of showing commands in byte representation in IDA. To do this, select Option > General:

best reverse engineering tools

Screenshot 36. Configuring IDA Pro to show commands in byte representation

This is what we get:

best reverse engineering tools

Screenshot 37. cmp data IDA Pro

cmp is a double-byte command starting with 1329, and the address starts with 132B. We can see that jmp is a one-byte command and that its address is relative (meaning that it shouldn’t be in the relocation table):

best reverse engineering tools

Screenshot 38. jmp data in IDA Pro

Thus, we have to remove the 132A value from the relocation table. To do so, we need to open the current version of our test application with Relocation Section Editor.

5. Deleting a value from the relocation table with Relocation Section Editor

We start by loading the test application and finding the target value: 0x0040132A.

best reverse engineering tools

Screenshot 39. Application values displayed in Relocation Section Editor

Next, we remove the target value and save the test application.

If we run the application now, it still crashes, so we need to go back to IDA Pro. 

After removing 132A from the relocation table and swapping jmp/mov, the application will also crash because we haven’t edited the value that was previously pointing to mov and now should point to jmp. CFF Explorer can help us fix this issue.

6. Modifying values in the relocation table with CFF Explorer

Now it’s time to open our test application in CFF Explorer. We have found the value — 1332 — on which delta for MessageBox used to be added.

best reverse engineering tools

Screenshot 40. The value for adding MessageBox delta 

Let’s replace the value 1332 with the value 132B, the new offset by which MessageBox can be found. If we run the test application now, it won’t crash or show a warning message about a detected debugger.

Next, we move to working with the MessageBox function calls.

7. API Monitor

This program is used to monitor API calls and contains a number of known API functions it can monitor. You can also add your own functions to API Monitor and use this tool to monitor network function calls and research passed parameters (of course, if traffic is not encrypted).

Let’s monitor our application. We’ll try to find the call for the MessageBox function:

best reverse engineering tools

Screenshot 41. MessageBox function calls

We’re interested only in the API functions that can show a message window. So we select only them in User32.dll.

In API Monitor, select File > Monitor New Process and set the path to our file. After running our process, we see the list of called functions. Let’s try to find MessageBox:

best reverse engineering tools

Screenshot 42. The MessageBox function in API Monitor analysis results

API Monitor shows which parameters were passed to the MessageBox function. Also, we can set different breakpoints for a function:

best reverse engineering tools

Screenshot 43. Function breakpoint options in API Monitor

If we run monitoring of our file, we’ll get the following results:

best reverse engineering tools

Screenshot 44. Results of application monitoring in API Monitor

Screenshot 44 also shows the parameters passed to the MessageBox function.

Read also:
Reverse Engineer Software

8. WinHex

Now, we move to working with binaries so we can find the code that we previously detected with IDA Pro and API Monitor. But before exploring a binary, we need to determine its type with a hex editor. In our example, we use WinHex.

Open the file with WinHex:

best reverse engineering tools

Screenshot 45. Application data in WinHex

The MZ signature at the zero offset corresponds to PE format files (executables or shared libraries), so this is an exe file or dll.

Most file formats have unique signatures. For example, here’s what a dump file looks like in WinHex:

best reverse engineering tools

Screenshot 46. Example of a dump file processed by WinHex

9. Scylla

To show you how to work with Scylla, we are going to once again use a packed application, but we won’t be unpacking it this time. Instead, we'll dump its memory and try to run it.

To do that, we open the packed executable file in IDA Pro. This time, we need to find the original entry point (OEP) into the application rather than the entry point of the packer.

best reverse engineering tools

Screenshot 47. Searching for the application’s original entry point with IDA Pro 

The pusha command saves general-purpose registers to the stack. In the end, there should be the popa command which pushes the stored register values. After the popa command, there is a jmp to the original point of entry. You can use the Search for text option by pressing Alt + T and look for the popa command.

best reverse engineering tools

Screenshot 48. The popa command

Below the popa command, there is jmp 40A191, which will eventually move to the original entry point.

Let’s put a breakpoint in jmp and run the debugger.

Now, we can try to follow jmp. However, IDA Pro displays another warning message:

best reverse engineering tools

Screenshot 49. No code warning message in IDA Pro

This message means that there is no code at the point we’re going to. Therefore, IDA will create instructions in disassembled listings on the basis of bytes pointed to by the Extended Instruction Pointer (EIP).

best reverse engineering tools

Screenshot 50. The address of the application’s original entry point 

0x00971A91 is the address of the original entry point after unpacking the application into memory.

Now, without closing IDA Pro, open Scylla in order to create the application’s dump and restore the application’s import table from it.

In the process list, choose our application and put the OEP address into the field. Then choose first IAT Autosearch and then Get imports. As a result, Scylla will show that the import table has been found.

best reverse engineering tools

Screenshot 51. Processing a test application with Scylla

Let’s make an application dump: press Dump, save the dump, then click Fix Dump and select the previously saved application.

If we run our application now, it will crash, so we need to remove the relocation table. To do so, open the modified dump file (it has the _SCY prefix) in CFF Explorer.

best reverse engineering tools

Screenshot 52. Working with the modified application dump file in CFF Explorer

Set 0 in the Relocation Directory RVA field.

Next, we need to check whether the ImageBase is the same that the application loaded into memory. 

best reverse engineering tools

Screenshot 53. Application’s ImageBase data in CFF Explorer 

You can find the ImageBase value in IDA Pro by going to Edit > Segments > Rebase program.

best reverse engineering tools

Screenshot 54. Configuring IDA Pro for ImageBase analysis

Let’s save and run the test application. Now, it will run as if it were packed.

Related services

Engineering for Cybersecurity Projects

Conclusion

When applied properly, reverse engineering can help you strengthen the security and improve the performance of your solution. However, quality reverse engineering is impossible without using the right set of tools and techniques.

In this article, we covered some of the best reverse engineering software that our team of professional reversers uses when researching software. Most of these tools can only be used for solving specific tasks, but when combined, they provide you with all the capabilities necessary for extensive software analysis.

Want to see if reverse engineering is the right approach for your next project? Get in touch with us using the form below.

Tell us about your project
Send us a request for proposal! We’ll get back to you with details and estimations.

Browse
By clicking Send you give consent to processing your data

Book an Exploratory Call

Do not have any specific task for us in mind but our skills seem interesting?

Get a quick Apriorit intro to better understand our team capabilities.

Contact Us

  • +1 202-780-9339
  • [email protected]
  • 3524 Silverside Road Suite 35B Wilmington, DE 19810-4929 United States
  • D-U-N-S number: 117063762