【永利酒店赌场】PE文件结构解析

既,已知某虚拟地址(如va)和某区块的虚拟地址(text_va),虚拟地址在区块中,同时还知道此区块在文件中的位置(text_file_offset),解出此虚拟地址在文件中的具体位置。解:根据他们的偏移量相同(都是text_va

PE文件结构详解,pe结构详解

  1、定位标准PE头

  DOS
Stub长度不固定,所以DOS头不是一个固定大小的数据结构。DOS头位于PE的起始位置,通过DOS头去定位后面标准PE头的位置就是通过字段e_lfanew。

  e_lfanew字段的值是一个相对偏移量,绝对定位时需要加上DOS
MZ头的基地址。

  也就是PE头的绝对位置是:

  PE_start = DOS MZ 基地址+IMAGE_DOS_HEADER.e_lfanew

  2、PE文件结构

  在32位系统下,最重要的部分是PE头和PE数据区。

  32位系统下的PE文件被划分为:DOS MZ头、DOS Stub、PE头、节表和节内容。

  节表是PE中所有节的目录,每个目录的字节码就是节内容,节内容按照目录里的指针指向的地址,分别将节的字节码在文件空间中排列起来,组成一个完整的PE文件,PE文件

头等于DOS头加PE头。

  3、PE文件头部解析 

  DOS MZ头IMAGE_DOS_HEADER:

  其中最重要的成员是e_magic成员和e_lfanew成员。

  DOS MZ头下面的是DOS Stub。整个DOS
Stub是一个字节块,其内容随着链接时使用的链接器不同而不同,PE中并没有与之对应的相关结构。

  PE头标识Signature:

  在DOS Stub后的是PE
头标识Signature,PE头部信息中有一个四字节的标识,该标识位于指针IMAGE_DOS_HEADER.elfanew指向的位置。其内容固定,对应于ASCII码

  的字符串“PE”。

  标准PE头IMAGE_FILE_HEADER:

  标准的PE头IMAGE_FILE_HEADER在PE头部标识后面,即位于elfanew值+4的位置。从此位置开始的20个字节为数据结构标准PE头IMAGE_FILE_HEADER的内容。(该结

构在微软官方文档中被称为标准通用对象文件格式)

  该部分记录了PE文件的全局属性,包括PE文件运行的平台,PE文件类型(EXE
Or DLL?),文件中存在的节的总数等信息。

  该部分用途:判断文件类型,得到PE文件中节的总量,当成节区信息进行遍历操作时的循环次数。

    扩展PE头IMAGE_OPTIONAL_HEADER32

 存储文件执行时的入口地址、文件被操作系统装入内存之后的默认基地址,节在磁盘和内存中的对其单位等信息。   

  PE头IAMGE_NT_HEADER:

  该部分是广义上的PE头,在标准PE文件中其大小为456字节

  IMAGE_NT_HEADER是上述三部分的总和,及Signature、IMAGE_FILE_HEADER和IMAGE_OPTIONAL_HEADER。

  该结构的详细定义如下:

  数据目录项IMAGE_DATA_DIRECTORY

  IMAGE_OPTIONAL_HEADER结构的最后一个字段DataDirectory字段定义了PE文件中出现所有不同类型的数据的目录信息。

  如导入表、导出表、资源和重定位表等。在内存中,这些数据被操作系统以页为单位组织起来,并赋以不同的访问属性。在文件中,这些数据也同样被组织起来,按照不同类别

分别存放在文件的指定位置。

  该结构就是用来描述不同类别的数据在文件(和内存)中的位置及大小。

  该数据目录中定义的数据类型一直是种,PE中用数据目录项IMAGE_DATA_DIRECTORY的数据结构定义每种数据结构。

  结构定义如下:

  总得数据目录一共由16个相同的IMAGE_DATA_DIRECTORY结构连续排列在一起组成。

  节表项IMAGE_SECTION_HEADER:

  节表位于IMAGE_NT_HEADER之后,由多个节表项(IMAGE_SECTION_HEADER)组成,每个节表项记录了PE中与某个特定的节有关的信息,如节的属性,节的大小,在

文件和内存中起始位置等。

  节表中的节的数量由字段IMAGE_FILE_HEADER中的NumberOfSection成员定义。

  节表的数据结构定义如下:

  4、PE头IMAGE_NT_HEADER的字段

  1.IMAGE_NT_HEADER.Signature

  +0000h,双字。PE文件标识,被定义为00004550h。

  如果更改其中任何一个字节,操作系统就会无法把该文件识别为正确的PE文件。由于文件的DOS头部分没有被破坏,程序仍然可以在DOS环境下运行。

  2.IMAGE_NT_HEADER.FileHeader:

  +0004h,结构。该结构指向IMAGE_FILE_HEADER。

  3.IMAGE_NT_HEADER.OptionalHeader:

  +0018h,结构。这个指向IMAGE_OPTIONAL_HEADER32。它是操作系统映像文件所有独有的头部信息。

  5、标准PE头IMAGE_FILE_HEADER的字段

  4.IMAGE_FILE_HEADER.Machine:

  +0004h,单字。指定给PE文件运行的平台。

  5.IMAGE_FILE_HEADER.NumberOfSections:

  +0006h,单字。文件中存在的节的总数。

  在XP系统中,可以有0个节,但是数值不能小于1,也不能超过96,如果将该值设为0,操作系统在装载时会提示不是有效的Win32程序。

  如果想在PE中增加或删除节,必须变更此处的值。

  这个值不能比实际内存中存在的节多,也不能少,否则在装载的时候回出现错误。

  6.IMAGE_FILE_HEADER.TimeDateStamp:

  +0008h,双字。编译器创建此文件的时间戳。低32位存储的值是自1970年1月1日00:00开始到创建时间为止的总秒数。

  这个值可以随便修改,对程序的运行没有影响。

  7.IMAGE_FILE_HEADER.PointerToSymbolTable:

  +000Ch,双字。COFF符号表的文件偏移。

  如果不存在COFF符号表,此值为0.对于映像文件,这个值为0。

  8.IMAGE_FILE_HEADER.NumberOfSymbols:

  +0010h,双字。符号表中元素的数目。

  因为字符串表紧跟符号表,所以可以根据这个值定位字符串表。

  在映像文件中,这个值为0,主要用于调试。

  9.IAMGE_FILE_HEADER.SizeOfOptionalHeader:

  +0014h,单字。指定结构IMAGE_OPTIONAL_HEADER32的长度。

  默认情况下,这个值是00e0h,如果是64位的PE文件,该结构默认大小为00F0h。

  10.IMAGE_FILE_HEADER.Characteristics:

  +0016h,单字。文件属性标志字段,它的不同数据位定义了不同的文件属性。这是一个很重要的字段,不同的定义将影响系统对文件的载入方式。

  对于普通的可执行PE文件来说,这个字段的值一般是010fh,对于DLL文件来说,这个字段的值是210ch。

  第1位为1时,表明此映像文件是合法的,可以运行。如果未设置此标志,表明出现链接器错误。

  第10位为1时,如果此映像文件在可移动存储介质上,加载器将完全加载它并把它复制到内存交换文件中。

  第11位为1时,如果此映像文件在网络上,那么加载器也将完全加载它并把它复制到内存交换文件中。

  当第13位为1时,表明此映像文件为动态链接库。这样的文件总被认为是可执行文件。

  可执行文件的标志位被设置为010fh,即第0、1、2、3、8位分别被设置为1,标识该文件为可执行文件,不含重定位信息,不含符号信息和行为信息,文件只在32位平台运

  行。

  6、扩展PE头IAMGE_OPTIONAL_HEADER32的字段

  11.IMAGE_OPTIONAL_HEADER32.Magic:

  +0018h,单字。魔术字,说明文件的类型,如果为010BH,则表示该文件为PE32;

  如果为0107h,则表示为ROM映像;如果为020BH,则表示文件为PE32+,即64位下的PE文件。

  12.IMAGE_永利酒店赌场,OPTIONGAL_HEADER32.MajorLinkerVersion

  13.IMAGE_OPTIONAL_HEADER32.MinorLinkerVersion:

  +001ah,单字。这两个字段都是字节型,指定链接的版本号,对执行没有任何影响。

  14.IAMGE_OPTIONAL_HEADER32.SizeOfCode:

   
+001ch,双字。所有代码节的总和(以字节计算),该大小是基于文件对齐后的大小,而非内存对齐后的大小。

  15.IMAGE_OPTIONAL_HEADER32.SizeOfInitializedData:

   +0020h,双字。所有包含已经初始化的数据的节的总大小。

  16.IMAGE_OPTIONAL_HEADER32.SizeOfUninitializedData:

  +0024h,双字。所有包含未初始化数据的节的总大小。

  数据未被初始化,在文件中不占用空间,但被加载到内存之后,PE加载程序会为这些数据分配适当大小的虚拟地址空间  

  17.IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint:

  +0028h,双字。该字段值是一个RVA,记录了启动代码距离该PE加载后的起始位置有多少个字节。

  如果一个可执行文件中附加了一段自己的代码,并想让这段代码首先被执行,一般要修改这里的值,使其指向自己代码的位置。

  对于一般程序映像,它就是启动地址。

  对于设备驱动文件来说,它是初始化函数的地址。入口点对于DLL是可选的,如果不存在入口点,这个字段值必须设置为0。

  18.IMAGE_OPTIONAL_HEADER32.BaseOfCode:

  +002Ch,双字。代码节的起始RVA,表示映像被加载进内存时代码节的开头相对于映像基地址的偏移地址。一般情况下,代码节紧跟在PE头部后面,节的名称通常为

  “.text”。

  19.IMAGE_OPTIONAL_HEADER32.BaseOfData:

  +0030h,双字。数据节的起始RVA,表示映像被加载进内存时数据节的开头相对于映像的基地址的偏移地址。一般情况下,数据节位于文件末尾,节的名称通常为“.data”。

  20.IMAGE_OPTIONAL_HEADER32.ImageBase:

  +0034h,双字。该字段指出了PE映像的优先装入地址。就是在AddressOfEntryPoint中的程序被加载到内存之后的RVA。

  链接器在产生可执行文件时,是对应这个地址生成机器码。

  如果操作系统也是按照这个地址加载机器码到内存中,那么指令中许多定位信息就不需要修改了,这样运行速度会快一些。

  对于EXE文件,每个文件使用的都是独立的虚拟地址孔家。所以,装入的地址通常不会被其他模块占据。EXE文件总能按照这个地址装入,这就意味着装入后的EXE文件不需要

  进行重定位了。

  在链接的时候,可以使用参数“.base”来指定优先装入的地址,如果不指定,链接器默认装入EXE的地址是0X00400000。相对于DLL文件,
默认优先装入的地址是

0X1000000。集成用到多个DLL文件,装入地址可能会发生冲突,PE加载器会调整其中的值。

  可以自己定义这个值,但是取值不能超出边界,取得值必须在进程空间中,该值必须是64K的整数倍。

  21.IMAGE_OPTIONAL_HEADER32.SectionAlignment:

  +0038h,双字。内存中节的对齐粒度。该字段指定了节被装入内存后的对齐单位。

  SectionAlignment的值必须大于等于FileAlignment的值。

  22.IMAGE_OPTIONAL_HEADER32.FileAlignment:

  +003ch,双字。文件中节的对齐粒度。文件中节对齐是为了提高文件从磁盘加载的效率。

  Windows
XP用来组织硬盘的所有文件系统都是基于簇(分配单元)的,每个簇包含几个物理扇区。扇区是磁盘物理存取的最小单位。簇越大,磁盘存储信息的容量就越大,但

  存取所花费的事件越长。

  通常情况下,Windows会选择使用152字节的簇大小来格式化分区,最大可达到4KB。

  23.IMAGE_OPTIONAL_HEADER32.MajorOperatingSystemVersion:

  24.IMAGE_OPTIONAL_HEADER32.MinorOperatingSystemVersion:

  +0040h。上述两个字段都为单字,共计为双字。标识操作系统的版本号,分主版本号和次版本号。

  25.IMAGE_OPTIONAL_HEADER32.MajorImageVersion:

  26.IMAGE_OPTIONAL_HEADER32.MinorImageVersion:

  +0044h,双字。本PE文件映像的版本号。

  27.IMAGE_OPTIONAL_HEADER32.MajorSubsystemVersion  

  28.IMAGE_OPTIONAL_HEADER32.MinorSubsystemVersion

  +0048h,双字。运行所需要的子系统的版本号。

  29.IMAGE_OPTIONAL_HEADER32.Win32VersionValue:

  +004ch,双字。子系统版本的值,暂时保留未用,必须设置为0。

  30.IMAGE_OPTIONAL_HEADER32.SizeOfImage:

  +0050h,双字。内存中整个PE文件的映射尺寸。

  必须保证它的值是SectionAlignment的整数倍。

  31.IMAGE_OPTIONAL_HEADER32.SizeOfHeaders:

  +0054h,双字。所有头+节表按照对齐粒度对齐后的大小。

  32.IMAGE_OPTIONAL_HEADER32.Checksum

  +0058h,双字。检验和,大多数PE文件中,这个值为0,但是在一些内核模式的驱动程序和系统DLL中,该值必须是正确的。

  33.IMAGE_OPTIONAL_HEADER32.Subsystem

  +005ch,单字。指定使用界面的子系统。取值如下:

  34.IMAGE_OPTIONAL_HEADER32.DllCharateristics

  +005eh,单字。DLL文件属性。是一个标志,不是针对DLL文件的,而是针对所有的PE文件。

  35.IMAGE_OPTIONAL_HEADER32.SizeOfStackReserve:

  +0060h,双字。初始化时保留栈的大小。该字段表示为初始线程的栈二保留的虚拟内存数量。该字段默认值为0x100000(1MB)。

  36.IMAGE_OPTIONAL_HEADER32.SizeOfStackCommit:

  +0064h,双字。初始化时实际提交的栈的大小。

  保证初始线程的栈实际占用的内存空间的大小,它是被系统提交的。

  37.IMAGE_OPTIONAL_HEADER32.SizeOfHeapReserve:

  +0068h,双字。初始化保留的堆的大小。用来保留初始进程堆使用的虚拟内存,堆的句柄可以通过GetProcessHeap函数获得。每一个进程至
少会有一个默认的进程堆,该堆在

  启动进程的时候被创建,在进程的生命周期中永远不会被删除。默认值为1MB。

  38.IMAGE_OPTIONAL_HEADER32.SizeOfHeapCommit:

   +006ch,双字。初始化时还涉及提交的堆大小。在进程初始化时设定的堆所占用的内存空间,默认值为1页。

  39.IMAGE_OPTIONAL_HEADER32.LoaderFlags:

  +0070h,双字。加载标志。

    40.IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSzie:

        +0074h,双字。定义数据目录结构的数量,一般为00000010h,即16个。

        该字段由SizeOfOptionalHeaders决定,实际应用中可取2~16.

    41.IMAGE_OPTIONAL_HEADER32.DataDirectory:

        +0078h,结构。

      
 由16个IMAGE_DATA_DIRECTORY结构线性排列而成。定义PE文件中16中不同类别的数据所在的位置和大小。

  7、数据目录项IMAGE_DATA_DIRECTORY的字段

    42.IMAGE_DATA_DIRECTORY.VirtualAddress:

      
 +0000h,双字。该字段记录了特定数据类型的起始RVA。针对不同的数据结构,该字段包含的数据含义不同。

    43.IMAGE_DATA_DIRECTORY.isize:

        +0004h,双字。该字段记录了特定类型的数据块的长度。

  8、节表项IMAGE_SECTION_HEADER

    44.IAMGE_SECTION_HEADER.Name1

      
 +0000h,8字节。通常是以““结尾的ASCII码字符串”来标识节的名称。内容可自行定义。

    45.IMAGE_SECTION_HEADER.Misc:

        +0008h,双字。

    46.IMAGE_SECTION_HEADER.VirtualAddress

        +000ch,双字。节区的RVA地址。

    47.IMAGE_SECTION_HEADER.SizeOfRawData

        +0010h,双字。节在文件对齐后的尺寸。

    48.IMAGE_SECTION_HEADER.PointerToRawData:

        +0014h,双字。节区起始数据在文件中的偏移。

    49.IMAGE_SECTION_HEADER.PointerToRelocations:

        +0018h,双字。在“obj”文件中使用,指向重定位表的指针。

    50.IMAGE_SECTION_HEADER.PointerToLinenumbers

        +001ch,双字。行号表的位置。

    51.IMAGE_SECTION_HEADER.NumberOfRelocations

        +0020h,单字。重定位表的个数。(在OBJ文件中使用)

    52.IMAGE_SECTION_HEADER.NumberOfLinenumbers

        +0022h,单字。行号表中行号的数量。

    53.IMAGE_SECTION_HEADER.Characteristics:

        +0024h,双字。节的属性。

      
 该字段属于节的属性标志字段,其中不同的数据位表示了不同的属性。具体定义如下:
    
   

1、定位标准PE头 DOS
Stub长度不固定,所以DOS头不是一个固定大小的数据结构。DOS头位于PE的起始位置,通过DO…

5.2输入表

数据目录表的第二个成员指向输入表的RVA;指向的地址是IMAGE_IMPORT_DESCRIPTOR(IID)结构,一个IID对应一个DLL,最后以一个全0的IID表示结束

永利酒店赌场 1

永利酒店赌场 2

 OriginalFristThunk和FirstThunk都指向IMAGE_THUNK_DATA结构;IMAGE_THUNK_DATA都指向同一个IMAGE_IMPORT_BY_NAME

永利酒店赌场 3

永利酒店赌场 4

永利酒店赌场 5

 最重要的还是要理解为什么需要INT和IAT两个东西指向同一个东西;其流程是这样:

1.INT是不可写的,IAT是PE加载器可重写的

2.在编译的时候,编译器不懂IAT要填什么,就随便填成了和INT一样的内容(所以用十六进制编缉器查看时IAT和INT的内容是一样的)

3.PE装载器加载时根据INT找到IMAGE_IMPORT_BY_NAME中的函数名,然后使用GetProcAddress(HMODULE
hModule,LPCSTR
lpProcName)找到函数对应的地址(hModule是DLL的句柄,lpProcName是IMAGE_IMPORT_BY_NAME中的函数名)

4.PE装载器使用查找到地址重写IAT(所以用OllyDbg查看时IAT和INT的内容是不一样的)

5.所以可以直接这样理解:IAT初始是什吐槽内容并不要紧、INT就是为了重写IAT而存在的

永利酒店赌场 6

 

RVA是相对虚拟地址(Relative Virtual Address)的缩写。RVA是当PE
文件被装载到内存中后,某个数据位置相对于文件头的偏移量。

3.PE头部

永利酒店赌场 7

  • va)可知,答案为 text_file_offset + (text_va – va)。

