飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 5461|回复: 15

PE文件中区段的详细分析

[复制链接]

该用户从未签到

发表于 2016-1-4 22:34:03 | 显示全部楼层 |阅读模式
PE文件中区段的详细分析(供大家参考学习)
当我们用ollydbg 分析PE文件时,加载后Alt + M 时看到PE Header 和很多区段,为了更深入得了解区块,本文将对区块进行分析.
第一部分:区块的基本知识
区块
在PE文件头与原始数据之间存在一个区块表,区块表包括每个块在映像中的信息,分别指向不同的区块实体。
区块表:
     区块表是一个IAMGE_SECTION_HEADER  结构数组,每一个IAMGE_SECTION_HEADER结构包含了他所关联区块的信息,如位置,长度,属性,编程时由
IMAMGE_NT_HEADERS.FileHeader.NumberOfSections 得到.
IMAGE_SECTION_HEADER 结构定义
Struct IMAGE_SECTION_HEADER
{
        DBYTE  Name;                     // 8个字节的块名
        union Misc                       // 区块尺寸
        {
            DWORD  PhysicalAddress;     // 物理地址  (一般忽略)
            DWORD  VirtualSize;         // 虚拟地址
};
DWORD VirtualAddress;           // 区块RVA 地址
DWORD SizeOfRawData;            // 在文件中对齐后的尺寸
DWORD PointerToRawData;         // 在文件中偏移
DWORD PointerToRelocations;     // 在OBJ 文件中使用,重定位的偏移
DWORD PointerToLinenumbers;     // 行号表偏移(供调试用)
WORD  NumberOfRelocations;      // 在OBJ文件中使用,重定位项数目
WORD  NumberOfLinenumbers;      // 行号表中行号数目
DWORD Characteristics;          // 区块的属性
};
重要属性介绍
(1)Name : 这是一个8位的ASCII(不是Unicode内码),用来定义块名,多数块名以.开始(如.Text),这个.实际上不是必需的,注意如果块名超过了8个字节,则没有最后面的终止标志NULL字节,带有$的区块的名字会从编译器里将带有$的相同名字的区块被按字母顺序合并。
(2) VirtualSize: 指出实际的,被使用的区块大小,是区块在没有对齐处理前的实际大小.如果VirtualSize > SizeOfRawData,那么SizeOfRawData是可执行文件初始化数据的大小
(SizeOfRawData – VirtualSize)的字节用0来填充.这个字段在OBJ文件中被设为0.
(3)VirtualAddress: 该块时装载到内存中的RVA,注意这个地址是按内存页对齐的,她总是SectionAlignment的整数倍,在工具中第一个块默认RVA为1000,在OBJ中为0。
(4)SizeofRawData: 该块在磁盘中所占的大小,在可执行文件中,该字段包括经过FileAlignment调整后块的长度。例如FileAlignment的大小为200h, 如果VirtualSize中的块长度为19Ah个字节,这一块保存的长度为200h个字节.
(5) PointerToRawData: 该块是在磁盘文件中的偏移,程序编译或汇编后生成原始数据,这个字段用于给出原始数据块在文件的偏移,如果程序自装载PE或COFF文件(而不是由OS装载),这种情况,必须完全使用线性映像方法装入文件,需要在该块处找到块的数据。
(6) PointerToRelocations 在PE中无意义
(7) PointerToLinenumbers 行号表在文件中的偏移值,文件调试的信息
(8) NumberOfRelocations 在PE中无意义
(9) NumberOfLinenumbers 该块在行号表中的行号数目
(10) Characteristics 块属性,(如代码/数据/可读/可写)的标志,这个值可通过链接器的/SECTION选项设置.下面是比较重要的标志:
字段值
用途
IAMGE_SCN_CNT_CODE               0x20h
包含代码,常与10000000h 一起设置
IMAGE_SCN_CNT_INITIALIZED_DATA   0x40h
该块包含已初始化的数据
IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x80h
该块包含未初始化的数据
IAMGE_SCN_MEM_DISCARDABLE  0x02000000h
该块可被丢弃,一旦加载可被丢弃的块.reloc(重定位块)
IAMGE_SCN_MEM_SHARED       0x10000000h
该块为共享块
IAMGE_SCN_MEM_EXECUTE      0x20000000h
该块可执行通常与0x20标志一起被设置
IAMGE_SCN_MEM_READ         0x40000000h
该块可读
IAMGE_SCN_MEM_WRITE        0x80000000h
该块可写
[字段属性]
第二部分:实际部分(让不同的人有不同想象空间)
以上是区块的基本知识,下面是我们分析PE文件时,心中应该有印象的东西,这样我们会猜猜,会获取意想不到的效果,尤其在解密,破解脱壳中表现得淋漓尽致.
编程区:
简单的例子:
原理: Section Table 是由IAMGE_SECTION_HEADER结构组成的数组,如何确定Section Table 的位置呢?或者是如何得到第一个IAMGE_SECTION_HEADER 的位置.我们知道在VC++中,利用IAMGE_FIRST_SECTION宏可以得到.
这里向大家介绍一点细节问题:
在PE文件中,OptionalHeader 的大小是可以变化的,虽然它的大小通常是E0h,原因是可选文件头大小是由文件头中的SizeOfOptionHeader 字段指定的,并不是固定值,这也是IAMGE_FIRST_SETION 宏对可选头的大小不直接用固定值的原因,大家应该注意.
// 此函数的作用是利用IAMGE_FIRST_SECTION宏得到区块表的起始位置
PIMAGE_SECTION_HEADER GetFirstSectionHeader(PIAMGE_NT_HEADER pNtH)
{
    PIAMGE_SECTION_HEADER pSH;
    pSH = IAMGE_FIRST_SECTION(pNtH);
    return pSH;
}
// 假如用ListView 控件来显示PE区段的信息
void ShowSectionHeaderInfo(HWND hDlg)
{
    LVITEM lvItem;
    char cBuff[9],cName[9];
    WORD i;
    PIMAGE_FILE_HEADER pFH = NULL;
    PIMAGE_SECTION_HEADER pSH = NULL;
    pFH = GetFileHeader(stMapFile.ImageBase); // 得到文件头指针,读者自己完成
    if(!pFH)
        return ;
    pSH = GetFirstSectionHeader(stMapFile.IamgeBase);//得到第一个区块表的指针
    for(i = 0; i < PFH -> NumberOfSections; i++) // 在列表中显示各区块信息
{
    memset(&lvItem, 0, sizeof(lvItem));
    lvItem.mask = LVIF_TEXT;
    lvItem.iTtem = i;
    memset(cName, 0, sizeof(cName));
    memcpy(cName, pSH->Name, 8);
    lvItem.pszText = cName;
    SendDlgItemMessage(hDlg, 1006, LVM_INSETRTITEM, 0, (LPARAM)& lvItem);
    …(其他的数据段 代码类似)
    ++pSH;
}
}
区块描述区:
    区块中的数据逻辑上是关联,区块的映像是按起始地址(RVA)来排列,使用区块名只是为了人们方便,对OS无关紧要.
