PE文件结构分析实验

打开HxD,页面如下
研究对象为HxD.exe

观察DOS头部数据

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number: 0x5a4d
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // File address of new exe header 0x3c
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

e_magic的数值为0x5A4D,偏移量为0x0000
e_lfanew的数值为0x00000100,偏移量为0x003C

查看PE头数据

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;                        // Signature == 0x00004550, 4字节
    IMAGE_FILE_HEADER FileHeader;           // 20(0x14)字节
    IMAGE_OPTIONAL_HEADER32 OptionalHeader; // 96 + 8x16 = 224(0xE0)
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; // 0xF8

Signature(签名)数值为0x4550,偏移量为0x003C + 0x0000

FileHeader文件头和OptionalHeader可选头

typedef struct _IMAGE_FILE_HEADER {
    WORD  	Machine;  //每个CPU都拥有的唯一的Machine码,兼容32位Intel x86芯片的Machine码为14C
    WORD  	NumberOfSections; //★指出文件中存在的节区数量
    DWORD 	TimeDateStamp;
    DWORD 	PointerToSymbolTable;
    DWORD 	NumberOfSymbols;
    WORD  	SizeOfOptionalHeader; //指出结构体IMAGE_OPTIONAL_HEADER32(32位系统)的长度★
    WORD  	Characteristics; //标识文件属性,是否可运行、是否为DLL等,以bit OR形式进行组合
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

typedef struct _IMAGE_OPTIONAL_HEADER {
    WORD     Magic;  //IMAGE_OPTIONAL_HEADER32为0x10B,IMAGE_OPTIONAL_HEADER64为0x20B
    BYTE     MajorLinkerVersion;
    BYTE     MinorLinkerVersion;
    DWORD    SizeOfCode;
    DWORD    SizeOfInitializedData;
    DWORD    SizeOfUninitializedData;
    DWORD    AddressOfEntryPoint; //★RVA值,指出程序最先执行的代码起始地址
    DWORD    BaseOfCode;
    DWORD    BaseOfData;
    DWORD    ImageBase;  //★指出文件的优先装入地址(32位进程虚拟内存范围为:0~7FFFFFFF)
    DWORD    SectionAlignment; //★节区在内存中的最小单位
    DWORD    FileAlignment;    //★节区在磁盘文件中的最小单位
    WORD     MajorOperatingSystemVersion;
    WORD     MinorOperatingSystemVersion;
    WORD     MajorImageVersion;
    WORD     MinorImageVersion;
    WORD     MajorSubsystemVersion;
    WORD     MinorSubsystemVersion;
    DWORD    Win32VersionValue;
    DWORD    SizeOfImage;  //指定了PE Image在虚拟内存中所占空间的大小
    DWORD    SizeOfHeaders;
    DWORD    CheckSum;
    WORD     Subsystem;   //区分系统驱动文件和普通可执行文件
    WORD     DllCharacteristics;
    DWORD    SizeOfStackReserve;
    DWORD    SizeOfStackCommit;
    DWORD    SizeOfHeapReserve;
    DWORD    SizeOfHeapCommit;
    DWORD    LoaderFlags;
    DWORD    NumberOfRvaAndSizes;   //指定Data Directory数组的大小
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; //★数据目录数组
 } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

具体含义看官方文档
https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_file_header

关键属性

  1. Machine 计算机架构。 该字段表示PE文件执行的计算机架构环境,0x014c表示x86架构,而0x8664表示x64计算机架构环境。
    值为0x8664,偏移量为0x0104 + 0x0004
  2. NumberOfSections 节数 该字段表示在PE头部后面紧跟的“节表”的大小,也就是“节数”,在Windows环境下最大节数为96。
    值为0x0009,偏移量为0x0104 + 0x0006
  3. SizeOfOptionalHeader 可选头的大小,单位是字节。
    值为0x000F,偏移量为0x0104 + 0x0010
  4. Characteristics 镜像特性
    值为0x0023,偏移量为0x0104 + 0x0012
  5. Magic魔术字。该字段表示了文件的状态,可以使用表格 2查询其具体含义。
    值为0x020B,偏移量为0x0118 + 0x0000
    表示可执行文件映像
  6. AddressOfEntryPoint 入口地址★★★。相对于PE文件加载进入内存中,代码的起始入口地址,这个地址使用了相对地址,即相对于Image base地址的偏移地址。
    值为0x005199C0,偏移量为0x0118 + 0x0010
  7. BaseOfCode 代码节入口地址,该地址是代码节的开始位置,使用了相对地址表示。
    值为0x00001000,偏移量为0x0118 + 0x0014
  8. ImageBase 镜像基地址★★。镜像基地址就是以上叙述中提及的Image base地址,即当PE文件加载到内存中,PE文件内存中开始位置的地址。通常在PE头部中的各类地址都是相对这个地址的偏移量,所以这是其他地址的基础,称为基地址。这个地址是64K的整倍数,通常默认Windows可执行文件(EXE)使用0x00400000,动态链接库(DLL)使用0x10000000。

节区头和节区(Sections)

节区头紧跟在PE头后面

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;     //内存中节区所占大小
    } Misc;
    DWORD   VirtualAddress;          //内存中节区起始地址(RVA)
    DWORD   SizeOfRawData;           //磁盘文件中节区所占大小
    DWORD   PointerToRawData;        //磁盘文件中节区的偏移地址
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;         //节区属性(bit OR)
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

节区头从本质上就是一个表格,表格的每一行是一个IMAGE_SECTION_HEADER结构体,表格长度就是PE头中NumberOfSections字段中的数值。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