4.2 文件偏移地址和相对偏移地址的换算

永利酒店赌场 8

永利酒店赌场 9

  1. 各区块自身不论多大,其自身差值都不会爱影响

2.
但如果其大小大于200h那么会影响下一区块的差值:比如当.text大小大于200h那么.rdata的文件偏移量将会后移;如果.text大小大于1000h那么.rdata的RVA也会后移

3.也就说表10-7中的差值只是说一般是这样子,但当程序很大时各区块的差值还是得重新计算;当然无论怎么样总是有:差值=区块RVA-区块文件偏移地址

 

步骤一:循环扫描区块表得出每个区块在内存中的起始
RVA(根据IMAGE_SECTION_HEADER 中的VirtualAddress
字段),并根据区块的大小(根据IMAGE_SECTION_HEADER 中的SizeOfRawData
字段)算出区块的结束 RVA(两者相加即可),最后判断目标 RVA
是否落在该区块内。
步骤二:通过步骤一定位了目标 RVA 处于具体的某个区块中后,那么用目标 RVA
减去该区块的起始 RVA ,这样就能得到目标 RVA 相对于起始地址的偏移量
RVA2.
步骤三:在区块表中获取该区块在文件中所处的偏移地址(根据IMAGE_SECTION_HEADER
中的PointerToRawData 字段), 将这个偏移值加上步骤二得到的 RVA2
值,就得到了真正的文件偏移地址。

