关于PE文件结构的问题! 如何用VC++读出PE文件的结构及各部分内容!提供有用资料者也给分! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 看看Windows核心编程的22章里面有一些,然后就是在线的MSDN里面有一些 1、PE文件格式的背景和由来: 在开始介绍PE结构之前,有必要向读者提一提常用的PE文件结构分析工具:Win32SDK提供的 DUMPBIN 可以转储PE文件和COFF OBJ/LIB 文件;Borland 的使用者可用TDUMP观察PE 文件,但TDUMP 不支持COFF OBJ。2、PE文件的顺序结构:我们可以把PE的内存映象结构用下面的图示简要的表示出来:DOS MZ HEADER DOS STUBPEHeader Signature(“PE\0\0”) FileHeader OptionalHeaderSection Table(array of IMAGE_SECTION_HEADER).text.data.edata.idata.reloc…COFF Line NumberCOFF SymbolsCode View Debug Information 2. 1、DOS header 和 DOS Stub:所有的 PE 文件(或32位的DLLS)都必须以一个简单的DOS MZheader为起始(IMAGE_DOS_HEADER结构体)。在实际中,除了e_lfanew(PE header 的文件偏移量)我们可以不必太关心其余成员数据。DOS Stub只是提供了PE文件在DOS下执行时,DOS会把它当作有效的执行文件而顺利执行。通常会在屏幕上输出 " This programcannot run in DOS mode " 之类的提示语。程序员也可以改变DOS Stub,根据自己的意图实现完整的 DOS代码。2. 2、PE Header:PE表头内含程序代码和各种资料的大小位置、适用的操作系统、堆栈(stack)最初大小等等重要信息。犹如执行文件的纲目。整个PE Header 是一个IMAGE_NT_HEADERS结构体,在Win32 SDK中定义如下:typedef struct _IMAGE_NT_HEADERS { DWORD Signature; \\PE标记,值为50h, 45h, 00h, 00h(ASCII:”PE\0\0”) IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader;} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;PE Signature为校验标记,由连接器产生。通常装载器通过指向此位的指针e_lfanew(DOS header中)来检验此文件是否为PE格式。FileHeader域包含了关于PE文件物理分布的一般信息,opionalHeader域包含了关于PE文件逻辑分布的信息。显然可以pNTHeader = dosHeader +dosHeader->e_lfanew获得pe头的地址。2.2.1、File Header 结构域:在Win32 SDK中 File Header 定义如下:typedef struct _IMAGE_FILE_HEADER {WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD ;} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;各个成员的说明列表如下:成 员 说 明Machine 该文件运行所要求的CPU。对于Intel平台,该值是IMAGE_FILE_MACHINE_I386(14Ch)。NumberOfSections 文件的节数目。如果我们要在文件中增加或删除一个节,就需要修改这个值。TimeDateStamp 连接器创建文件时刻。从1969/12/31 4:00 P.M. 之后的总秒数。PointerToSymbolTable COFF 符号表格的偏移位置,用于调试。NumberOfSymbols COFF 符号表格中符号的个数,用于调试。SizeOfOptionalHeader 指示紧随本结构之后的 OptionalHeader 结构大小,必须为有效值。Characteristics 关于文件信息的标记,比如文件是 exe(0x0002) 还是 dll(0x2000)在实际应用中,有三个域对我们有用: NumberOfSections ,SizeOfOptionalHeader 和Characteristics。我们通常不会改变 SizeOfOptionalHeader 和Characteristics 的值,如果要遍历节表就得使用 NumberOfSections。2. 2。2、Option Header结构域:这是PE表头的第三个成分。对于PE文件而言,这一部分其实并不是可有可无。因为COFF格式允许不同的设计者在标准的File header之后定义一个结构。Optional header 正是PE设计者认为在基本的File header 信息之外还需要的一些重要的信息。完整的结构定义可以参考Win32 SDK中的WINNT.H头文件,这里列举了其中的重要成员:成员 说 明AddressOfEntryPoint PE装载器准备运行的PE文件的第一个指令的RVA。若要改变整个执行的流程,可以将该值指定到新的RVA,这样新RVA处的指令首先被执行。ImageBase PE文件的优先装载地址。如果该值是400000h,PE装载器将尝试把文件装到虚拟地址空间的400000h处。若该地址区域已被其他模块占用,那PE装载器会选用其他空闲地址,这个过程我们把它叫做重定位。SectionAlignment 内存中节对齐的粒度(granularity)。一旦装载到内存中,每个节(section)保证从一个此值的倍数的虚拟地址开始。如果该值是4096 (1000h),那么每节的起始地址必须是4096的倍数。FileAlignment 文件中节对齐的粒度。文件中组成每个section的原始数据(raw data)保证是从一个此值的倍数的虚拟地址开始。如果该值是(200h),,那么每节的起始地址必须是512的倍数。MajorSubsystemVersionMinorSubsystemVersion win32子系统版本。若PE文件是专门为Win32设计的,该子系统版本必定是4.0否则不会有3维立体感对话框等。SizeOfImage 内存中整个PE映像体(map)的尺寸。它是所有头和节经过节对齐处理后的大小。SizeOfHeaders 所有头+节表的大小,也就等于文件尺寸减去文件中所有节的尺寸。可以以此值作为PE文件第一节的文件偏移量。Subsystem NT用来识别PE文件属于哪个子系统。 对于大多数Win32程序,只有两类值:Windows GUI 和 Windows CUI (控制台)。DataDirectory IMAGE_DATA_DIRECTORY 结构数组。每个结构给出一个重要数据结构的RVA,比如引入地址表等。在PE header中,有很多地址指针是用RVA来表示的。 RVA 代表相对虚拟地址(RelativeVirtual Address)。简言之,RVA是虚拟空间中到参考点的一段距离,类似文件偏移量。当然它是相对虚拟空间里的一个地址,而不是文件头部。举例来说,如果PE文件装入虚拟地址(VA)空间的400000h处,且进程从虚址401000h开始执行,我们可以说进程执行起始地址在RVA 1000h。每个RVA都是相对于模块的起始VA(Virtual Address)而言的。2.2.3、Option Header 的中的重要数据成员 Data Directory:Data Directory 定义为IMAGE_DATA_DIRECTORY结构体数组,每个数组元素给出一个重要数据结构的RVA(Relative Visual Address 相对虚地址),比如引入表地址、重定位表地址。通常共16个成员。(详细的宏定义请参阅WIN32 SDK 的WINNT.H 头文件)这个数组起到让装载器迅速的在内存中找到特定的节(section)的作用,减去了遍历节表的麻烦。2. 3、Section Header:紧接在PE header 的是section table(IMAGE_SECTION_HEADER) 。每个表项包含有该节的属性、偏移量等。如果PE文件里有3节,那么此数据结构就有3个元素。为了更好的理解PE header 和Section header 在PE文件中的组织关系,我们可以把PE文件看作一逻辑磁盘,PE header是boot扇区而sections是各种文件,节表视为逻辑磁盘中的根目录。节表定义如下:typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics;} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 重要成员的说明列表如下:成员 说 明Name 节名。长度不超过8字节。仅仅是个标记而已,注意这里不用null结束。VirtualAddres 本节的RVA(相对虚拟地址)。PE装载器将节映射至内存时会读取本值。如果域值是1000h,而PE文件装在地址400000h处,那么本节就被载到401000h。SizeOfRawData 经过文件对齐处理后节尺寸,PE装载器提取本域值了解需映射入内存的节字节数。PointerToRawData 这是节基于文件的偏移量,PE装载器通过本域值找到节数据在文件中的位置。Characteristics 包含标记以指示节属性,比如节是否含有可执行代码、初始化数据、未初始数据,是否可写、可读等。2.4、Section 域节(section)是PE文件真正内容的划分。每一节是是拥有共同属性的数据的集合。每节都有相应的命名,不过这个命名不是太重要,只要是相同属性的内容都可以放进一节,命名只是便于识别。下面重点介绍一下一些重要的段。2.4.1、text section 此节一般包含有连接器连接的所有obj目标文件的执行代码。这个执行代码块是一个大的.text。不同于在DOS下面的执行文件可以分成几部分。如果是使用的Borland C++,其编译器将产生的代码存于名为CODE的区域,连接器连接到名为CODE而不是.text的节中。2.4.2、data section .data是初始化的数据块。这些数据块包括编译时被初始化的字符串常量、全局(globle)和静态(static)变量。2.4.3、bss section 任何没有初始化的全局和局部变量都会存放到.bss节中。这个节并不占用文件的储藏空间,所以 RawDataOffset 总是为0。2.4.4、rsrc section 该节包含模块的全部资源。如图标、菜单、位图等等。2.4.5、idata section .idata包含其他外来的如DLL中的函数及数据信息。PE文件的每一个输入函数都明确的列于该节中。2.4.6、edata section 与.idata对应,.edata是该PE文件输出函数和数据的列表,以供其他模块引用。有的PE文件没有引出函数或数据,也就没有该节。3、其余部分: 在节(Sections)的后面是COFF符号表格、COFF调试信息、COFF行号信息。这些域对我们的作用不大,有兴趣的读者可参阅其他书籍。4、PE文件的装载过程: 通常 这有个程序源代码~http://www.vckbase.com/code/downcode.asp?id=1205 在msdn里有一段技术文章。http://61.153.195.10:8080/list.asp?part1=1&part2=5这里讲的很详细。 文件格式汇编http://www.csdn.net/dev/format/ 谁有资源节的资料,给我发一份:[email protected],谢谢~ 我毕业设计的题目是windows平台下文件的加密与解密。打算用VC++来做。所以要多了解一些相关的资料,首先就是了解PE文件格式,有其他关于这个主题的资料,也希望能告诉我。先谢谢各位了! 你的EMail.我这有篇关于这个的论文,不过没有源码~ [email protected]也给我一份.谢谢先 《Win32环境下的汇编语言设计》里面有详细的说明 这样的定义在vs2008下怎么报错了 哪位兄弟用过WTSQuerySessionInformation这个API? dll可以包含对话框界面吗? 我在做一个学生上机考试系统/请问怎么在视图(从ScrollView派生)里将题目显示出来 简单问题,立即结分 如何抓屏幕的内容 maybe it is the last time i came here !!! 工业曲线绘制 哪个控件比较好呢 求救,VC++程序运行不了 请问在VC6中如何直接读写I/O端口? 我在一个文本文件中输入了"r"然后回车,可是用程序读出并放在CEdit时却显示"r屯 "这是为什么怎么解决? 紧急求救!!!
1、PE文件格式的背景和由来: 在开始介绍PE结构之前,有必要向读者提一提常用的PE文件结构分析工具:Win32
SDK提供的 DUMPBIN 可以转储PE文件和COFF OBJ/LIB 文件;Borland 的使用者可用TDUMP
观察PE 文件,但TDUMP 不支持COFF OBJ。
2、PE文件的顺序结构:我们可以把PE的内存映象结构用下面的图示简要的表示出来:DOS MZ HEADER
DOS STUB
PE
Header Signature(“PE\0\0”)
FileHeader
OptionalHeader
Section Table(array of IMAGE_
SECTION_HEADER).text.data.edata.idata
.reloc…
COFF Line Number
COFF Symbols
Code View Debug Information 2. 1、DOS header 和 DOS Stub:所有的 PE 文件(或32位的DLLS)都必须以一个简单的DOS MZ
header为起始(IMAGE_DOS_HEADER结构体)。在实际中,除了e_lfanew(PE header 的文件
偏移量)我们可以不必太关心其余成员数据。DOS Stub只是提供了PE文件在DOS下执行时
,DOS会把它当作有效的执行文件而顺利执行。通常会在屏幕上输出 " This program
cannot run in DOS mode " 之类的提示语。程序员也可以改变DOS Stub,根据自己的意
图实现完整的 DOS代码。2. 2、PE Header:PE表头内含程序代码和各种资料的大小位置、适用的操作系统、堆栈(stack)最初大小
等等重要信息。犹如执行文件的纲目。整个PE Header 是一个IMAGE_NT_HEADERS结构体,
在Win32 SDK中定义如下:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; \\PE标记,值为50h, 45h, 00h, 00h(ASCII:
”PE\0\0”)
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;PE Signature
为校验标记,由连接器产生。通常装载器通过指向此位的指针e_lfanew(DOS header中)
来检验此文件是否为PE格式。FileHeader域包含了关于PE文件物理分布的一般信息,
opionalHeader域包含了关于PE文件逻辑分布的信息。显然可以pNTHeader = dosHeader +
dosHeader->e_lfanew获得pe头的地址。2.2.1、File Header 结构域:在Win32 SDK中 File Header 定义如下:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD ;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;各个成员的说明列表如下:成 员 说 明
Machine 该文件运行所要求的CPU。对于Intel平台,该值是IMAGE_FILE_MACHINE_I386
(14Ch)。
NumberOfSections 文件的节数目。如果我们要在文件中增加或删除一个节,就需要修改
这个值。
TimeDateStamp 连接器创建文件时刻。从1969/12/31 4:00 P.M. 之后的总秒数。
PointerToSymbolTable COFF 符号表格的偏移位置,用于调试。
NumberOfSymbols COFF 符号表格中符号的个数,用于调试。
SizeOfOptionalHeader 指示紧随本结构之后的 OptionalHeader 结构大小,必须为有效
值。
Characteristics 关于文件信息的标记,比如文件是 exe(0x0002) 还是 dll(0x2000)在实际应用中,有三个域对我们有用: NumberOfSections ,SizeOfOptionalHeader 和
Characteristics。我们通常不会改变 SizeOfOptionalHeader 和Characteristics 的值
,如果要遍历节表就得使用 NumberOfSections。2. 2。2、Option Header结构域:这是PE表头的第三个成分。对于PE文件而言,这一部分其实并不是可有可无。因为COFF格
式允许不同的设计者在标准的File header之后定义一个结构。Optional header 正是PE
设计者认为在基本的File header 信息之外还需要的一些重要的信息。完整的结构定义可
以参考Win32 SDK中的WINNT.H头文件,这里列举了其中的重要成员:成员 说 明
AddressOfEntryPoint PE装载器准备运行的PE文件的第一个指令的RVA。若要改变整个执
行的流程,可以将该值指定到新的RVA,这样新RVA处的指令首先被执行。
ImageBase PE文件的优先装载地址。如果该值是400000h,PE装载器将尝试把文件装到虚
拟地址空间的400000h处。若该地址区域已被其他模块占用,那PE装载器会选用其他空闲
地址,这个过程我们把它叫做重定位。
SectionAlignment 内存中节对齐的粒度(granularity)。一旦装载到内存中,每个节(s
ection)保证从一个此值的倍数的虚拟地址开始。如果该值是4096 (1000h),那么每节的
起始地址必须是4096的倍数。
FileAlignment 文件中节对齐的粒度。文件中组成每个section的原始数据(raw data)
保证是从一个此值的倍数的虚拟地址开始。如果该值是(200h),,那么每节的起始地址必
须是512的倍数。
MajorSubsystemVersion
MinorSubsystemVersion win32子系统版本。若PE文件是专门为Win32设计的,该子系统版
本必定是4.0否则不会有3维立体感对话框等。
SizeOfImage 内存中整个PE映像体(map)的尺寸。它是所有头和节经过节对齐处理后的
大小。
SizeOfHeaders 所有头+节表的大小,也就等于文件尺寸减去文件中所有节的尺寸。可以
以此值作为PE文件第一节的文件偏移量。
Subsystem NT用来识别PE文件属于哪个子系统。 对于大多数Win32程序,只有两类值:
Windows GUI 和 Windows CUI (控制台)。
DataDirectory IMAGE_DATA_DIRECTORY 结构数组。每个结构给出一个重要数据结构的RVA
,比如引入地址表等。在PE header中,有很多地址指针是用RVA来表示的。 RVA 代表相对虚拟地址(Relative
Virtual Address)。简言之,RVA是虚拟空间中到参考点的一段距离,类似文件偏移量。
当然它是相对虚拟空间里的一个地址,而不是文件头部。举例来说,如果PE文件装入虚拟
地址(VA)空间的400000h处,且进程从虚址401000h开始执行,我们可以说进程执行起始地
址在RVA 1000h。每个RVA都是相对于模块的起始VA(Virtual Address)而言的。2.2.3、Option Header 的中的重要数据成员 Data Directory:Data Directory 定义为IMAGE_DATA_DIRECTORY结构体数组,每个数组元素给出一个重要
数据结构的RVA(Relative Visual Address 相对虚地址),比如引入表地址、重定位表
地址。通常共16个成员。(详细的宏定义请参阅WIN32 SDK 的WINNT.H 头文件)
这个数组起到让装载器迅速的在内存中找到特定的节(section)的作用,减去了遍历节表的
麻烦。2. 3、Section Header:紧接在PE header 的是section table(IMAGE_SECTION_HEADER) 。每个表项包含有该节
的属性、偏移量等。如果PE文件里有3节,那么此数据结构就有3个元素。为了更好的理解
PE header 和Section header 在PE文件中的组织关系,我们可以把PE文件看作一逻辑磁
盘,PE header是boot扇区而sections是各种文件,节表视为逻辑磁盘中的根目录。
节表定义如下:
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 重要成员的说明列表如下:成员 说 明
Name 节名。长度不超过8字节。仅仅是个标记而已,注意这里不用null结束。
VirtualAddres 本节的RVA(相对虚拟地址)。PE装载器将节映射至内存时会读取本值。
如果域值是1000h,而PE文件装在地址400000h处,那么本节就被载到401000h。
SizeOfRawData 经过文件对齐处理后节尺寸,PE装载器提取本域值了解需映射入内存的节
字节数。
PointerToRawData 这是节基于文件的偏移量,PE装载器通过本域值找到节数据在文件中
的位置。
Characteristics 包含标记以指示节属性,比如节是否含有可执行代码、初始化数据、未
初始数据,是否可写、可读等。2.4、Section 域节(section)是PE文件真正内容的划分。每一节是是拥有共同属性的数据的集合。每节
都有相应的命名,不过这个命名不是太重要,只要是相同属性的内容都可以放进一节,命
名只是便于识别。下面重点介绍一下一些重要的段。2.4.1、text section 此节一般包含有连接器连接的所有obj目标文件的执行代码。这个执行代码块是一个大
的.text。不同于在DOS下面的执行文件可以分成几部分。如果是使用的Borland C++,其
编译器将产生的代码存于名为CODE的区域,连接器连接到名为CODE而不是.text的节中。
2.4.2、data section
.data是初始化的数据块。这些数据块包括编译时被初始化的字符串常量、全局(globle)
和静态(static)变量。
2.4.3、bss section
任何没有初始化的全局和局部变量都会存放到.bss节中。这个节并不占用文件的储藏
空间,所以 RawDataOffset 总是为0。2.4.4、rsrc section
该节包含模块的全部资源。如图标、菜单、位图等等。2.4.5、idata section
.idata包含其他外来的如DLL中的函数及数据信息。PE文件的每一个输入函数都明确的
列于该节中。2.4.6、edata section
与.idata对应,.edata是该PE文件输出函数和数据的列表,以供其他模块引用。有的PE文
件没有引出函数或数据,也就没有该节。
3、其余部分:
在节(Sections)的后面是COFF符号表格、COFF调试信息、COFF行号信息。这些域对
我们的作用不大,有兴趣的读者可参阅其他书籍。4、PE文件的装载过程: 通常
http://www.vckbase.com/code/downcode.asp?id=1205
http://61.153.195.10:8080/list.asp?part1=1&part2=5
这里讲的很详细。
也给我一份.谢谢先