原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx

上传人:b****4 文档编号:6203618 上传时间:2023-05-06 格式:DOCX 页数:41 大小:40.02KB
下载 相关 举报
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第1页
第1页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第2页
第2页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第3页
第3页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第4页
第4页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第5页
第5页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第6页
第6页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第7页
第7页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第8页
第8页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第9页
第9页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第10页
第10页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第11页
第11页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第12页
第12页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第13页
第13页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第14页
第14页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第15页
第15页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第16页
第16页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第17页
第17页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第18页
第18页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第19页
第19页 / 共41页
原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx_第20页
第20页 / 共41页
亲,该文档总共41页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx

《原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx》由会员分享,可在线阅读,更多相关《原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx(41页珍藏版)》请在冰点文库上搜索。

原创For菜鸟文章PE文件格式qduwg翻译文档格式.docx

它基于在UNIX和VMS上运行的对象文件和可执行文件的COFF"

common 

object 

file 

format"

格式。

win32 

SDK 

包括一个头文件<

winnt.h>

包括对PE格式的定义。

我将提及成员名和定义。

你也可能发现DLL文件"

imagehelp.dll"

 

非常有用。

它是NT的一部分,但文档很少。

它的一些函数在"

Developer 

Network"

被描述。

总览:

在PE文件的开始,我们可以发现MSDOS执行部分("

stub"

);

这使得任何一个PE文件是有效的DOS执行文件。

在DOS-stub之后是32位的魔数0x00004550(IMAGE_NT_SIGNATURE).然后是一个COFF格式的文件头,指明在何种机器上运行,多少个节在里面,连接的时间,是否是可执行文件或者DLL等。

DLL和可执行文件的区别:

DLL不能够启动,只可以被其他可执行文件使用,一个可执行文件不能够连接到另一个可执行文件。

接着,我们看到一个可选文件头optional 

header(虽然叫“可选”,它实际上一直存在)。

COFF把可选文件头用于库,不用于目标文件。

这里告诉我们文件如何被调入:

起始地址,预留堆栈数,数据段尺寸。

一个有趣的部分是尾巴上的数组数据目录data 

directories,这些目录包含指向节内数据的指针。

例如,如果文件有输出目录,可以在数组成员IMAGE_DIRECTORY_ENTRY_EXPORT内发现一个指针指向那个目录(目录描述结构->

THUNKDATA结构->

BYNAME结构)。

他将指向一个节。

在头的后面是节头,实际上,节的内容就是真正需要运行一个程序所需要的东西,所有的头和目录成员就是帮你找到它。

每个节有几个标志:

对齐,包含的数据类型(初始化数据等),是否可以共享等,及数据自身。

多数节含有一个或多个通过“可选头”内的数据目录项引用的目录。

没有目录类型的内容是初始化数据或者可执行代码。

(节是物理意义上的内容组织,目录是逻辑意义上的内容组织,两者互相配合才能找到需要的东西。

节是存储内容的地方,区域的安排,目录是如何对里面东西进行查找,目的是寻找里面的内容)

+-------------------+

DOS-stub 

|

file-header 

+- 

-+

optional 

header 

|- 

-|

data 

directories 

section 

headers 

... 

Signature

----------------------

DOS 

STUB的概念在16位WINDOWS可执行文件内就已经被熟知了,STUB是用于OS/2可执行文件,自解压文档和其他程序。

对于PE文件,它是DOS2兼容可执行文件,总是包含100字节内容,输出一个错误信息:

比如"

this 

program 

needs 

NT"

.

你认识到一个DOSSTUB通过验证DOS-header,就是一个IMAGE_DOS_HEADER结构,前两个字节必须使"

MZ"

(有一个定义针对这个WORD,IMAGE_DOS_SIGNATURE 

)。

你通过尾部的'

e_lfanew'

给出的偏移量所确定的签名区别一个PE文件。

对于PE文件,它是一个32位,按照8字节对齐边界。

其值0x00004550由IMAGE_NT_SIGNATURE 

定义.

IMAGE_NT_HEADERS 

STRUCT

Signature 