说明:本文件中各种文件头格式截图基本都来自看雪的《加密与解密》;本文相当《加密与解密》的阅读笔记。

RVA转换到文件偏移地址的方法如下:

4.1 IMAGE_NT_HEADER

永利酒店赌场 10

永利酒店赌场 11

其中VirtualAddress指出了区块进入内存后的RVA地址(OD找区块用这个地址)PointerToRawDATA指出区块在磁盘文件中的地址(十六进制编缉器找区块用这个地址)

 

例如:导入表的位置和大小可以从PE文件头中IMAGE_OPTIONAL_HEADER32结构的数据目录字段中获取,对应的项目是DataDirectory字段的第2个IMAGE_DATA_DIRECTORY结构。从IMAGE_DATA_DIRECTORY结构的VirtualAddress字段得到的是导入表的RVA值,如果在内存中查找导入表,那么将RVA值加上PE文件装入的基址就是实际的地址;如果在PE文件中查找导入表,需要将RVA转换成File
Offset(也就是数据在文件中的位置)。

5.1输出表

数据目录表的第一个成员指向输出表的RVA,指向的地址是IMAGE_EXPORT_DIRECTORY结构。

永利酒店赌场 12

其中AddressofFunctions指向输出函数的地址数组,AddressOfNames指向输出函数的名称数组,AddressOfNameOrdinale指向输出函数的输出序数数组。

