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

[PE结构分析] 7.相对虚拟地址(RVA)和文件偏移间的转移,perva

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

比如说:导入表的岗位和大小可以从PE文件头中IMAGE_【澳门金沙国际】龃龉虚拟地址,PE结构分析。OPTIONAL_HEADER32结构的数额目录字段中赢得,对应的品种是DataDirectory字段的第2个IMAGE_DATA_DIRECTORY结构。从IMAGE_DATA_DIRECTORY结构的VirtualAddress字段得到的是导入表的RVA值,假诺在内存中查找导入表,那么将RVA值加上PE文件装入的基址就是实际的地方;倘若在PE文件中查找导入表,必要将RVA转换成File
Offset(也就是数码在文书中的地方)。

RVA转换来文件偏移地址的点子如下:

手续一:循环扫描区块表得出每个区块在内存中的开始RVA(根据IMAGE_SECTION_HEADER 中的VirtualAddress
字段),并依照区块的深浅(依照IMAGE_SECTION_HEADER 中的SizeOfRawData
字段)算出区块的扫尾 RVA(两者相加即可),最终判断目标 RVA
是或不是落在该区块内。
手续二:通过步骤一定位了对象 RVA 处于具体的某部区块中后,那么用目的 RVA
减去该区块的开场 RVA ,那样就能获得目的 RVA 绝对于开首地址的偏移量
RVA2.
步骤三:在区块表中得到该区块在文书中所处的撼动地址(依照IMAGE_SECTION_HEADER
中的PointerToRawData 字段), 将以此偏移值加上步骤二获取的 RVA2
值,就得到了着实的文书偏移地址。

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

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

]
7.相对虚拟地址(RVA)和文书偏移间的更换,perva
RVA是相对虚拟地址(Relative Virtual Address)的缩写。RVA是当PE
文件被装载到内存…

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

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\0\0”。

  标准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年11月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字节。平常是以“\0“结尾的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…

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

诸如:导入表的职分和分寸可以从PE文件头中IMAGE_OPTIONAL_HEADER32结构的数码目录字段中赢得,对应的体系是DataDirectory字段的第2个IMAGE_DATA_DIRECTORY结构。从IMAGE_DATA_DIRECTORY结构的VirtualAddress字段获得的是导入表的RVA值,假诺在内存中查找导入表,那么将RVA值加上PE文件装入的基址就是实际的地方;假诺在PE文件中查找导入表,要求将RVA转换成File
Offset(也就是数码在文书中的地点)。

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

RVA转换来文件偏移地址的办法如下:

手续一:循环扫描区块表得出每个区块在内存中的开始RVA(依照IMAGE_SECTION_HEADER 中的VirtualAddress
字段),并按照区块的分寸(根据IMAGE_SECTION_HEADER 中的SizeOfRawData
字段)算出区块的终结 RVA(两者相加即可),最终判断目标 RVA
是或不是落在该区块内。
步骤二:通过步骤一定位了目的 RVA 处于具体的某部区块中后,那么用目的 RVA
减去该区块的开局 RVA ,那样就能博得目的 RVA 绝对于起先地址的偏移量
RVA2.
步骤三:在区块表中获取该区块在文书中所处的撼动地址(按照IMAGE_SECTION_HEADER
中的PointerToRawData 字段), 将那些偏移值加上步骤二获取的 RVA2
值,就赢得了着实的文书偏移地址。

步骤一:循环扫描区块表得出每个区块在内存中的先导RVA(按照IMAGE_SECTION_HEADER 中的VirtualAddress
字段),并基于区块的高低(按照IMAGE_SECTION_HEADER 中的SizeOfRawData
字段)算出区块的扫尾 RVA(两者相加即可),最终判断目的 RVA
是或不是落在该区块内。
步骤二:通过步骤一定位了目标 RVA 处于具体的某个区块中后,那么用目的 RVA
减去该区块的原初 RVA ,那样就能收获目的 RVA 相对于开端地址的偏移量
RVA2.
步骤三:在区块表中获取该区块在文书中所处的撼动地址(根据IMAGE_SECTION_HEADER
中的PointerToRawData 字段), 将以此偏移值加上步骤二取得的 RVA2
值,就获得了着实的文书偏移地址。

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

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

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

相关文章