DWORD 

?

FileHeader 

IMAGE_FILE_HEADER 

<

>

OptionalHeader 

IMAGE_OPTIONAL_HEADER32 

ENDS

文件头File 

Header

-----------

Machine 

WORD 

NumberOfSections 

TimeDateStamp 

PointerToSymbolTable 

NumberOfSymbols 

SizeOfOptionalHeader 

Characteristics 

要得到IMAGE_FILE_HEADER,确认DOS头的前2个字节"

,然后找到'

成员,然后从文件开始跳过许多字节,验证你找到的签名。

文件头作为一个IMAGE_FILE_HEADER结构,就从它后面开始。

从上到下描述其成员。

第1:

Machine, 

16位值,指明可执行文件所需要的系统。

已知合法值如下:

IMAGE_FILE_MACHINE_I386 

0x014c 

Intel 

80386 

处理器。

0x014d 

80486处理器

0x014e 

Pentium 

处理器

0x0160 

R3000 

(MIPS)处理器

IMAGE_FILE_MACHINE_R3000 

(0x162) 

IMAGE_FILE_MACHINE_R4000 

(0x166) 

R4000 

IMAGE_FILE_MACHINE_R10000 

(0x168)R10000 

IMAGE_FILE_MACHINE_ALPHA 

(0x184) 

DEC 

Alpha 

AXP处理器

IMAGE_FILE_MACHINE_POWERPC 

(0x1F0)IBM 

Power 

PC处理器

第2:

NumberOfSections,16位值,它是跟随于头后面的节数。

我们在后面讨论。

第3:

TimeDateStamp,32位值,文件创建的时间。

可以通过该值区分不同的文件版本。

时间戳用于绑定输入目录,后面讲到。

有些连接器设置该值为荒唐的值。

PointerToSymbolTable和NumberOfSymbols,都是32位的。

用于调试信息。

一般都是0。

第4:

SizeOfOptionalHeader,16位,是IMAGE_OPTIONAL_HEADER的尺寸.可以用它确认PE文件结构的正确性。

第5:

Characteristics,16位值,包括一个标志集合,多数只对目标文件和库有效。

Bit 

(IMAGE_FILE_RELOCS_STRIPPED) 

如果文件内没有重定位信息该位置1。

这里指的是每个节内的重定位信息。

不用于可执行文件,可执行文件的重定位信息在后面提到的base 

relocation目录。

(IMAGE_FILE_EXECUTABLE_IMAGE) 

如果文件是可执行的则置1,例如不是一个目标文件或者库文件。

如果连接器试图创建可执行文件,但由于某种原因失败了,也置1。

(IMAGE_FILE_LINE_NUMS_STRIPPED)如果行数信息剥离,置1,对可执行文件无效。

(IMAGE_FILE_LOCAL_SYMS_STRIPPED) 

如果没有本地符号信息该位置1。

对可执行文件无效。

(IMAGE_FILE_AGGRESIVE_WS_TRIM) 

如果操作系统被假定通过页换出抢占式修剪进程的工作集(进程使用的内存数),该位置1。

Bits 

(IMAGE_FILE_BYTES_REVERSED_LO)和15(IMAGE_FILE_BYTES_REVERSED_HI) 

如果文件的的endianess不是机器期望的,则置1,于是读之前必须交换字节。

对可执行文件不可靠。

(IMAGE_FILE_32BIT_MACHINE) 

如果机器被期望是32位机器,置1。

(IMAGE_FILE_DEBUG_STRIPPED)如果没有调试信息在文件内,置1。

10 

(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) 

如果程序不能够从可移动媒体比如软盘或光驱,置1。

操作系统建议拷贝文件到交换文件然后执行。

11 

(IMAGE_FILE_NET_RUN_FROM_SWAP) 

如果不能够才网络运行,置1。

12 

(IMAGE_FILE_SYSTEM) 

如果文件是类似驱动程序的系统文件,置1。

对执行文件无效。

13 

(IMAGE_FILE_DLL) 

如果文件是DLL,置1.

14 

(IMAGE_FILE_UP_SYSTEM_ONLY) 