AddressOfNames和AddressOfNameOrdinale的顺序是相同的,也就是说AddressOfNameOrdinale第一个元素的值就是就是AddressOfNames第一个函数的输出序数,依次类推。

使用输出序数做为数组下标到AddressofFunctions指向的地址数组即可找到函数对应的地址。PE重写IAT时使用GetProcAddress通过函数名获取函数地址基本也就是这个流程。

 

5.3资源

windows系统中的各种可视元素叫做资源,包括快捷键(Accelerator)、位图(Bitmap)、光标(Cursor)、对话框(Dialog
Box)、图标(Icon)、菜单(Menu)、字符串表(String
Table)、工具栏(Toolbar)、版本信息(Version Information)等。

数据目录表的第三个成员指向资源结构的RVA,资源结构一般是相同的三层IMAGE_RESOURCE_DIRECTORY+n
*
IMAGE_RESOURCE_DIRECTORY_ENTRY加上指向最终资源代码的IMAGE_RESOURCE_DATA_ENTRY构成。

永利酒店赌场 13

其中NumberOfNameEntries的值加上NumberOfIdEntries的值等于紧接在IMAGE_RESOURCE_DIRECTORY后边的IMAGE_RESOURCE_DIRECTORY_ENTRY的个数。

永利酒店赌场 14

