PE文件格式详解,第三讲,可选头文件格式,以及节表

          PE文件格式详解,第三讲,可选头文件格式,以及节表

一丶可选头结构以及作用

typedef struct _IMAGE_OPTIONAL_HEADER {

    WORD    Magic;                  /*机器型号,判断是PE是32位还是64位*/
    BYTE    MajorLinkerVersion;          /*连接器版本号高版本*/
    BYTE    MinorLinkerVersion;          /*连接器版本号低版本,组合起来就是 5.12 其中5是高版本,C是低版本*/
    DWORD   SizeOfCode;               /*代码节的总大小(512为一个磁盘扇区)*/
    DWORD   SizeOfInitializedData;        /*初始化数据的节的总大小,也就是.data*/
    DWORD   SizeOfUninitializedData;       /*未初始化数据的节的大小,也就是 .data ? */
    DWORD   AddressOfEntryPoint;          /*程序执行入口(OEP) RVA(相对偏移)*/
    DWORD   BaseOfCode;               /*代码的节的起始RVA(相对偏移)也就是代码区的偏移,偏移+模块首地址定位代码区*/
    DWORD   BaseOfData;               /*数据结的起始偏移(RVA),同上*/
    DWORD   ImageBase;               /*程序的建议模块基址(意思就是说作参考用的,模块地址在哪里)*/
    DWORD   SectionAlignment;           /*内存中的节对齐*/
    DWORD   FileAlignment;             /*文件中的节对齐*/
    WORD    MajorOperatingSystemVersion;    /*操作系统版本号高位*/
    WORD    MinorOperatingSystemVersion;    /*操作系统版本号低位*/
    WORD    MajorImageVersion;          /*PE版本号高位*/
    WORD    MinorImageVersion;          /*PE版本号低位*/
    WORD    MajorSubsystemVersion;        /*子系统版本号高位*/
    WORD    MinorSubsystemVersion;        /*子系统版本号低位*/
    DWORD   Win32VersionValue;          /*32位系统版本号值,注意只能修改为4 5 6表示操作系统支持nt4.0 以上,5的话依次类推*/
    DWORD   SizeOfImage;               /*整个程序在内存中占用的空间(PE映尺寸)*/
    DWORD   SizeOfHeaders;            /*所有头(头的结构体大小)+节表的大小*/
    DWORD   CheckSum;               /*校验和,对于驱动程序,可能会使用*/
    WORD    Subsystem;              /*文件的子系统 :重要*/
    WORD    DllCharacteristics;         /*DLL文件属性,也可以成为特性,可能DLL文件可以当做驱动程序使用*/
    DWORD   SizeOfStackReserve;        /*预留的栈的大小*/
    DWORD   SizeOfStackCommit;         /*立即申请的栈的大小(分页为单位)*/
    DWORD   SizeOfHeapReserve;        /*预留的堆空间大小*/
    DWORD   SizeOfHeapCommit;         /*立即申请的堆的空间的大小*/
    DWORD   LoaderFlags;            /*与调试有关*/
    DWORD   NumberOfRvaAndSizes;       /*下面的成员,数据目录结构的项目数量*/
    IMAGE_DATA_DIRECTORY DataDirectory[16];/*数据目录,默认16个,16是宏,这里方便直接写成16*/
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

需要注意的成员:

1.PE类型

这个有宏定义了

#define IMAGE_NT_OPTIONAL_HDR32_MAGIC      0x10b    /*32位PE*/
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b    /*64位PE*/
#define IMAGE_ROM_OPTIONAL_HDR_MAGIC       0x107    /*其它,单片机*/

2丶.OEP,程序执行入口位置.

我们利用昨天写的程序,可以完成一个反调试.

思路:

1.修改OEP偏移,置为0位置处(也就是MZ的位置)

2.在MZ位置后面添加我们自己的代码

3.添加完成之后,继续跳到以前OEP的位置.

首先,看PE文件的值,OEP的偏移位置是00001008偏移,那么OD调试,看下位置在哪里.

我们知道了入口偏移是00401008位置,那么我们就知道了模块首地址是00400000

公式  00401008 - 1008 = 00400000  因为我们知道1008是相对于模块地址来的所以可以求出模块地址,我们跳转过去

可以看出,前边正好是4D5A,那么我们可以修改一下,添加自己的代码,首先4D5A正好是汇编代码

那么我们可以去平栈,然后跳转到我们以前的OEP位置.

修改成下边那样

首先,我们以前讲DOS头的时候说过,如果这个EXE文件运行在32位系统下,那么DOS头中就地一个和最后一个成员有用,那么后面我们随便修改.

上面代码很简单,首先栈平衡,然后跳转到我们以前代码执行位置.

文件中(PE)我们把后面的二进制都修改为我们的代码

入后偏移(RVA)修改为0000000

运行我们的程序,和调试我们的程序

运行程序:

可以正常运行

调试程序:

程序出错,反调试了

二丶数据目录

数据目录,主要是存放各种表格的,看下

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;        虚拟地址(表格位置)
    DWORD   Size;              大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

关于表格,这里有很多宏定义.

#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY        4   // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // Debug Directory
//      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT            12   // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   // COM Runtime descriptor

它是按照位来计算的.    

 三丶节表

在NT头下面,紧跟着的是节表

节表是什么意思? 可以理解为分区,就是几个区

那么意思就是保存了区

那么我们猜想一下,都需要什么成员

地址

地址大小

文件中的地址

文件大小

等等....

看下节表的信息吧

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;      /*在OBJ文件中使用*/
    DWORD   PointerToLinenumbers;      /*行号表位置,调试使用*/
    WORD    NumberOfRelocations;      /*在OBJ文件中使用*/
    WORD    NumberOfLinenumbers;      /*行号表的数量*/
    DWORD   Characteristics;        /*节的属性*/
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

重要成员

1.节的尺寸

2.虚拟地址,RVA(偏移)

3.文件中的大小

4.文件中的偏移

5.节的属性

其中节的属性有很多,(表达这个分区是一个什么样的分区,代码区,常量区等等)

看下宏定义(按位来的,可以看下第二讲的最后关于文件属性的讲解,其中讲解了这个怎么按位来)

#define IMAGE_SCN_CNT_CODE                   0x00000020  // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA       0x00000040  // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA     0x00000080  // Section contains uninitialized data.

#define IMAGE_SCN_LNK_OTHER                  0x00000100  // Reserved.
#define IMAGE_SCN_LNK_INFO                   0x00000200  // Section contains comments or some other type of information.
//      IMAGE_SCN_TYPE_OVER                  0x00000400  // Reserved.
#define IMAGE_SCN_LNK_REMOVE                 0x00000800  // Section contents will not become part of image.
#define IMAGE_SCN_LNK_COMDAT                 0x00001000  // Section contents comdat.
//                                           0x00002000  // Reserved.
//      IMAGE_SCN_MEM_PROTECTED - Obsolete   0x00004000
#define IMAGE_SCN_NO_DEFER_SPEC_EXC          0x00004000  // Reset speculative exceptions handling bits in the TLB entries for this section.
#define IMAGE_SCN_GPREL                      0x00008000  // Section content can be accessed relative to GP

#define IMAGE_SCN_LNK_NRELOC_OVFL            0x01000000  // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE            0x02000000  // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED             0x04000000  // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED              0x08000000  // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED                 0x10000000  // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE                0x20000000  // Section is executable.
#define IMAGE_SCN_MEM_READ                   0x40000000  // Section is readable.
#define IMAGE_SCN_MEM_WRITE                  0x80000000  // Section is writeable.

其中保留的没有写.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Objective-C

Swift-MVVM 简单演练(三)

2923
来自专栏葡萄城控件技术团队

Xamarin.Forms入门-使用 Xamarin.Forms 来创建跨平台的用户界面

Xamarin.Forms 是一个跨平台的、基于原生控件的UI工具包,开发人员可以轻松的创建适用于 Android,iOS 以及 Windows Phone的用...

4697
来自专栏hotqin888的专栏

用beego进行onlyoffice document server的二次开发

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/det...

1852
来自专栏一个会写诗的程序员的博客

Macaca 极简教程Macaca 介绍快速开始:从无到有搭建 Macaca 环境 (forMac)代码实例awesome-macaca

macaca提供的元素查找工具,可以将app视图的结构以布局结构树的格式在浏览器上展示出来,用过点击某个元素,就可以方便的查询到该控件的基本信息,以方便查找。具...

4992
来自专栏lgp20151222

debug的一些按钮意义

903
来自专栏张善友的专栏

Visual Studio 2012 和.NET Framework 4.5 快速开始的5分钟视频

观看 60 到 90 分钟的截屏视频是很困难的。如果你观看完所有的这些视频,它将花费你不到一小时的时间,而你将对 Web 开发和 Visual Studio 2...

1828
来自专栏张善友的专栏

Page.FindControl方法找不到指定控件的原因

在ASP.NET 2.0中,引入了MasterPage的机制,在当前页使用MasterPage的情况下,放在 ContentPlaceholder1这样的内容页...

2347
来自专栏iOS 开发杂谈

浅析 NSTimer 和 CADisplayLink 内存泄漏

谈论 NSTimer & CADisplayLink 内存泄漏,要理解 NSTimer & CADisplayLink 的基础概念,下面通过一个倒计时的实现的 ...

1881
来自专栏hbbliyong

WPF备忘录(2)WPF获取和设置鼠标位置与progressbar的使用方法

一、WPF 中获取和设置鼠标位置   方法一:WPF方法 Point p = Mouse.GetPosition(e.Source as Framewo...

3667
来自专栏BY的专栏

iOS定时器,你真的会使用吗?前言正文结语

5155

扫码关注云+社区

领取腾讯云代金券