如果文件不是为多处理器设计的,置1 

相对虚拟地址Relative 

Virtual 

Addresses

--------------------------

PE格式使用所谓的RVA。

用于描述内存地址,如果你不知道基地址的话。

需要你加上基地址得到线性地址。

基地址是PE映像加载的地址。

例如:

假如可执行文件加载到0x400000,可执行文件的RVA是0x1560. 

有效执行起始地址为0x401560.如果被加载到0x100000,则执行起始位置在0x101560.

情况变的复杂起来,由于节不必按照加载的映像那样对齐。

例如,节一般按照512字节对齐。

加载的映像可能按照4096字节对齐。

参看'

SectionAlignment'

'

FileAlignment'

对齐的意思就是地址值=对齐长度的倍数。

于是为了找到一个特殊的RVA指向的信息,你必须计算偏移量好象文件被加载一样。

假如知道执行起点在RVA 

0x1560, 

想从这反汇编代码。

要找到文件内的地址,你必须找出在RAM内的按照4096对齐的节,"

.code"

节自内存RVA 

0x1000开始,16384字节长,你知道RVA 

0x1560的偏移量在那个节内是0x560.找出节在文件内按照512字节对齐,且"

从0x800开始,那么在文件内的代码执行起点是0x800+0x560=0xd60。

然后反汇编,并发现一个存取地址0x1051d0处的变量.线性地址在加载执行文件时重新分配,并给出优先加载地址。

你发现优先加载地址是0x100000,于是我们处理RVA 

0x51d0. 

这是一个开始于RVA 

0x5000的数据区,2048字节长。

它开始于文件偏移量0x4800.变量可以在文件偏移量0x4800+0x51d0-0x5000=0x49d0处发现。

可选头Optional 

---------------

紧跟在文件头的后面是IMAGE_OPTIONAL_HEADER,尽管名字是可选,实际一直存在。

包含关于如何精确处理PE文件的信息。

从上到下介绍成员。

Magic 

MajorLinkerVersion 

BYTE 

MinorLinkerVersion 

SizeOfCode 

SizeOfInitializedData 

SizeOfUninitializedData 

AddressOfEntryPoint 

BaseOfCode 

BaseOfData 

ImageBase 

SectionAlignment 

FileAlignment 

MajorOperatingSystemVersion 

MinorOperatingSystemVersion 

MajorImageVersion 

MinorImageVersion 

MajorSubsystemVersion 

MinorSubsystemVersion 

Win32VersionValue 

SizeOfImage 

SizeOfHeaders 

CheckSum 

Subsystem 

DllCharacteristics 

SizeOfStackReserve 

SizeOfStackCommit 

SizeOfHeapReserve 

SizeOfHeapCommit 

LoaderFlags 

NumberOfRvaAndSizes 

DataDirectory 

IMAGE_DATA_DIRECTORY 

IMAGE_NUMBEROF_DIRECTORY_ENTRIES 