根据IMAGE_RESOURCE_DIRECTORY_ENTRY所在层级的不同,Name和OffsetToData的含义不相同。

Name:

不管在哪层,当最高位为1时低位值做指针使用;当最高位为0时低位值做编号使用。

更具体的,一般在第一层时高位为0低位用做编号表示资源类型比如是对话框还是菜单;第二高位为1低位为指向IMAGE_RESOURCE_DIR_STRING_U的指针该结构保存资源的名称;第三层时高位为0低位用做编号表示该资源中的语言比如是英语还是汉语。

OffsetToData:

不管在哪层,当最高位为1时指向下一层目录块的起始地址;当最高位为0时指向IMAGE_RESOURCE_DATA_ENTRY。

更具体的,一般在第一和第二层时最高位为1,指向下一层目录块的起始地址;在第三层时最高位为0,指向IMAGE_RESOURCE_DATA_ENTRY。

5.数据目录表

数据目录表是IMAGE_OPTIONAL_HEADER结构的最后一个成员,类型为IMAGE_DATA_DIRECTORY
* 16

永利酒店赌场 15

数据目录表各成员位置由VirtualAddress指出,并且不是像PE头接在DOS头后不远处一样,一般都在很远的地址;所以一般都是跳过先讲完区块然后再回头讲,也因此初学者可能会感到有些混乱。

 

