IDA Pro Tips to Add to Your Bag of Tricks


Senior Security Researcher

IDA Pro is the most common software for reverse engineering in the industry. It can decompile the five most common architectures (x86/x64/ARM/PowerPC/MIPS), disassemble more than a hundred rare architectures, and debug most of them.

This article is a selection of my favorite tips for IDA Pro. Let’s get to it!

Data Structure Alignment

Compilers usually put structure fields at aligned offsets of 4 or 8 bytes, but this is not the case in some exotic scenarios.

Suppose the source code of the examined software has the following structure:

struct test_s {
    char ch1;
    QWORD qw1;

Usually, a compiler would pad the field ch1 to a length of 8 bytes, which would make the total size of the structure 16 bytes.

Suppose the compiler didn’t do this, and you are faced with a 9-byte structure to disassemble. Such a structure could be perfectly created in the Structures window (Shift+F9), but if you create it in the Local Types window (Shift+F1), the parsed result will be wrong:

The value of qw1 will be mapped to the data after the created padding, but the actual value of qw1 is located in the created padding itself (db 1, 2, 3, …).

To correctly display the structure, you need to fix the alignment by adding the directive #pragma pack(1):

#pragma pack(1)
struct test_s
    char ch1;
    QWORD qw1;

This will result in the correct parsing of this structure:

Full-Text Search

If you’ve ever tried to use Ctrl+F in IDA Pro, you’ve probably noticed that this keyboard shortcut only works in the Imports, Exports, and Strings windows.

For all the other windows, there is the Alt+T combination.

Example of Alt+T usage in the Pseudocode window

Using Alt+T, you can search information in the Disassembler, Pseudocode, and Structures windows.

Rebasing Binaries

When you open a binary file in IDA Pro, and this file is not in the well-known format (e.g. ELF or PE), IDA asks you about the address it needs to load the file. Usually, this address cannot be known before the file is examined.

Let’s load a sample firmware to the 0x0 address:

Example of a firmware loaded to the wrong 0x0 address

After the firmware is loaded, there are three pointers to the uninitialized memory at the 0x04 address: 0x80000145, 0x800002E7, and 0x800002DF. Therefore, you can guess that the initial offset is 0x80000000.

To avoid reloading the firmware, you should call the Rebase Program function using Edit → Segments → Rebase, and shift the firmware to the 0x8000000 address:

Rebase menu

This will correctly display the firmware:

Example of a firmware loaded to the correct 0x80000000 address

Selecting and Exporting Binary Data

There are two hotkeys that can help you export data from IDB files:

Alt+L. Selects a data region of any length
Shift+E. Exports the selected data to different formats

After you press Alt+L, IDA starts selecting data and fixes the initial selection point. This will help you move the destination selection point anywhere you want.

When the needed region is selected, press Shift+E to export the data in a supported format, such as a string, HEX sequence, or C-bytes array. After the data is copied, stop selecting by pressing Alt+L again.

Example of usage of Alt+L and Shift+E combinations to export data

These combinations work in the Disassembler and Hex-View windows.

Revealing String Literals in the Decompiler

Some old compilers, and compilers for real-time operating systems, typically place read-only and read-write data in the same segment. This leads to a situation wherein the decompiler shows variables instead of string literals where the latter are supposed to be.

Example of unreadable pseudocode with variables instead of string literals

The first way to fix this issue is to change the variable type from char * to const char * by the Y hotkey.

Pseudocode after modifying the first argument’s type

The second way is to go to the decompiler settings (Edit → Plugins → Hex-Rays Decompiler → Options); and uncheck the “Print only constant strings literals” checkbox:

Hex-Rays decompiler configuration

As a result, all the data-containing variables are shown as string literals:

Pseudocode after modifying the Hex-Rays decompiler configuration

Little-Endian Code, Big-Endian Data

Some ARM compilers create Little-Endian code but make data in the Big-Endian format.

To display such binaries correctly, go to General Options → Analysis → Processor-Specific Analysis Options → Edit ARM Architecture, and check the “BE-8 code (ARMB)” checkbox:

The ARM architecture options

Breakpoints: Setting Conditionals

IDA Pro supports conditional breakpoints, which consist of a code in IDC/Python that is run in a specific location.

Example of configuring a conditional breakpoint

Note that an IDC/Python code can be run during a debugging to modify the register values and the memory data as well.

Breakpoints: Disabling Stepping Support

When I debug binaries via a GDB server in IDA Pro, I often encounter a bug in which breakpoints stop working after one of the breakpoints has been successfully triggered.

In this case, I go to Debugger → Debugger Options → Set Specific Options, and I uncheck the “Use stepping support” checkbox:

GDB configuration menu

After the stepping support is disabled, the breakpoints start functioning properly.

This configuration isn’t saved to IDB files. To keep it disabled, add the SINGLE_STEP = 0 line to the %IDADIR%\cfg\dbg_gdb.cfg configuration file.

Remote Debugging: IDA Debugging Servers

IDA Pro has its own remote debugging servers for Windows, Linux, Mac, and Android. They could be used instead of ordinary GDB or WinGDB servers.

Content of the directory with the remote debugging servers

These files are located in the %IDADIR%\dbgsrv directory.

Remote Debugging: ASLR

If you attach to a remote GDB server on a system that has ASLR, IDA Pro will not be able to find the location of the examining binary in the memory. As a result, IDA Pro will try to work with addresses pointing to an invalid memory space.

To make IDA Pro use the real binary addresses, rebase the IDB before attaching to the target process.

Garbage Collection in IDAPython

IDA Pro’s built-in Python interpreter constantly runs in the IDA background and never restarts. Therefore, all the variables and objects you create in the code accumulate, and this could lead to memory leaks and unexpected side effects.

For example, let’s create a file with the following code:

import logging

def main():
    logger = logging.getLogger('test1-script')
    formatter = logging.Formatter('[TEST 1] %(name)s - %(message)s')
    ch = logging.StreamHandler()
    logger.debug("Log message!")

if __name__ == "__main__":

After you run this file twice, you will see that two logging handlers start to work simultaneously:

Result of two runs of the script

So, you need to pay close attention to the code to prevent such unwanted behavior.

In the case of the logging class, I recommend you use one of following ways to clear the handlers:

# Python 2/3

# Python 3
from importlib import reload

# Python 2

IDA Pro 7.4+ Tips

Collapsing local variable setting

The local variables could be collapsed by default if you set the COLLAPSE_LVARS parameter to YES in the %IDADIR%\cfg\hexrays.cfg file.

Example of collapsed local variables

This used to be possible through the Numpad+- shortcut or by the Collapse Declarations option in the context menu.

Jumping between matching parentheses/brackets

Matching parentheses/brackets are now highlighted in the pseudocode, and you can quickly jump between them by the % key (Shift+5).

Example of matching parentheses
Copying the pseudocode to the disassembly listing

The / hotkey can copy the pseudocode to the disassembly listing as comments.

Example of the / key result

More Tips and Tricks

If you’re running out of tricks and tips for IDA Pro, check out the following sources. You’ll definitely find what you specifically need.

Share your favorite tricks in the comments on our Twitter!