有时,当您在IDA中手动加载二进制文件时,最终会遇到具有未知读写标志和执行标志的段。您可以在“细分”子视图下(Shift + F7)看到它们。有没有一种方法可以从IDA的GUI内更改这些标志,而无需运行脚本并进行修改?

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

尽管我很欣赏在一般情况下要回答的问题,但在这种情况下,我正在处理带有代码和数据的平面二进制ARM文件。所有页面级别的权限都由软件在加载时通​​过MMU直接映射设置。

#1 楼

我不知道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


来自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


这样,如果要设置以以下位置开头的段的权限VA 0x00400000既要读取又要执行,则可以运行以下IDC命令:

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

或者,如果您只是想处理来自Hex-Rays的警告,使用GUI中的细分视图将细分的类从CODE更改为DATA可能就足够了。

评论


非常优雅的解决方案。

–奶油饼干
13年7月2日在15:20

谢谢,我知道脚本解决方案以及编写自己的导入器。关于您的第二个解决方案(这是我当前正在使用的),这与警告无关。它与数据和代码混合在一起有关。十六进制射线存在嵌入某些段类型中的常量池的问题,这在处理低级软件时会对反编译产生重大负面影响。我倾向于在IDA中不内置任何内容,并且将映射到热键的脚本解决方案最简单。

–彼得·安德森(Peter Andersson)
13年7月2日在16:59



是时候写一个插件= D了,我隐约记得在RCE开发Symbian应用程序时就此事与Ilfak联系了。我记得我不得不删除这些段并重新构建它们。

– Stolas
13年7月3日在12:55



另一个解决方案是直接更改表示该段的segment_t结构的.perm成员。

–TMR232
15年7月1日在16:26

#2 楼

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



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_WRITEIMAGE_SCN_MEM_EXECUTE

随着IDA加载可执行文件,此后的所有工作都在数据库中完成。 IDA不会对可执行文件进行任何更改。我相信您将必须修补可执行文件,以便永久更改段上的读/写/执行权限。除非有脚本或插件来执行。

评论


在这种情况下,二进制文件未使用标准格式。它是从平面二进制文件导入的。该文件是ARM代码以及从头到尾的一些数据。这是一个低级加载程序,它通过更改MMU映射和权限直接映射其自己的段。

–彼得·安德森(Peter Andersson)
2013年7月2日在16:53



@PeterAndersson“ ...一个低级加载程序,它通过更改MMU映射和权限直接映射其自身的段。”您能否修补二进制文件以在映射过程中修改必要的权限?

– PSS
13年7月2日在17:56

在这种特殊情况下,Hex Rays反编译器如何处理各种段类型和标志更多是一个问题,但问题实际上是更普遍的。首次导入二进制文件时,RWX标志处于未知状态,当您进行反向工程时,您会在MMU映射段时发现其真实属性。实际上,我认为甚至没有一种方法可以将二进制平面文件作为段导入并设置标志。

–彼得·安德森(Peter Andersson)
13年7月2日在18:16

#3 楼

您可以使用Sark(代码,文档)进行操作:

import sark

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

# Set the permissions
segment.permissions.write = True


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

#4 楼

添加到以前的响应中,可以通过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”)