已发表至CSDN博客。
通常区块中的数据逻辑上是关联的。PE文件一般至少有两个区块:一个是代码块,另一个是数据块。每一个区块都有截然不同的名字,然而这个名字并没有多少卵用,只是标明这个区块主要的用途。例如有一个区块叫.rdata,表明它是一个只读区块。还有其他的一些区块,例如.text一般都是存代码的,.reloc存放可执行文件的基址重定位内容·····
我们可以创建和命名自己的区块,在VC++中,用#pragma来声明,告诉编译器插入数据到一个区块内:
#pragma data_seg("MY_DATA")
区块还可以合并,将相关的区块合并到一起,能节省磁盘和内存空间,每个区块至少占用一个内存页嘛,如果两个区块的内容没有超过一个内存页,而且区块的用途相近,那就在一起在一起在一起咯。
区块的大小是要对齐的,有两种对齐值,一种用于磁盘文件内,一种用于内存中。
这两个值定义在PE头中的IMAGE_OPTIONAL_HEADER结构中,一个是SectionAlignment(内存)、另一个是FileAlignment(磁盘)。
每一区块从对齐值的倍数的偏移开始,然而区块的实际代码或数据的大小不一定刚好是这么多,所以其他剩下的地方一般都是用00H来填充,这就是区块中的间隙。在磁盘中的对齐值一般是200H,现在假设.data区块从400H开始存,长度为90H,那么它实际上就占了400H~490H这段空间,从490~600H全部填00H,然后接下来的一个区块从600H开始存。
PE 文件头里边的SectionAligment 定义了内存中区块的对齐值。PE 文件被映射到内存中时,区块总是至少从一个页边界开始。
一般在X86 系列的CPU 中,页是按4KB(1000h)来排列的;在IA-64 上,是按8KB(2000h)来排列的。所以在X86 系统中,PE文件区块的内存对齐值一般等于 1000h,每个区块按1000h 的倍数在内存中存放。
DOS头、PE文件头和区块表被映射到内存后,其偏移位置并没有发生改变。而区块不一样,其偏移位置会发生变化。
例如.text块起始端与文件头的偏移量为A,映射到内存后与文件头的偏移量为B,A为文件偏移地址(File Offset),B为相对虚拟地址(RVA),假设它们的差值为C,则有如下关系:
文件偏移地址 = 相对虚拟地址 - 差值
文件偏移地址 = 该块在内存中的虚拟地址 - 基地址 - 差值
建议利用一些PE结构查询工具,实践计算一下,理论的东西太难,实践一下子就能懂了。工具可以用PEid、LordPE等。
通常区块中的数据逻辑上是关联的。PE文件一般至少有两个区块:一个是代码块,另一个是数据块。每一个区块都有截然不同的名字,然而这个名字并没有多少卵用,只是标明这个区块主要的用途。例如有一个区块叫.rdata,表明它是一个只读区块。还有其他的一些区块,例如.text一般都是存代码的,.reloc存放可执行文件的基址重定位内容·····
我们可以创建和命名自己的区块,在VC++中,用#pragma来声明,告诉编译器插入数据到一个区块内:
#pragma data_seg("MY_DATA")
区块还可以合并,将相关的区块合并到一起,能节省磁盘和内存空间,每个区块至少占用一个内存页嘛,如果两个区块的内容没有超过一个内存页,而且区块的用途相近,那就在一起在一起在一起咯。
区块的大小是要对齐的,有两种对齐值,一种用于磁盘文件内,一种用于内存中。
这两个值定义在PE头中的IMAGE_OPTIONAL_HEADER结构中,一个是SectionAlignment(内存)、另一个是FileAlignment(磁盘)。
每一区块从对齐值的倍数的偏移开始,然而区块的实际代码或数据的大小不一定刚好是这么多,所以其他剩下的地方一般都是用00H来填充,这就是区块中的间隙。在磁盘中的对齐值一般是200H,现在假设.data区块从400H开始存,长度为90H,那么它实际上就占了400H~490H这段空间,从490~600H全部填00H,然后接下来的一个区块从600H开始存。
PE 文件头里边的SectionAligment 定义了内存中区块的对齐值。PE 文件被映射到内存中时,区块总是至少从一个页边界开始。
一般在X86 系列的CPU 中,页是按4KB(1000h)来排列的;在IA-64 上,是按8KB(2000h)来排列的。所以在X86 系统中,PE文件区块的内存对齐值一般等于 1000h,每个区块按1000h 的倍数在内存中存放。
DOS头、PE文件头和区块表被映射到内存后,其偏移位置并没有发生改变。而区块不一样,其偏移位置会发生变化。
例如.text块起始端与文件头的偏移量为A,映射到内存后与文件头的偏移量为B,A为文件偏移地址(File Offset),B为相对虚拟地址(RVA),假设它们的差值为C,则有如下关系:
文件偏移地址 = 相对虚拟地址 - 差值
文件偏移地址 = 该块在内存中的虚拟地址 - 基地址 - 差值
建议利用一些PE结构查询工具,实践计算一下,理论的东西太难,实践一下子就能懂了。工具可以用PEid、LordPE等。