飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 9261|回复: 13

[分享] 菜鸟的PE结构学习之路(三) 初步解析PE头

[复制链接]
  • TA的每日心情
    开心
    2015-8-2 16:07
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-9-28 16:37:39 | 显示全部楼层 |阅读模式
    本帖最后由 F8LEFT 于 2014-10-7 13:06 编辑

          菜鸟在此,大牛飞过~~~~~~~
          以上仅为个人的一点小小的心得,有什么不对的地方还请各位指出。
            这次我继续来解析PE头,结构非常的多,不过作用基本上可以从名字上面去看出来,因此实际上没有想象中的困难。
             那么,下面正式开始:

    ----------------------------------请叫我分割线-------------------------------------分割线-----------------------------------

           鉴于PE头的成员比较多,所以我就不全部介绍呵,就挑重要的部分来讲吧(绝对不是因为懒~~~)。
           惯例先讲一点小知识,这次来讲标志位。
           我想定义一个区段,并给区段赋予几个属性,因此我定义了一个结构
    struct  SectionCharacteristics {
            bool HasCode;                        //含可执行代码
            bool HasData;                        //含有数据
            bool Read;                                //可读
            bool Write;                                //可写
    };
           很简单的结构呵。接着,我发现一个问题了,就是空间非常的浪费。假如这4个数据全部为真的时候,内存中是这样的: 0x01, 0x01, 0x01, 0x01。转换为二进制位就是:00000001, 00000001, 00000001, 00000001。看啊,每个字节,就只有一个位是被用到的。于是我把这几个属性压缩到一个字节中: 00001111,完全可以达到想要的效果,同时又节省了空间,这想法挺棒的。
           咦,等等,这又遇到了问题。问题就是这些数据不容易提取啊。这也是可以解决的。比如说,我想提取第3位数据,我就这样 data & 00000100,如果结果不为0的话,那么第3位就是1了。想修改也容易: 写0:data = data & ~00000100,写1: data = data | 00000100;

          来,继续讲解PE吧。先来看一下IMAGE_FILE_HEADER的数据:
    1.jpg
          首先头4个字节为PE标志,”PE\0\0”
          先给出IMAGE_FILE_HEADER的定义
    typedef struct _IMAGE_FILE_HEADER {
        WORD    Machine;                       //运行平台
        WORD    NumberOfSections;              //PE中节的数量
        DWORD   TimeDateStamp;                                   //文件创建日期和时间
        DWORD   PointerToSymbolTable;                   //指向符号表(用于调试)
        DWORD   NumberOfSymbols;                           //符号表中的符号数量(用于调试)
        WORD    SizeOfOptionalHeader;                   //扩展头结构的长度
        WORD    Characteristics;                           //文件属性
    } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
          这样就基础知识就差不多了,下面来逐个解析。

    Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

                                               |PE - Start|  Signature       | Machine  | NumberOfSections
    000000C0   00 00 00 00 00 00 00 00 |  50 45 00 00  |  4C 01    | 04 00   
                                                |PE - Start|幻数”PE\0\0”  | 运行平台 | 节数
                    TimeDataStamp| P~S~Table   | N~O~Symbols | S~O~H | Characteristics
    000000D0   81 7E 73 4D | 00 00 00 00 | 00 00 00 00     | E0 00    | 0F 01    
                            时间戳     | 指向符号表  | 符号数量           | 扩展头  | 文件属性
           解析一下较为重要的部分:
    Signature: 幻数 “PE\0\0”,是PE头的开始标志。
    NumberOfSections: 节的数目,就是在PEID中看到的区段的数目了
    TimeDataStamp: 时间戳,是自1970.1.1 到 文件建立时间经过的秒数
    SizeOfOptionalHeader: 扩展头长度,标志下一个头(IMAGE_OPTIONAL_HEADER)的大小。
    Characteristics: 描述PE文件的属性,可以由多个标志位进行组合,注意的是,这字段并不是描述文件的隐藏,只读之类的属性的。。。

          接着是下一个头,IMAGE_OPTIONAL_HEADER。这里我就直接借用WindowsPE权威指南里面的图了,里面说明非常的详细。比我做的要好多了。定义比较长,估计给出了也没有人会看,具体可以参考我的程序代码。来,直接上截图:
    2.jpg

           可以看到,这个扩展头给出了程序启动的基本的信息,有PE类型、代码段大小,数据段大小、建议装入基址、程序入口RVA。在最后还有一个叫数据目录的信息,是非常重要的,这里我没有截图出来,将放在下一次讲解。

          那么这次就到此为止了,代码我会给出,就当做是国庆节给大家的礼物了,虽然可能有点乱就是了。

          最后补一下IMAGE_OPTIONAL_HEADER的定义:
    1. typedef struct _IMAGE_OPTIONAL_HEADER {
    2.     //
    3.     // Standard fields.
    4.     //

    5.     WORD    Magic;         //幻数107h = ROM Image,10Bh = exe Image
    6.     BYTE    MajorLinkerVersion;         //链接器版本号
    7.     BYTE    MinorLinkerVersion;
    8.     DWORD   SizeOfCode;         //所有含代码的节的总大小
    9.     DWORD   SizeOfInitializedData;         //所有含已初始化数据的节的总大小
    10.     DWORD   SizeOfUninitializedData;        //所有含未初始化数据的节的大小
    11.     DWORD   AddressOfEntryPoint;         //程序执行入口RVA
    12.     DWORD   BaseOfCode;         //代码的节的起始RVA
    13.     DWORD   BaseOfData;         //数据的节的起始RVA

    14.     //
    15.     // NT additional fields.
    16.     //

    17.     DWORD   ImageBase;         //程序的建议装载地址
    18.     DWORD   SectionAlignment;         //内存中的节的对齐粒度
    19.     DWORD   FileAlignment;         //文件中的节的对齐粒度
    20.     WORD    MajorOperatingSystemVersion;//操作系统版本号
    21.     WORD    MinorOperatingSystemVersion;
    22.     WORD    MajorImageVersion;         //该PE的版本号
    23.     WORD    MinorImageVersion;
    24.     WORD    MajorSubsystemVersion;         //所需子系统的版本号
    25.     WORD    MinorSubsystemVersion;
    26.     DWORD   Win32VersionValue;         //未用
    27.     DWORD   SizeOfImage;         //内存中的整个PE映像尺寸
    28.     DWORD   SizeOfHeaders;         //所有头 + 节表的大小
    29.     DWORD   CheckSum;         //校验和
    30.     WORD    Subsystem;         //文件的子系统
    31.     WORD    DllCharacteristics;         //DLL文件特性
    32.     DWORD   SizeOfStackReserve;         //初始化时的栈大小
    33.     DWORD   SizeOfStackCommit;         //初始化时实际提交的栈大小
    34.     DWORD   SizeOfHeapReserve;         //初始化时保留的堆大小
    35.     DWORD   SizeOfHeapCommit;         //初始化时实际提交的堆大小
    36.     DWORD   LoaderFlags;         //与调试有关
    37.     DWORD   NumberOfRvaAndSizes;         //下面的数据目录结构的项目数量
    38.     IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];        //数据目录
    39. } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
    复制代码




    EasyPE V0.20.zip

    155.56 KB, 阅读权限: 30, 下载次数: 3, 下载积分: 飘云币 -2 枚

    源码

    评分

    参与人数 1威望 +20 飘云币 +20 收起 理由
    冷月孤心 + 20 + 20 很给力!

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2025-1-4 10:11
  • 签到天数: 490 天

    [LV.9]以坛为家II

    发表于 2014-9-29 08:49:01 | 显示全部楼层
    对PE一窍不通的路过
    PYG19周年生日快乐!
  • TA的每日心情
    难过
    2023-5-16 11:00
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2014-11-4 13:36:22 | 显示全部楼层
    基本不够,越看越晕。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2015-9-18 09:23
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2015-1-22 09:04:50 | 显示全部楼层
    学习一下,感谢分享了
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2015-1-25 10:21:27 | 显示全部楼层
    PE头好难。。有点看不懂
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2018-11-13 00:00
  • 签到天数: 25 天

    [LV.4]偶尔看看III

    发表于 2015-1-31 08:33:22 | 显示全部楼层
    谢谢分享。下载收藏
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2015-2-1 22:16:05 | 显示全部楼层
    不错的教程,支持
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2015-2-7 20:08:26 | 显示全部楼层
    PYG有你更精彩!

    评分

    参与人数 1飘云币 -120 收起 理由
    冷月孤心 -120 禁止复制粘贴,不是我看不到你,是你自己不尊.

    查看全部评分

    PYG19周年生日快乐!

    该用户从未签到

    发表于 2015-2-25 15:29:51 | 显示全部楼层
    必须支持一下

    评分

    参与人数 1飘云币 -120 收起 理由
    冷月孤心 -120

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2023-12-30 18:00
  • 签到天数: 82 天

    [LV.6]常住居民II

    发表于 2015-3-4 00:32:40 | 显示全部楼层
    写的不错啊,辛苦辛苦
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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