[手机系统] PE文件结构详解(DOS头/NT头/节表/导入表)使用010 Editor手动解析notepad

563 0
Honkers 2025-3-3 16:11:09 | 显示全部楼层 |阅读模式

一:DOS部分

DOS部分分为DOS MZ文件头和DOS块,其中DOS MZ头实际是一个64位的IMAGE_DOS——HEADER结构体。

DOS MZ头部结构体的内容如下,我们所需要关注的是前面两个字节(e_magic)和后面四个字节(e_lfanew)

  1. typedef struct _IMAGE_DOS_HEADER
  2. {
  3. WORD e_magic; // DOS头的标识 "MZ" 4Dh 5Ah(2个字节) #define IMAGE_DOS_SIGNATURE 0x5A4D
  4. WORD e_cblp; // 文件最后一页中的字节数
  5. WORD e_cp; // 文件中的全部页数
  6. WORD e_crlc; // 重定位表中的指针数
  7. WORD e_cparhdr; // 头部尺寸,以段落为单位
  8. WORD e_minalloc; // 所需的最小附加段
  9. WORD e_maxalloc; // 所需的最大附加段
  10. WORD e_ss; // 初始的SS值(相对偏移量)
  11. WORD e_sp; // 初始的SP值
  12. WORD e_csum; // 补码校验值
  13. WORD e_ip; // 初始的IP值
  14. WORD e_cs; // 初始的CS值
  15. WORD e_lfarlc; // 重定位表的字节偏移量
  16. WORD e_ovno; // 覆盖号
  17. WORD e_res[4]; // 保留字
  18. WORD e_oemid; // OEM 标识符(相对e_oeminfo)
  19. WORD e_oeminfo; // OEM 信息
  20. WORD e_res2[10]; // 保留字
  21. // DosHeader + 0x3C 正好定位到e_lfanew
  22. LONG e_lfanew; // NT头相对于文件起始地址的偏移, 4字节, 指示NT头的位置
  23. } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
复制代码

二、PE文件头

PE文件头可以分为三个部分,分别为PE标识、标准PE头、扩展PE头,结构体内容如下所示

  1. typedef struct _IMAGE_NT_HEADERS {
  2. DWORD Signature; ``// PE标识--4字节
  3. IMAGE_FILE_HEADER FileHeader; ``// 标准PE头--20字节
  4. IMAGE_OPTIONAL_HEADER32 OptionalHeader; ``// 扩展PE头--224字节/240字节
  5. } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
复制代码

现在我们详细解释一下标准PE头,标准PE头的结构体如下:

  1. typedef struct _IMAGE_FILE_HEADER
  2. {
  3. WORD Machine; //PE文件运行的平台,值为IMAGE_FILE_MACHINE_I386(0x14c)表示是x86处理器,
  4. //IMAGE_FILE_MACHINE_AMD64(0x8664)或IMAGE_FILE_MACHINE_IA64(0x200)表示是x64处理器。
  5. WORD NumberOfSections; //文件中存在的节的个数,如果想在PE文件中增加或删除节,必须变更此处的值
  6. DWORD TimeDateStamp; //创建此文件时的时间戳
  7. DWORD PointerToSymbolTable; //COFF符号表的文件偏移,对于映像文件来说,此值为0
  8. DWORD NumberOfSymbols; //符号表中元素的数目,对于映像文件来说,此值为0
  9. WORD SizeOfOptionalHeader; //可选头的大小,32位下默认为00E0h,64位下默认为00F0h
  10. WORD Characteristics; //文件属性标志,exe一般是010fh,dll一般是210eh
  11. } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
复制代码

现在我们得到:

那什么是PE文件属性呢,现在我们知道PE文件属性的十六进制值是00 22(倒序读取),那么可以得到二进制是0001 0110

对应下面的表,也就是第1位、第二位和第四位对应数字为1得到的属性值

对于扩展PE头,大小有标准PE头的SizeOfOptionalHeader决定,就是00F0

三、节表

每个节表的固定大小是40字节,节表不止一个,可能有多个,节表的数量是标准PE头中的NumberOfSections属性决定的,虽然节表有多个,但是每个节表中的结构是相同的。

根据上面的标准头解析,可以看到是六个节表(00 06),每个节表大小是40字节,一共是240字节,如下图

每个节表的最后四个字节是属性,这里是60 00 00 20,可以得到二进制是0110 0000 0000 0000 0000 0000 0010 0000

那么就可以得到:

利用工具打开,可以发现是六个节表

以下是节表的基本结构

  1. typedef struct _IMAGE_SECTION_HEADER {
  2. 0x00 BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //00 00 00 74 78 65 74 2E 8字节,节表的名字,一般情况下"\0"来结束,内容可以自己定义
  3. union {
  4. 0x08 DWORD PhysicalAddress;
  5. 0x08 DWORD VirtualSize;
  6. } Misc; //00 01 80 6C 双字,是该节在没有对齐前的真是尺寸,内容可以不准确
  7. 0x0c DWORD VirtualAddress; //00 00 10 00 节区在内存中的偏移地址
  8. 0x10 DWORD SizeOfRawData; //00 01 82 00 节在文件中对齐后的尺寸
  9. 0x14 DWORD PointerToRawData; //00 00 04 00 节区在文件中的偏移
  10. 0x18 DWORD PointerToRelocations; //00 00 00 00 在exe文件中无意义
  11. 0x1c DWORD PointerToLinenumbers; //00 00 00 00 在exe文件中无意义
  12. 0x20 WORD NumberOfRelocations; //00 00 在exe文件中无意义
  13. 0x22 WORD NumberOfLinenumbers; //00 00 该节在行号表中的行号数
  14. 0x24 DWORD Characteristics; //60 00 00 20 节的属性
  15. };
复制代码

 四、节数据

查看区段:

我们需要的是节区在文件中的偏移,就是在20字节之后的00000400,节区的大小是在16字节之后的,也就是0046FE00

 也就是00000400之后的数据:

以上就是最基本的PE文件结构了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

特级红客

关注
  • 3281
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行