1.PE文件总体结构

PE文件框架结构,就是exe文件的排版结构。也就是说我们以十六进制打开一个.exe文件,开头的那些内容就是DOS头内容,下来是PE头内容,依次类推。

如果能认识到这样的内含,那么“exe开头的内容是不是就直接是我们编写的代码”(不是,开头是DOS头内容)以及“我们编写的代码被编排到了exe文件的哪里”(在.text段,.text具体地址由其相应的IMAGE_SECTION_HRADER指出)此类的问题答案就显而易见了。

永利酒店赌场 16

exe文件从磁盘加载到内存,各部份的先后顺序是保持不变的,但由于磁盘(一般200H)和内存(一般1000H)区块的对齐大小不一样,所以同一内容在磁盘和在内存中的地址是不一样的。

换言之你在磁盘上看到一段内容一内容要到在内存中找到它–假设它是能映射到内容的部份–那么要做相应的地址转换。(比如你在Ultraedit中看到某几个字节而想在OllyDbg中找到这几个字节那么需要进行地址转换)

另外要注意,PE文件中存放的地址值都是内存中的地址,这些地址在OllyDbg中不需要转换到其指定的位置就能找到其指向的内容;这要根据这个地址找到内容在Ultraedit的地址,需要将此RVA址转换成文件偏移地址。