dup(<

IMAGE_OPTIONAL_HEADER 

equ 

IMAGE_OPTIONAL_HEADER32>

第1个16位字是'

Magic'

,总是0x010b.

下面2个字节是连接器的版本号'

MajorLinkerVersion'

和'

MinorLinkerVersion'

,这些值都不可靠,不能总是妥当的反映连接器版本。

有些连接器不设置该域。

下面3个longwords(32位)指定执行代码尺寸('

SizeOfCode'

),初始化数据尺寸

SizeOfInitializedData'

 

所谓的数据段"

segment"

未初始化数据尺寸

SizeOfUninitializedData'

所谓的"

bss 

.这些数值也不可靠。

往下一个32位的RVA.是入口点的偏移量。

('

AddressOfEntryPoint'

).执行从此开始。

下面2个32位是可执行代码('

BaseOfCode'

)和初始化数据('

BaseOfData'

)的RVAs 

我们对它没有兴趣,因为可以通过节来查看更可靠的信息。

非初始化数据没有RVA。

下面是一个32位值,ImageBase'

作为整个文件的优先加载地址,包括所有头在内。

该值总是

64KB的倍数,文件已经被连接器重定位,如果文件能够真正加载到这个地址,加载器不必重定位文件。

如果另一个映像已经被加载到那个地址,则优先地址不可使用。

这种情况下,映像被加载到其他地址,需要重定位。

如果映像是DLL,还有更多结果,因为"

bound 

imports"

不再有效,需要对使用DLL的执行文件进行修正。

参见'

import 

directory'

下面2个32位是当映像文件加载后,PE文件的节在内存内的对齐,'

以及在文件内的对齐'

一般文件对齐是512,节对齐是4096.

下面2个16位的字是期望的操作系统版本,'

MajorOperatingSystemVersion'

和 

MinorOperatingSystemVersion'

下面2个16位的字是期望的可执行文件版本,'

MajorImageVersion'

MinorImageVersion'

许多连接器不正确设置这些信息。

下面2个16位的字是期望的子系统版本,'

MajorSubsystemVersion和MinorSubsystemVersion. 

这个必须是Win32版本或者POSIX版本。

该版本需要正确提供,因为它被检查并使用。

如果程序是Win32-GUI并运行在NT4,子系统版本不是4.0,对话框不是3D效果。

然后是Win32VersionValue,32位。

大部分情况下是0。

下面是32位的映像需要的内存数量'

SizeOfImage'

.是所有的头和节的总和,如果节已经对齐。

它是给加载器的线索,需要多少页加载映像。

下面一个是32位的所有头的总和,包括数据目录和节头。

SizeOfHeaders'

.它也是才文件开始到第一节的偏移量。

然后是32位的校验码'

CheckSum'

.对当前版本的NT,只校验映像是否是NT驱动程序。

对于其他可执行文件类型,不必提供这个码,可能为0。

然后是16的子系统Subsystem'

表明在什么系统上运行:

IMAGE_SUBSYSTEM_NATIVE 

(1)执行文件不需要子系统,用于驱动程序。

IMAGE_SUBSYSTEM_WINDOWS_GUI 

(2)映像是Win32图形程序可以打开控制台 

IMAGE_SUBSYSTEM_WINDOWS_CUI 

(3)映像是Win32控制台程序,可以得到缺省控制台。

IMAGE_SUBSYSTEM_OS2_CUI 

(5)映像是OS/2 

控制台,程序是OS/2格式。

IMAGE_SUBSYSTEM_POSIX_CUI 

(7)映像使用POSIX控制台子系统

Windows 

95可执行文件总是使用Win32 

subsystem,于是合法值是2和3。

下面是16位,DllCharacteristics,表明是否是DLL,如果0位置1,DLL被通知进程结合。

位1置1,DLL被通知线程脱离。

位2置1,DLL被通知线程结合。

位3置1,DLL被通知进程脱离。

下面4个 

32 

位预留堆栈大小'

SizeOfStackReserve'

提交的堆栈大小'

SizeOfStackCommit'

预留的堆的大小'

SizeOfHeapReserve'

和提交的的堆的的大小'

SizeOfHeapCommit'

预留数量是地址空间不是真实的RAM,程序启动时,提交的数量是真正的分配的内存。

这个值也是堆和栈根据需要增长的一个数量。

一个程序预留1 

MB的堆并提交的堆时64KB,该堆就从64KB开始,并保证可以加大到1MB.堆将以64KB块增长。

该堆在这里是主要堆,默认堆。

一个进程可以创建多个堆如果需要的话。

栈是第一个线程的栈,进程可以创建许多线程,每个都有自己的堆栈,DLLs 

没有栈或者堆,于是在其映像内该值被忽略。

下面是32位的LoaderFlags, 

没有用。

然后是32位的NumberOfRvaAndSizes,在随后的目录内的有效项目数。

最好使用

IMAGE_NUMBEROF_DIRECTORY_ENTRIES,即16。

下面是具有IMAGE_NUMBEROF_DIRECTORY_ENTRIES(16)个成员的IMAGE_DATA_DIRECTORYs结构数组.

VirtualAddress 

isize 

IMAGE_DATA_DIR

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2