11

Sometimes when you load a binary manually in IDA you wind up with segments that have unknown read write and execute flags. You can see them under the Segments subview (Shift + F7). Is there a way to change these flags from within the GUI of IDA without running a script and modifying them?

It seems like such a basic piece of functionality which is very important for the proper operation of the Hex Rays decompiler. I've been using the class to express segment rights which just seems wrong considering these flags exist.

Although I would appreciate the question being answered in the general case, in this particular case I'm dealing with flat binary ARM files with code and data intermixed. All page level permissions are set up by the software when it loads by directly mapping them via the MMU.

4 Answers 4

10

I don't know of anything natively built into the GUI that allows you to change the segment permissions, but you can easily change the segment permissions with IDC.

From IDA's help file:

SetSegmentAttr  

***********************************************
** set segment attribute
        arguments:      segea - any address within segment
                        attr  - one of SEGATTR_... constants
                        value - the new value of the attribute

success SetSegmentAttr(long segea, long attr, long value);
SEGATTR_ALIGN          alignment
SEGATTR_COMB           combination
SEGATTR_PERM           permissions
SEGATTR_FLAGS          segment flags
SEGATTR_SEL            segment selector
SEGATTR_ES             default ES value
SEGATTR_CS             default CS value
SEGATTR_SS             default SS value
SEGATTR_DS             default DS value
SEGATTR_FS             default FS value
SEGATTR_GS             default GS value
SEGATTR_TYPE           segment type
SEGATTR_COLOR          segment color

From segment.hpp:

/* 22 */  uchar perm;           // Segment permissions (0-no information)
#define SEGPERM_EXEC  1 // Execute
#define SEGPERM_WRITE 2 // Write
#define SEGPERM_READ  4 // Read

As such, if you wanted to set the permissions of a segment that begins at VA 0x00400000 to both Read and Execute, you could just run the following IDC command:

SetSegmentAttr(0x00400000, SEGATTR_PERM, 4 | 1);

Alternatively, if you're just looking to deal with warnings from Hex-Rays, it may suffice to use the Segments view in the GUI to change a segment's class from CODE to DATA.

4
  • Very ellegant solution. Jul 2, 2013 at 15:20
  • Thanks, I'm aware of the scripting solutions as well as writing your own importer. Regarding your second solution (which is what I'm currently using), this isn't warning related. It has to do with data and code being intermixed. Hex Rays has issues with constant pools that are embedded in certain segment types which has significant negative impact on the decompilation when dealing with low level software. I'm leaning towards there being nothing built into IDA and the scripting solution mapped to a hotkey being the easiest. Jul 2, 2013 at 16:59
  • Time to write a Plugin =D I vaguely recall contacted Ilfak with this on a support matter while RCE-ing a Symbian Application. I recall that I had to remove the segments and rebuild them.
    – Stolas
    Jul 3, 2013 at 12:55
  • Another solution would be to directly change the .perm member of a segment_t structure representing the segment.
    – tmr232
    Jul 1, 2015 at 16:26
8

These so called flags are imported from binary. Let's take Microsoft's PE/COFF format binary for example. This is basic layout of PE:

PE/COFF Layout

Each segment that you see in IDA is a loaded in accordance to IMAGE_SECTION_HEADER structure of the particular section/segment. The structure has the following format:

typedef struct _IMAGE_SECTION_HEADER {
  BYTE  Name[IMAGE_SIZEOF_SHORT_NAME];
  union {
    DWORD PhysicalAddress;
    DWORD VirtualSize;
  } Misc;
  DWORD VirtualAddress;
  DWORD SizeOfRawData;
  DWORD PointerToRawData;
  DWORD PointerToRelocations;
  DWORD PointerToLinenumbers;
  WORD  NumberOfRelocations;
  WORD  NumberOfLinenumbers;
  DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

DDWORD Characteristics member of the structure holds flags that indicate permission levels for the section/segment. There are lots different flags available, but to name few: IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE, and IMAGE_SCN_MEM_EXECUTE.

As IDA loads executable, all work thereafter is done within the database. No changes are made to executable by IDA. I believe you will have to patch your executable in order to change read/write/execute permissions on a segment permanently. Unless, there is a script or plug-in to do it.

3
  • In this case the binary isn't using a standard format. It's imported from a flat binary file. The file is ARM code and some data from start to finish. It's a low level loader which maps its own segment directly by changing the MMU mappings and permissions. Jul 2, 2013 at 16:53
  • @PeterAndersson "...a low level loader which maps its own segment directly by changing the MMU mappings and permissions." Could you possible patch the binary to modify necessary permissions during mapping process?
    – PSS
    Jul 2, 2013 at 17:56
  • it's more of an issue with how the Hex Rays decompiler treats various segment types and flags in this particular case but the question really is more general. When you first import the binary the RWX flags are in an unknown state, as you reverse engineer it you discover their true attributes when the segment is mapped by the MMU. As a matter of fact I don't think there's even a way of importing a binary flat file as a segment and setting the flags. Jul 2, 2013 at 18:16
3

You can do it using Sark (code, docs):

import sark

# Get the segment
segment = sark.Segment(ea=0x00400000)

# Set the permissions
segment.permissions.write = True

Disclaimer: I am the author of Sark.

0

Adding to previous responses, you can copy attributes from another segment via a python script:

       try:
            attributes = [
                SEGATTR_ALIGN,
                SEGATTR_PERM,
                SEGATTR_BITNESS,
                SEGATTR_FLAGS,
                SEGATTR_SEL,
                SEGATTR_TYPE
            ]

            from_seg_ea = list(Segments())[SegByName(attrs_from)]
            if from_seg_ea == BADADDR:
                print "Error in copying attributes"

            for attr in attributes:
                SetSegmentAttr(startea,
                               attr,
                               GetSegmentAttr(from_seg_ea, attr))
        except Exception as e:
            print e
            SegDelete(startea, 1)

@startea is the start address of your segment, @attrs_from is a string representing the segment you want to copy attributes from (e.g., ".text")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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