Hex-Rays' blog

Igor’s Tip of the Week #167: Adding and splitting segments – Hex Rays

Written by Igor Skochinsky | Dec 1, 2023

When analyzing firmware binaries, a proper memory layout is quite important. When loading a raw binary, IDA usually creates a code segment for the whole binary. This is good enough when that code is all you need to analyze, but it is not always the case. For example, the code can refer to external hardware as MMIO (memory-mapped I/O), or use extra memory which is not part of the binary image. How to handle such situations?

Creating segments

To make extra addresses present in the database, use Edit > Segments > Create segment… action.

Enter the segment name, start/end addresses and optional class. The class is usually just informative but may affect decompiler’s behavior. The “Use sparse storage option” is useful for segments which are mostly empty and have relatively few data items (e.g. BSS or MMIO). When enabled, IDA will use storage optimized for such use case so the IDB won’t grow much even if the new segment is very large.

NB: the end address of the segment is exclusive, i.e. last byte of the segment will have address end_ea-1.

Once the segment is created, it may be a good idea to reanalyze the database so that reference to the newly available addresses are discovered.

Splitting segments

If you specify an address range which partially intersects with an existing segment, IDA will automatically truncate it to make room for the new one. For example, assume you have a firmware loaded as ROM segment from 0 to 0x80000 but then discover that the code area seems to end at 0x60000. To to split off the last part as read-only data, create a new segment (e.g. named .rodata) with boundaries 0x60000 to 0x80000 and the ROM segment will be automatically truncated to end at 0x60000.

Moving the segment boundary

Let’s say that after analyzing the binary further, you realize that .rodata should actually start at 0x70000. You can move the split point quickly using the following steps:

  1. navigate to the new split point (e.g. 0x70000);
  2. Invoke Edit > Segments > Edit segment (or use shortcut Alt–S);
  3. In the Start address (or End address, depending on the direction of the move), enter here.
  4. Make sure “Move adjacent segments” is enabled and click OK.

Because most numerical input fields in IDA accept IDC expressions, here will be converted to the current address(0x70000), so .rodata segment boundaries will be adjusted to 0x70000-0x80000, and the adjacent ROM segment extended to 0-0x70000.

See also:

Igor’s tip of the week #41: Binary file loader

IDA Help: Create a new segment

IDA Help: Change segment attributes