如何在 IDA 中更改段上的读/写/执行标志?

逆向工程 艾达 分割
2021-07-05 04:42:15

有时,当您在 IDA 中手动加载二进制文件时,您最终会得到具有未知读写和执行标志的段。您可以在 Segments 子视图 ( Shift+ F7)下看到它们有没有办法在不运行脚本和修改它们的情况下从 IDA 的 GUI 中更改这些标志?

这似乎是一个基本功能,对于 Hex Rays 反编译器的正确操作非常重要。我一直在使用该类来表达段权限,考虑到这些标志的存在,这似乎是错误的。

虽然我很感激在一般情况下回答的问题,但在这种特殊情况下,我正在处理代码和数据混合的平面二进制 ARM 文件。所有页面级别的权限都由软件在加载时通​​过 MMU 直接映射来设置。

4个回答

我不知道 GUI 中是否有任何本机内置允许您更改分段权限的内容,但是您可以使用 IDC 轻松更改分段权限。

来自 IDA 的帮助文件:

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

从段.hpp:

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

因此,如果要将以 VA 0x00400000 开始的段的权限设置为读取和执行,则只需运行以下 IDC 命令:

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

或者,如果你只是寻找应对来自六角射线的警告,但可能足以使用细分查看在GUI中从改变一个段的类CODEDATA

这些所谓的标志是从二进制导入的。我们以微软的 PE/COFF格式二进制为例。这是PE的基本布局:

PE/COFF 布局

您在 IDA 中看到的每个段都是根据特定段/段的IMAGE_SECTION_HEADER结构加载的该结构具有以下格式:

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该结构的成员拥有指示该部分/段的权限级别的标志。有许多不同的标志可用,但仅举几例:IMAGE_SCN_MEM_READIMAGE_SCN_MEM_WRITE,和IMAGE_SCN_MEM_EXECUTE

当 IDA 加载可执行文件时,此后的所有工作都在数据库中完成。IDA 不会对可执行文件进行任何更改。我相信您必须修补可执行文件才能永久更改段的读/写/执行权限。除非,有一个脚本或插件来做到这一点。

你可以使用 Sark ( code , docs ):

import sark

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

# Set the permissions
segment.permissions.write = True

免责声明:我是 Sark 的作者。

添加到以前的响应中,您可以通过 python 脚本从另一个段复制属性:

       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 是你的段的起始地址,@attrs_from 是一个字符串,代表你想要从中复制属性的段(例如,“.text”)