EXE 和 OBJ 定义 .text .data
Borland 连接器用的是 CODE DATA
名称
描述
.text
默认的代码区块,它的内容全是指令代码,链接器把所有目标文件的text块连接成一个大的.text块,使用Borland C++,编译器产生的代码存放在CODE的区域里
.data
默认的读/写数据块,全局变量,静态变量一般放在这个区段
.rdata
默认只读数据区块,但程序中很少用到该块中的数据,一般两种情况用到,一是MS 的链接器产生EXE文件中用于存放调试目录,二是用于存放说明字符串,如果程序的DEF文件中指定了DESCRIPTION,字符串就会出现在rdata中
.idata
包含其他外来的DLL的函数及数据信息,即输入表,将.idata区块合并成另一个区块已成为一种惯例,典型的是.rdata区块,默认的,链接器只在创建一个Release模式的可执行文件时才能将idata合并到另外一个区块中
.edata
输出表,当创建一个输出API或数据的可执行文件时,连接器会创建一个.EXP文件,这个.EXP文件包含一个.edata区块,其会被加载到可执行文件中,经常被合并到.text或.rdata 区块中
.rsrc
资源,包括模块的全部资源,如图标,菜单,位图等,这个区块是只读的,无论如何不应该吧它命名为.rsrc以外的名字,也不能合并到其他的区块里
.bss
未初始化的数据,很少在用,取而代之的是执行文件的.data区块的的VirtualSize被扩展大的空间里用来装未初始化的数据.
.crt
用于C++ 运行时(CRT)所添加的数据
.tls
TLS的意思是线程局部存储器,用于支持通过_declspec(thread)声明的线程局部存储变量的数据,这包括数据的初始化值,也包括运行时所需要的额外变量
.reloc
可执行文件的机制重定位,基址重定位一般仅Dll需要的
.sdata
相对于全局指针的可被定位的 短的读写数据
.pdata
异常表,包含CPU特定的IAMGE_RUNTIME_FUNTION_ENTRY结构数组,DataDirectory中的IMAGE_DIRECTORY_ENTRY_EXCEPTION指向它.
.didat
延迟装入输入数据,在非Release模式下可以找到
总结:虽然编译器自动产生一系列标准的区块,我们可以创建和命名自己的区块,在VC++中可以使用:
#pragma data_seg(“My_DATA”)
编译器有个很搞笑的特征,看见两个区块相似的属性的区块,那么连接时就合并成一个区块,这个取决于是否用/merge开关 /merge .rdata = .text
参考文献: 加密解密3

评分

参与人数 6威望 +44 飘云币 +28 收起 理由
vitamin + 4
netle8 + 4 很给力!
speedboy + 8 + 8 赞一个!
a74909898 + 4 很给力!
small-q + 20 + 20 很给力!
expasy + 4 PYG有你更精彩!

查看全部评分

PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2019-11-29 10:15
  • 签到天数: 27 天

    [LV.4]偶尔看看III

    发表于 2016-1-4 23:04:39 | 显示全部楼层
    抢沙发,学习pe结构
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2024-1-4 14:31
  • 签到天数: 73 天

    [LV.6]常住居民II

    发表于 2016-1-4 23:59:26 | 显示全部楼层
    前排学习,占位
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2024-4-13 20:08
  • 签到天数: 2046 天

    [LV.Master]伴坛终老

    发表于 2016-1-5 06:25:02 | 显示全部楼层
    学习了呀。。。。。。PE结构和ARM结构都不太好懂呀。。。。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-2-26 11:14
  • 签到天数: 459 天

    [LV.9]以坛为家II

    发表于 2016-1-5 08:04:45 | 显示全部楼层
    在普及PE结构了啊
    PYG19周年生日快乐!
  • TA的每日心情

    2022-5-20 13:32
  • 签到天数: 235 天

    [LV.7]常住居民III

    发表于 2016-1-5 14:57:16 | 显示全部楼层
    似懂非懂,继续学习
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2020-10-6 19:00
  • 签到天数: 107 天

    [LV.6]常住居民II

    发表于 2016-1-5 17:30:21 | 显示全部楼层
    学习了,谢谢分享
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2024-3-19 08:32
  • 签到天数: 269 天

    [LV.8]以坛为家I

    发表于 2016-1-5 17:33:46 | 显示全部楼层
    学习pe结构
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表