3

I'm browsing an old 80186 BIOS ROM in IDA free. I have loaded the binary file at the correct address and created one big segment for the entire thing since I knew nothing about the internal structure.

Now, as I have been digging around, disassembling, commenting etc, I have identified some things that I'd like to create new segments for, e.g. interrupt vector seg:offset, far jmps, jump tables that are offsets into different CS values, etc.

  1. Is this how you are supposed to use IDA segments? I.e. avoid having to hand-calculate linear addresses from jump table offsets by making a new segment with the (known) CS value at the time the table is used.

  2. How do I create a new segment without losing the data entered (disassembly, arrays, comments...) in the one all-encompassing segment I already have? It seems that to make room for a new segment, I need to delete or move the one that's already there, but when I do, all work done in that area (of linear addresses) is lost.

Edit: This is the ROM. It's loaded at 0xf0000-0x100000, entry point is f000:fff0 (reset vector) https://www.dropbox.com/s/63oxq39w0v3rdo9/RYSA094_joined.bin?dl=0

1

IDA's UI deletes segment items because usually the code needs to be recreated if the segment base changes. If you cheat and don't change the segment base immediately, items won't be destroyed. I.e. try this:

  1. create new segment specifying the same base as the existing segment. IDA usually fills in the current segment base if you use selection before invoking the "Create Segment" menu item.

  2. change the segment base behind IDA's back using IDC or IDAPython:

    set_segm_attr(here, SEGATTR_SEL, newbase)

Some xrefs, especially those based on current segment/CS may need to be recreated.

  • Thanks, that did the trick. To clarify, when you say "usually the code needs to be recreated if the segment base changes" - what are the potential risks of sneaking the segment base change in like this? – esrever May 30 '18 at 10:56
  • 1
    @esrever some xrefs, especially those based on current segment/CS may need to be recreated – Igor Skochinsky May 30 '18 at 11:01
5

IDA is not very user friendly when it comes to manipulating the segments. There's an option to keep the data while you're resizing the segment, it will at least keep your bytes intact. But the all your names and comments will be lost. So the only thing I can suggest is to use save database to IDC, and then edit it to remove the segment creation part. So that it will still apply the names, comments, etc.

Personally, I do firmware reversing in two steps:

1) load the whole firmware at address 0, recover the memory map. Close this IDA database.

2) split the firmware into pieces, create new IDA database and load the pieces properly

3

You can merge segments in two steps:

  • first make sure the end address of the lower segment matches the start address of the higher segment.
  • then once the segments are adjacent, you can combine them without losing data by setting the end address of the first segment to end address of the second segment.

Then IDA will automatically merge the two segments without loss of data.

I think they do need to have the same segment bitness ( 16 or 32 bit ).

Do make a backup copy of your database before trying this out, typo's can destroy your data.


Splitting works similarly:

  • add a segment with the same attributes and end-address as the original.
    • IDA will automatically split, and retain contents.

Example ( in IDC scripting )

Position your cursor on the first line of the new segment you want to create, and paste this in the script commandline:

AddSeg(here, SegEnd(here), GetSegmentAttr(here, SEGATTR_ORGBASE), 
    GetSegmentAttr(here, SEGATTR_BITNESS), 
    GetSegmentAttr(here, SEGATTR_ALIGN),
    GetSegmentAttr(here, SEGATTR_COMB));
  • I tried your IDC command, but have the same problem. First: "The range 00000000000FB050..0000000000100000 contain instructions/data. Do you want to remove these instructions?" If I choose yes, all work in the new segment part is lost. If I choose no: "Create a segment (00000000000FB050-0000000000100000, sel 0000000000000000): can't trim the previous segment." (the previous segment is at F0000-100000) – esrever May 28 '18 at 6:36
  • if you are browsing a 80186 rom, why do you post addresses as 64 bit (16 hexdigits ) numbers? – Willem Hengeveld May 28 '18 at 6:42
  • I must say that i never tried this command on a segmented architecture, i know it works fine in flat address spaces. Can you maybe post a link to the rom, so i try it for myself? – Willem Hengeveld May 28 '18 at 6:43
  • That's how I get them from IDA. Maybe I've goofed when first importing the binary? – esrever May 28 '18 at 6:43
  • I've added it to the original post now. – esrever May 28 '18 at 6:49

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.