还要注意DOS头/PE头/块表,映射到内存时属同一区块而且是第一区块,所以此三者上的RVA和文件偏移地址是相等的。

永利酒店赌场 17

 

2.1MS-DOS头部(IMAGE_DOS_HEADER)

永利酒店赌场 18

最后的e_lfanew即是PE文件的RVA地址

永利酒店赌场 19

我们在前边已经提过,对于DOS头/PE头/区块表三部分RVA和文件偏移地址是相等的,所以上边在十六进制文本编缉器中,直接转向e_lfanew指向的000000B0可以正好找到PE头。

2.2DOS stub

DOS
stub是当操作系统不支持PE文件时执行的部分,一般由编译器自己生成内容是输出“This
program cannot be run in MS-DOS mode”等提示。

PE文件头的位置由e_lfanew指出而不是在固定位置,所以DOS
stub允许你改成自己想要执行的代码,想写多长写多长;但一般直接不理会。

 

 

3.3 IMAGE_OPTIONAL_HEADER

永利酒店赌场 20

永利酒店赌场 21

其中ImageBase指出程序装载的基地址

 

3.2 IMAGE_FILE_HEADER

永利酒店赌场 22

SizeOfOptionalHeader指了OptionalHeader的大小,NumberOfSections指出了文件的区块数;没有指向OptionalHeader和区块表的指针,这暗示区块表紧接在OpthionalHeader后,OpthonalHeader紧接在FileHeader扣,紧接的意思是没有空格的。

 

4.区块表

3.1 PE Signature

四个字节,内容“PE”,对应十六进制“50 45 00 00”

 

 2.DOS头部

网站地图xml地图