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

作者:IBinary
出处:http://www.cnblogs.com/iBinary/
版权所有,欢迎保留原文链接进行转载:)

一丶可选头结构以及作用


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.

其中保留的没有写.

作者:IBinary
出处:http://www.cnblogs.com/iBinary/
版权所有,欢迎保留原文链接进行转载:)

PE文件格式详解,第三讲,可选头文件格式,以及节表的更多相关文章

  1. PE文件格式详解,第一讲,DOS头文件格式

    PE文件格式详解,第一讲,DOS头文件格式 今天讲解PE文件格式的DOS头文件格式 首先我们要理解,什么是文件格式,我们常说的EXE可执行程序,就是一个文件格式,那么我们要了解它里面到底存了什么内容 ...

  2. PE文件格式详解,第二讲,NT头文件格式,以及文件头格式

    PE文件格式详解,第二讲,NT头文件格式,以及文件头格式 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) PS:本篇博客 ...

  3. PE文件结构详解(二)可执行文件头

    在PE文件结构详解(一)基本概念里,解释了一些PE文件的一些基本概念,从这篇开始,将详细讲解PE文件中的重要结构. 了解一个文件的格式,最应该首先了解的就是这个文件的文件头的含义,因为几乎所有的文件格 ...

  4. PE文件格式详解(七)

    PE文件格式详解(七)   Ox00 前言 前面好几篇在讲输入表,今天要讲的是输出表和地址的是地址重定位.有了前面的基础,其实对于怎么找输出表地址重定位的表已经非常熟悉了.   0x01 输出表结构 ...

  5. BMP文件格式详解

    BMP文件格式详解(BMP file format) BMP文件格式,又称为Bitmap(位图)或是DIB(Device-Independent Device,设备无关位图),是Windows系统中广 ...

  6. PE文件详解(六)

    这篇文章转载自小甲鱼的PE文件详解系列原文传送门 之前简单提了一下节表和数据目录表,那么他们有什么区别? 其实这些东西都是人为规定的,一个数据在文件中或者在内存中的位置基本是固定的,通过数据目录表进行 ...

  7. OpenGL学习--05--纹理立方体--BMP文件格式详解(转载)

    http://blog.csdn.net/o_sun_o/article/details/8351037 BMP文件格式详解 BMP文件格式详解(BMP file format) BMP文件格式,又称 ...

  8. 音视频入门-11-PNG文件格式详解

    * 音视频入门文章目录 * PNG 文件格式解析 PNG 图像格式文件由一个 8 字节的 PNG 文件署名域和 3 个以上的后续数据块(IHDR.IDAT.IEND)组成. PNG 文件包括 8 字节 ...

  9. Android逆向之旅---SO(ELF)文件格式详解

    第一.前言 从今天开始我们正式开始Android的逆向之旅,关于逆向的相关知识,想必大家都不陌生了,逆向领域是一个充满挑战和神秘的领域.作为一名Android开发者,每个人都想去探索这个领域,因为一旦 ...

随机推荐

  1. vue2+swiper(用户操作swiper后,不能autoplay了)

    将autoplayDisableOnInteraction设置为false

  2. VS2012启用angularjs智能提示Intelligence(转)

    1. 關閉正在執行的 Visual Studio 2012 2. 開啟檔案總管,並進入以下目錄: C:\Program Files (x86)\Microsoft Visual Studio 11.0 ...

  3. poj 1523求割点

    题意:给出一个无向图,求割点以及去除这个点后图分为几部分: 思路:割点定义:去掉该点后图将分成几个部分.割点:(1)当k为根节点且有>1个分支,则去除该点后图便被分成几个分支.(2)DFN[v] ...

  4. Android学习记录:获取联系人

    在AndroidManifest中申请读取联系人的权限 <uses-permission android:name = "android.permission.READ_CONTACT ...

  5. Python并发编程协程(Coroutine)之Gevent

    Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译 ...

  6. 团队作业4——第一次项目冲刺(Alpha版本)4.28

    团队作业4--第一次项目冲刺(Alpha版本) Day seven: 会议照片 每日站立会议: 项目进展 今天是项目的Alpha敏捷冲刺的第七天,先大概整理下昨天已完成的任务以及今天计划完成的任务.今 ...

  7. 控制结构(9) 管道(pipeline)

    // 上一篇:线性化(linearization) // 下一篇:指令序列(opcode) 最近阅读了酷壳上的一篇深度好文:LINUX PID 1 和 SYSTEMD.这篇文章介绍了systemd干掉 ...

  8. 201521123044 《Java程序设计》第8周学习总结

    1. 本章学习总结 2. 书面作业 本题作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结(见注释) public static List<String> conv ...

  9. Git与码云(Git@OSC)入门-如何在实验室和宿舍同步你的代码(2)

    4. 处理冲突 4.1 向远程仓库push时无法提交成功,提示在push前应该先pull 如图所示: 有可能是因为远程仓库的版本与本地仓库的版本不一致,所以应先git pull将远程仓库的内容合并到本 ...

  10. java课程设计--WeTalk(201521123076)

    在线群聊系统 1,团队课程设计博客链接 http://www.cnblogs.com/slickghost/p/7018105.html 个人负责模块或任务说明 负责模块:总体设计及主要聊天功能实现 ...