• 程序员的自我修养五Windows PE/COFF


    5.1 Windows的二进制文件格式PE/COFF

    PE文件格式事实上与ELF同根同源,它们都是由COFF格式发展而来。

    5.2 PE前身——COFF

    在win下,Command Prompt for vs 2017,cd命令进入源代码所在目录:

    运行命令:

    “cl”是VISUAL C++的编译器。/c参数表示只编译,不链接,只会生成obj文件,不会生成exe文件。如下:

     如果不加这个参数,那么cl会在编译源代码后,再调用link链接器将生产的obj文件与默认的C运行库链接,生成exe文件。
    “/Za”参数禁用这些C和C++的专有扩展。
    可以使用下面命令查看obj的结构:

    /ALL参数将打印输出目标文件的所有相关信息,包括文件头,每个段的属性和段的原始数据及符号表。
    下面是打印出来的所有相关信息:

    Microsoft (R) COFF/PE Dumper Version 14.10.25019.0
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    
    Dump of file SimpleSection.obj
    
    File Type: COFF OBJECT
    
    FILE HEADER VALUES
    14C machine (x86)
    5 number of sections
    5960849C time date stamp Sat Jul 8 15:07:08 2017
    1F4 file pointer to symbol table
    14 number of symbols
    0 size of optional header
    0 characteristics
    
    SECTION HEADER #1
    .drectve name
    0 physical address
    0 virtual address
    18 size of raw data
    DC file pointer to raw data (000000DC to 000000F3)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    100A00 flags
    Info
    Remove
    1 byte align
    
    RAW DATA #1
    00000000: 20 20 20 2F 44 45 46 41 55 4C 54 4C 49 42 3A 22 /DEFAULTLIB:"
    00000010: 4C 49 42 43 4D 54 22 20 LIBCMT"
    
    Linker Directives
    -----------------
    /DEFAULTLIB:LIBCMT
    
    SECTION HEADER #2
    .debug$S name
    0 physical address
    0 virtual address
    74 size of raw data
    F4 file pointer to raw data (000000F4 to 00000167)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    42100040 flags
    Initialized Data
    Discardable
    1 byte align
    Read Only
    
    RAW DATA #2
    00000000: 04 00 00 00 F1 00 00 00 67 00 00 00 29 00 01 11 ....?...g...)...
    00000010: 00 00 00 00 44 3A 5C 53 69 6D 70 6C 65 53 65 63 ....D:SimpleSec
    00000020: 74 69 6F 6E 5C 53 69 6D 70 6C 65 53 65 63 74 69 tionSimpleSecti
    00000030: 6F 6E 2E 6F 62 6A 00 3A 00 3C 11 00 22 00 00 07 on.obj.:.<.."...
    00000040: 00 13 00 0A 00 BB 61 00 00 13 00 0A 00 BB 61 00 .....?a......?a.
    00000050: 00 4D 69 63 72 6F 73 6F 66 74 20 28 52 29 20 4F .Microsoft (R) O
    00000060: 70 74 69 6D 69 7A 69 6E 67 20 43 6F 6D 70 69 6C ptimizing Compil
    00000070: 65 72 00 00 er..
    
    SECTION HEADER #3
    .data name
    0 physical address
    0 virtual address
    C size of raw data
    168 file pointer to raw data (00000168 to 00000173)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    C0300040 flags
    Initialized Data
    4 byte align
    Read Write
    
    RAW DATA #3
    00000000: 54 00 00 00 25 64 0A 00 55 00 00 00 T...%d..U...
    
    SECTION HEADER #4
    .text$mn name
    0 physical address
    0 virtual address
    4E size of raw data
    174 file pointer to raw data (00000174 to 000001C1)
    1C2 file pointer to relocation table
    0 file pointer to line numbers
    5 number of relocations
    0 number of line numbers
    60500020 flags
    Code
    16 byte align
    Execute Read
    
    RAW DATA #4
    00000000: 55 8B EC 8B 45 08 50 68 00 00 00 00 E8 00 00 00 U.ì.E.Ph....è...
    00000010: 00 83 C4 08 5D C3 CC CC CC CC CC CC CC CC CC CC ..?.]?ìììììììììì
    00000020: 55 8B EC 83 EC 08 C7 45 FC 01 00 00 00 A1 00 00 U.ì.ì.?Eü....?..
    00000030: 00 00 03 05 00 00 00 00 03 45 FC 03 45 F8 50 E8 .........Eü.E?Pè
    00000040: 00 00 00 00 83 C4 04 8B 45 FC 8B E5 5D C3 .....?..Eü.?]?
    
    RELOCATIONS #4
    Symbol Symbol
    Offset Type Applied To Index Name
    -------- ---------------- ----------------- -------- ------
    00000008 DIR32 00000000 A $SG1535
    0000000D REL32 00000000 F _printf
    0000002E DIR32 00000000 B ?static_var@?1??main@@9@9 (`main'::`2'::static_var)
    00000034 DIR32 00000000 13 ?static_var2@?1??main@@9@9 (`main'::`2'::static_var2)
    00000040 REL32 00000000 E _func1
    
    SECTION HEADER #5
    .bss name
    0 physical address
    0 virtual address
    4 size of raw data
    0 file pointer to raw data
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    C0300080 flags
    Uninitialized Data
    4 byte align
    Read Write
    
    COFF SYMBOL TABLE
    000 010461BB ABS notype Static | @comp.id
    001 80000191 ABS notype Static | @feat.00
    002 00000000 SECT1 notype Static | .drectve
    Section length 18, #relocs 0, #linenums 0, checksum 0
    004 00000000 SECT2 notype Static | .debug$S
    Section length 74, #relocs 0, #linenums 0, checksum 0
    006 00000000 SECT3 notype Static | .data
    Section length C, #relocs 0, #linenums 0, checksum AC5AB941
    008 00000000 SECT3 notype External | _global_init_var
    009 00000004 UNDEF notype External | _global_uninit_var
    00A 00000004 SECT3 notype Static | $SG1535
    00B 00000008 SECT3 notype Static | ?static_var@?1??main@@9@9 (`main'::`2'::static_var)
    00C 00000000 SECT4 notype Static | .text$mn
    Section length 4E, #relocs 5, #linenums 0, checksum CC61DB94
    00E 00000000 SECT4 notype () External | _func1
    00F 00000000 UNDEF notype () External | _printf
    010 00000020 SECT4 notype () External | _main
    011 00000000 SECT5 notype Static | .bss
    Section length 4, #relocs 0, #linenums 0, checksum 0
    013 00000000 SECT5 notype Static | ?static_var2@?1??main@@9@9 (`main'::`2'::static_var2)
    
    String Table Size = 0x5D bytes
    
    Summary
    
    4 .bss
    C .data
    74 .debug$S
    18 .drectve
    4E .text$mn
    View Code
    COFF文件结构

    COFF的文件头部包括两部分,一个是描述文件总体结构和属性的映像头,另一个是描述该文件中包含的段属性的段表
    映像:因为PE文件再装载时被直接映射到进程的虚拟空间中运行,它时进程的虚拟空间的映像。所以PE可执行文件很多时候被叫做映像文件

    文件头里描述COFF文件总体属性的映像头是一个”IMAGE_FILE_HEADER”的结构,相当于ELF中”Elf32_Ehdr”结构。

    上面目标文件中这部分与这个结构对应:

    File Type: COFF OBJECT
    
    FILE HEADER VALUES
    14C machine (x86)//目标机器类型
    5 number of sections//PE中所含段的数量
    5960849C time date stamp Sat Jul 8 15:07:08 2017//PE文件创建时间
    1F4 file pointer to symbol table//符号表在PE文件中的位置
    14 number of symbols
    0 size of optional header//optional header的大小,这个结构只存在PE可执行文件中,COFF文件中不存在
    0 characteristics

    COFF OBJECT也就是COFF目标文件格式。
    映像头后面就是COFF文件的段表,它是一个类型”IMAGE_SECTION_HEADER”结构数组,数组里面每一个元素代表一个段,这个结构和ELF文件中的”Elf32——Shdr”很相似。

    5.3 链接指示信息

    上面目标文件中”.drectve”内容:

    SECTION HEADER #1
    .drectve name
    0 physical address
    0 virtual address
    18 size of raw data
    DC file pointer to raw data (000000DC to 000000F3)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    100A00 flags //标准位,即"IMAGE_SECTION_HEADERS"里面的Characteristics成员。
    Info
    Remove
    1 byte align//这三个组合属性表示该段时信息段,并非程序数据
    
    RAW DATA #1//该段在文件中的原始数据
    00000000: 20 20 20 2F 44 45 46 41 55 4C 54 4C 49 42 3A 22 /DEFAULTLIB:"
    00000010: 4C 49 42 43 4D 54 22 20 LIBCMT" //dumpbin对该段进行解析后的结果,它就是"cl"编译器希望传递给"link"链接器的参数,它表示VC的静态链接的多线程C库。
    
    Linker Directives
    -----------------
    /DEFAULTLIB:LIBCMT

    它的内容时编译器传给链接器的指令。

    5.4 调试信息

    COFF文件中所有以”.debug”开始的段都包含着调试信息。

    • “.debug$S”表示包含的是符号相关的调试信息。
    • “.debug$P”表示包含的是预编译头文件相关的调试信息。
    • “.debug$T”表示包含的是类型相关的调试信息。

    调试信息段具体格式被定义在PE格式文件标准中。

    SECTION HEADER #2
    .debug$S name
    0 physical address
    0 virtual address
    74 size of raw data
    F4 file pointer to raw data (000000F4 to 00000167)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    42100040 flags
    Initialized Data
    Discardable
    1 byte align
    Read Only
    
    RAW DATA #2
    00000000: 04 00 00 00 F1 00 00 00 67 00 00 00 29 00 01 11 ....?...g...)...
    00000010: 00 00 00 00 44 3A 5C 53 69 6D 70 6C 65 53 65 63 ....D:SimpleSec
    00000020: 74 69 6F 6E 5C 53 69 6D 70 6C 65 53 65 63 74 69 tionSimpleSecti
    00000030: 6F 6E 2E 6F 62 6A 00 3A 00 3C 11 00 22 00 00 07 on.obj.:.<.."...
    00000040: 00 13 00 0A 00 BB 61 00 00 13 00 0A 00 BB 61 00 .....?a......?a.
    00000050: 00 4D 69 63 72 6F 73 6F 66 74 20 28 52 29 20 4F .Microsoft (R) O
    00000060: 70 74 69 6D 69 7A 69 6E 67 20 43 6F 6D 70 69 6C ptimizing Compil
    00000070: 65 72 00 00

    5.5 符号表

    COFF符号表的内容基本和ELF文件的符号表一样,主要是符号名。符号的类型,所在的位置

    COFF SYMBOL TABLE //符号编号 符号大小 符号所在位置 符号类型,只有两种notype和notype() 符号可见范围 符号名
    000 010461BB ABS notype Static | @comp.id //ABS表示符号是个绝对值,不存在任何段中
    001 80000191 ABS notype Static | @feat.00 //notype 变量和其他符号
    002 00000000 SECT1 notype Static | .drectve //表示符号所表示的对象定义在本COFF文件的第一个段中
    Section length 18, #relocs 0, #linenums 0, checksum 0
    004 00000000 SECT2 notype Static | .debug$S //Static局部变量,只有目标文件中可见
    Section length 74, #relocs 0, #linenums 0, checksum 0
    006 00000000 SECT3 notype Static | .data
    Section length C, #relocs 0, #linenums 0, checksum AC5AB941
    008 00000000 SECT3 notype External | _global_init_var //External全局变量,可以被其他目标文件引用
    009 00000004 UNDEF notype External | _global_uninit_var //表示符号未定义,即这个符号被定义在其他目标文件中
    00A 00000004 SECT3 notype Static | $SG1535
    00B 00000008 SECT3 notype Static | ?static_var@?1??main@@9@9 (`main::`2::static_var)
    00C 00000000 SECT4 notype Static | .text$mn
    Section length 4E, #relocs 5, #linenums 0, checksum CC61DB94
    00E 00000000 SECT4 notype () External | _func1 //notype ()函数
    00F 00000000 UNDEF notype () External | _printf
    010 00000020 SECT4 notype () External | _main
    011 00000000 SECT5 notype Static | .bss
    Section length 4, #relocs 0, #linenums 0, checksum 0
    013 00000000 SECT5 notype Static | ?static_var2@?1??main@@9@9 (`main::`2::static_var2)

    5.6 Windows下的ELF——PE

    PE文件是基于COFF的扩展,它比COFF文件多几个结构,最主要变化:

    • 文件最开始的部分不是COFF文件头,而是DOS MZ可执行文件格式的文件头和桩代码
    • 原来的COFF文件头中的”IMAGE_FILE_HEADER”部分扩展成PE文件文件头结构”IMAGE_NT_HEADERS”,这个结构包括原来的”Image Header”及新增的PE扩展头部结构
  • 相关阅读:
    剑指OFFER----面试题37. 序列化二叉树
    剑指OFFER----面试题36. 二叉搜索树与双向链表
    剑指OFFER----面试题35. 复杂链表的复制
    6.深拷贝与浅拷贝
    DevExpress ASP.NET v19.1版本亮点:发布全新的Gantt控件
    MFC界面库BCGControlBar v30.1新功能详解:Dialogs和Forms
    Kendo UI for jQuery使用教程:支持Web浏览器
    DevExpress Windows 10 v19.1新版亮点:UWP控件新功能全面解析
    Java 11必掌握的8大特性,完美代码信手拈来
    Kendo UI for jQuery使用教程:入门指南
  • 原文地址:https://www.cnblogs.com/Tan-sir/p/7447203.html
Copyright © 2020-2023  润新知