PE文件格式(区块)

华盟原创文章投稿奖励计划

节区头定义了各节区的属性

节区头是由IMAGE_SECTION_HEADER结构体组成的数组,每个结构体对应一个节区
typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];        // Name,为对应节区的名字,IMAGE_SIZEOF_SHORT_NAME的值固定为8。如名字的长度小于8,以NULL字符结束;名字的长度等于8,则没有NULL字符,因为数组长度为8。节区的名字通常以点号开头,通常而言,这个名字可以随便修改
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;        // 在未对齐的情况下,区块所有数据的大小
    } Misc;
    DWORD   VirtualAddress;        // 区块被装载到内存时的RVA,这个值总是SectionAlignment的整数倍
    DWORD   SizeOfRawData;        // 区块数据在磁盘文件中按照FileAlignment对齐后的大小
    DWORD   PointerToRawData;        // 区块数据在磁盘文件中的偏移地址
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;        // 区块的属性值,表明区块的可读、可写、可执行等
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
IMAGE_SECTION_HEADER结构体占用40字节,下图是节表头文件偏移值:0x1E8

PE文件格式(区块) 

PE文件格式(区块) 
PE文件格式(区块) 

节区的大小是需要进行对齐处理的,而且在文件中的对齐值与在内存中的对齐值是不一样的,在IMAGE_NT_HEADERS的OptionalHeader中指明了这两个值(FileAlignment和SectionAlignment)
节区的起始地址总是进行对齐后的值
下图中可以看到PE文件节区的数目为5,文件对齐值为0x200,节区(内存)对齐值为0x1000

PE文件格式(区块) 

上面已经计算出了节表头的文件偏移值为0x1E8,而且知道每个节表头的大小为40字节,那么5个节表头的大小就是200字节,因此可以计算出节表头结束的偏移值为:

0x1E8 + 40 × 5 = 0x2B0
区块中的数据逻辑通常是关联的。PE文件一般至少有两个区块,一个是代码块,另一个是数据块。每个块都有特定的名字,这个名字用于表示区块的用途

PE文件格式(区块) 

RVA(相对虚拟地址),相对于PE文件载入地址的偏移地址
相对虚拟地址(RVA)= 虚拟地址(VA)- 基址(ImageBase)
RAW = RVA - VirtualAddress + PointerToRawData
RVA = 1100,File Offset = ?
1100位于第一个节区(.text)
RAW = 1100(RVA)- 1000(VirtualAddress)+ 400(PointerToRawData)= 500

PE文件格式(区块) 

为了更容易理解,写一个程序,把随机基址关掉

PE文件格式(区块) 
PE文件格式(区块) 

PE文件格式(区块) 

RVA = 0x403018 – 0x400000 = 0x3018

PE文件格式(区块) 

PE文件格式(区块) 

File Offset = 0x3018 – 0x3000+0x1E00 = 0x1E18

PE文件格式(区块) 

PE文件格式(区块)

本文原创,作者:congtou,其版权均为华盟网所有。如需转载,请注明出处:https://www.77169.net/html/271766.html

发表回复