10

I am trying to reverse engineer a binary blob I expect to transition from 16-bit real mode into 32-bit protected mode (it is boot time code), so I expect the code to contain code of both sorts.

When I launch IDA, I am given the option of 16 or 32-bit code, but not mixed.

How do I instruct IDA to attempt to disassemble data at a given address as 32-bit mode?

I can using the 16-bit analyzer deduce the initial jump (unoriginally) and IDA happily analyses the code from there. I can see where the 32-bit code jumps to (far jump, so IDA doesn't try to analyze it), but IDA treats this as 16-bit when I hit C.

Other than launching a 16, and a 32-bit dissasmbly session, can I do this in one?

  • The arm processor module can do exactly this. So i guess it is a feature that could be implemented in theory. – Willem Hengeveld Aug 21 '14 at 6:02
7

Ida Free 5

Edit -> Segments ->CreateSegment

in the dialog

segment name  = seg001....seg00n
start         = <start address viz 0x0A
end           = <end address viz 0x1e
base          = 0x0 
class         = some text viz 32one,32two,16three
radio button  = 32 bit segment or 16 bit segment as needed
click yes to a cryptic dialog 

example the binary stream contains 16 bit dos puts routine and 32 bit random pushes intermixed

C:\Documents and Settings\Admin\Desktop>xxd -g 1 1632blob.bin
0000000: b4 01 cd 21 88 c2 b4 02 cd 21 68 78 56 34 12 68  ...!.....!hxV4.h
0000010: 0d d0 37 13 68 be ba 37 13 68 00 0d db ba b4 01  ..7.h..7.h......
0000020: cd 21 88 c2 b4 02 cd 21 68 78 56 34 12 68 0d d0  .!.....!hxV4.h..
0000030: 37 13 68 be ba 37 13 68 00 0d db ba b4 01 cd 21  7.h..7.h.......!
0000040: 88 c2 b4 02 cd 21 68 78 56 34 12 68 0d d0 37 13  .....!hxV4.h..7.
0000050: 68 be ba 37 13 68 00 0d db ba                    h..7.h....

C:\Documents and Settings\Admin\Desktop>

loading this blob as binary file moving to offset 0 and pressing c would disassemble all bytes as 16 bit

now you can move to offset 0x0a and create a 32 bit segment with start as 0x0a end as 0x1e base as 0x0 class as 32one use 32bitsegment radio button and press c again to create 32 bit disassembly

see below

seg000:0000                ;
seg000:0000                ; +-------------------------------------------------------------------------+
seg000:0000                ; ¦     This file is generated by The Interactive Disassembler (IDA)        ¦
seg000:0000                ; ¦     Copyright (c) 2010 by Hex-Rays SA, <support@hex-rays.com>           ¦
seg000:0000                ; ¦                      Licensed to: Freeware version                      ¦
seg000:0000                ; +-------------------------------------------------------------------------+
seg000:0000                ;
seg000:0000                ; Input MD5   : AEB17B9F8C4FD00BF2C04A4B3399CED1
seg000:0000
seg000:0000                ; ---------------------------------------------------------------------------
seg000:0000
seg000:0000                                .686p
seg000:0000                                .mmx
seg000:0000                                .model flat
seg000:0000
seg000:0000                ; ---------------------------------------------------------------------------
seg000:0000
seg000:0000                ; Segment type: Pure code
seg000:0000                seg000          segment byte public 'CODE' use16
seg000:0000                                assume cs:seg000
seg000:0000                                assume es:seg005, ss:seg005, ds:seg005, fs:seg005, gs:seg005
seg000:0000 B4 01                          mov     ah, 1
seg000:0002 CD 21                          int     21h
seg000:0004 88 C2                          mov     dl, al
seg000:0006 B4 02                          mov     ah, 2
seg000:0008 CD 21                          int     21h
seg000:0008                seg000          ends
seg000:0008
seg001:0000000A                ; ---------------------------------------------------------------------------
seg001:0000000A
seg001:0000000A                ; Segment type: Regular
seg001:0000000A                seg001          segment byte public '32one' use32
seg001:0000000A                                assume cs:seg001
seg001:0000000A                                ;org 0Ah
seg001:0000000A                                assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg001:0000000A 68 78 56 34 12                 push    12345678h
seg001:0000000F 68 0D D0 37 13                 push    1337D00Dh
seg001:00000014 68 BE BA 37 13                 push    1337BABEh
seg001:00000019 68 00 0D DB BA                 push    0BADB0D00h
seg001:00000019                seg001          ends
seg001:00000019
seg002:001E                ; ---------------------------------------------------------------------------
seg002:001E
seg002:001E                ; Segment type: Pure code
seg002:001E                seg002          segment byte public 'CODE' use16
seg002:001E                                assume cs:seg002
seg002:001E                                ;org 1Eh
seg002:001E                                assume es:seg005, ss:seg005, ds:seg005, fs:seg005, gs:seg005
seg002:001E B4 01                          mov     ah, 1
seg002:0020 CD 21                          int     21h
seg002:0022 88 C2                          mov     dl, al
seg002:0024 B4 02                          mov     ah, 2
seg002:0026 CD 21                          int     21h
seg002:0026                seg002          ends
seg002:0026
seg003:00000028                ; ---------------------------------------------------------------------------
seg003:00000028
seg003:00000028                ; Segment type: Regular
seg003:00000028                seg003          segment byte public '32two' use32
seg003:00000028                                assume cs:seg003
seg003:00000028                                ;org 28h
seg003:00000028                                assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg003:00000028 68 78 56 34 12                 push    12345678h
seg003:0000002D 68 0D D0 37 13                 push    1337D00Dh
seg003:00000032 68 BE BA 37 13                 push    1337BABEh
seg003:00000037 68 00 0D DB BA                 push    0BADB0D00h
seg003:00000037                seg003          ends
seg003:00000037
seg004:003C                ; ---------------------------------------------------------------------------
seg004:003C
seg004:003C                ; Segment type: Pure code
seg004:003C                seg004          segment byte public 'CODE' use16
seg004:003C                                assume cs:seg004
seg004:003C                                ;org 3Ch
seg004:003C                                assume es:seg005, ss:seg005, ds:seg005, fs:seg005, gs:seg005
seg004:003C B4 01                          mov     ah, 1
seg004:003E CD 21                          int     21h
seg004:0040 88 C2                          mov     dl, al
seg004:0042 B4 02                          mov     ah, 2
seg004:0044 CD 21                          int     21h
seg004:0044                seg004          ends
seg004:0044
seg005:00000046                ; ---------------------------------------------------------------------------
seg005:00000046
seg005:00000046                ; Segment type: Regular
seg005:00000046                seg005          segment byte public '32three' use32
seg005:00000046                                assume cs:seg005
seg005:00000046                                ;org 46h
seg005:00000046                                assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg005:00000046 68 78 56 34 12                 push    12345678h
seg005:0000004B 68 0D D0 37 13                 push    1337D00Dh
seg005:00000050 68 BE BA 37 13                 push    1337BABEh
seg005:00000055 68 00 0D DB BA                 push    0BADB0D00h
seg005:00000055                seg005          ends
seg005:00000055
seg005:00000055
seg005:00000055                                end
| improve this answer | |
10

You could either do it manually or create a custom loader module for your binary blob. What you need to do is separate code into 2 segments: 32-bit segment and 16-bit segment, and specify appropriate addressing mode. IDA supports 16, 32, 64 bit modes. If needed you could manually create 2 different code segments and change address mode manually by pressing Alt+S

In order to incorporate it in a loader, you may utilize getseg and set_segm_addressing from segment.hpp out of IDA SDK:

// Get pointer to segment by linear address
//      ea - linear address belonging to the segment
// returns: NULL or pointer to segment structure

inline segment_t *getseg(ea_t ea) { return (segment_t *)(segs.get_area(ea)); } 

// Change segment addressing mode (16, 32, 64 bits)
// You must use this function to change segment addressing, never change
// the 'bitness' field directly.
// This function will delete all instructions, comments and names in the segment
//      s      - pointer to segment
//      bitness- new addressing mode of segment
//                 2: 64bit segment
//                 1: 32bit segment
//                 0: 16bit segment
// returns: 1-ok, 0-failure

idaman bool ida_export set_segm_addressing(segment_t *s, size_t bitness);

Firstly, you will need to get a pointer to a segment structure using getseg. Thereafter, you could change segment addressing mode to 16 or 32 bit using set_segm_addressing.

| improve this answer | |

Your Answer

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