PE文件格式之MS-DOS头,PE文件头,区块

PE文件格式之MS-DOS头,PE文件头,区块

可执行文件的格式是操作系统本身执行机制的反映。

1.在Win16平台上(如Windows 3.x),可执行文件是NE格式。
2.在Win32平台上(包括Windows 9x/NT/2000/XP/2003/Vista/CE),可执行文件是PE格式。

PE是Portable Executable File Format(可移植的执行体)简写,它是目前Windows平台上的主流可执行文件格式。

PE文件衍生于早期建立在VAX/VMS上的COFF文件格式(Common Object File Format),描述PE格式及COFF文件的主要地方是在winnt.h,其中有一节叫“Image Format”。该节给出了DOSMZ格式和Windows 3.1的NE格式文件头,之后就是PE文件的内容。在这个头文件中,几乎能找到关于PE文件的每一个数据结构定义、枚举类型、常量定义。winnt.h是PE文件定义的最终决定者。

EXE和DLL之间的区别完全是语义上的,他们使用完全相同的PE格式。唯一的区别就是用一个字段标识出这个文件是EXE还是DLL。还有许多DLL的扩展,如OCX控件和控制面板程序(.CPL文件)等都是DLL,它们有一样的实体。

64位的Windows只是对PE格式做了一些简单的修饰,新格式叫PE32+

在学习PE格式细节的时候,可以参照下图和Stud_PE工具配合(直观显示PE各部分数据)
这里写图片描述
​ 图1.PE文件的框架结构

1.PE的基本概念

PE文件使用的是一个平面地址空间,所有代码和数据都被合并在一起,组成一个很大的结构。文件的内容被分割为不同的区块(Section,又称区段、节等),区块中包含代码或数据,各个区块按页边界来对齐,区块没有大小限制,是一个连续结构。每个块都有它自己在内存中的一套属性,比如:这个块是否包含代码、是否只读或可读/写等。

PE文件不是作为单一内存映射文件被装入内存

Windows加载器(又称PE装载器)遍历PE文件并决定文件的哪一部分被映射,这种映射方式是将文件较高的偏移位置映射到较高的内存地址中。当磁盘文件一旦被装入内存中,磁盘上的数据结构布局和内存中的数据结构布局是一致的。这样如果知道在磁盘的数据结构中寻找一些内容,那么几乎都能在被装入到内存映射文件中找到相同的信息。但数据之间的相对位置可能改变,其某项的偏移地址可能区别于原始的偏移位置,不管怎样,所有表现出来的信息都允许从磁盘文件偏移到内存偏移的转换
:angry: 是不是一脸懵逼= = 慢慢来!

这里写图片描述

​ 图2.PE文件磁盘与内存映像结构图

1.基地址

1.当PE文件通过Windows加载器被装入内存后,内存中的版本被称作模块(Module)。

2.映射文件的起始地址被称为模块句柄(hModule),可以通过模块句柄访问内存中其他的数据结构。这个初始内存地址也称为基地址(ImageBase)。

3.内存中的模块代表着进程从这个可执行文件中所需要的代码、数据、资源、输入表、输出表及其他有用的数据结构所使用的内存都放在一个连续的内存块中,编程人员只要知道装载程序文件映像到内存后的基地址即可。PE文件剩下的其他部分可以被读入,但是可能不映射。

4.Windows NT或Windows 95将Module的基地址作为Module的实例句柄(Instance Handle,即Hinstance)。

5.在32位Windows系统中可以直接调用GetModuleHandle以取得指向DLL的指针,通过指针访问该DLL Module的内容。

HMODULE GetModuleHandle(LPCTSTR lpModuleName);

6.当调用该函数时,传递一个可执行文件或DLL文件名字符串,如果系统找到文件,则返回该可执行文件或DLL文件映像加载到的基地址。也可调用GetModuleHandle,传递NULL参数,则返回调用的可执行文件的基地址。

7.基地址的值是由PE文件本身设定的。按照默认设置,用Visual C++建立的EXE文件基地址是00400000hDLL文件基地址是10000000h。但是,可以在创建应用程序的EXE文件时改变这个地址,方法是在链接应用时使用链接程序的/BASE选项,或者链接后通过REBASE应用程序进行设置。

上面的简单了解下就好~ :joy:

2.相对虚拟地址

1.在可执行文件中,有许多地方需要指定内存中的地址。例如,引用全局变量时,需要指定它的地址。

2.PE文件尽管有一个首选的载入地址(基地址),但是它们可以载入到进程空间的任何地方,所以不能依赖于 PE的载入点。由于这个原因,必须有一个方法来指定地址而不依赖于PE载入点的地址。

3.为了在PE文件中避免有确定的内存地址,出现了相对虚拟地址(Relative Virtual Address,简称RVA)概念。

4.RVA只是内存中的一个简单的相对于PE文件装入地址的偏移位置,它是一个“相对”地址,或称为“偏移量”。

eg: 一个exe文件从地址400000h处装入,并且它的代码区块开始于401000h,代码块的RVA就是

目标地址 401000h-载入地址 400000h =RVA 1000h

5.将实际的装入地址加上RVA即可得到实际的内存地址

实际的内存地址被称作虚拟地址(Virtual Address,简称VA)

虚拟地址(VA)=基地址(ImageBase)+相对虚拟地址(RVA)

3.文件偏移地址

当PE文件储存在磁盘上时,某个数据的位置相对于文件头的偏移量,称为文件偏移地址(File Offset)或物理地址(RAW Offset)。

我们常用的winhex或者Hex Workshop 打开的文件所显示地址就是文件偏移地址

2.MS-DOS头部

1.每个PE文件是以一个DOS程序开始的,有了它,一旦程序在DOS下执行,DOS就能识别出这是有效的执行体

2.然后运行紧随MZ header之后的DOS stub(DOS块)。DOS stub实际上是一个有效的EXE,在不支持PE文件格式的操作系统中,它将简单显示一个错误提示,类似于字符串“This program cannot be run in MS-DOS mode”。

3.我们平常把DOS MZ头和DOS stub合称为DOS文件头

PE文件的第一个字节起始于一个传统的MS-DOS头部,被称作IMAGE_DOS_HEADER。

   IMAGE_DOS_HEADER {        // DOS .EXE header

   WORD  e_magic;                    // Magic number

   WORD  e_cblp;                     // Bytes on last page of file

   WORD  e_cp;                       // Pages in file

   WORD  e_crlc;                     // Relocations

   WORD  e_cparhdr;                  // Size of header in paragraphs

   WORD  e_minalloc;                 // Minimum extra paragraphs needed

   WORD  e_maxalloc;                 // Maximum extra paragraphs needed

   WORD  e_ss;                       // Initial (relative) SS value

   WORD  e_sp;                       // Initial SP value

   WORD  e_csum;                     // Checksum

   WORD  e_ip;                       // Initial IP value

   WORD  e_cs;                       // Initial (relative) CS value

   WORD  e_lfarlc;                   // File address of relocation table

   WORD  e_ovno;                     // Overlay number

   WORD  e_res[4];                   // Reserved words

   WORD  e_oemid;                    // OEM identifier (for e_oeminfo)

   WORD  e_oeminfo;                  // OEM information; e_oemid specific

   WORD  e_res2[10];                 //Reserved words

   LONG  e_lfanew;                   // File address of new exe header

 }IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; 

其IMAGE_DOS_HEADER结构如下所示(左边的数字是到文件头的偏移量):

这里写图片描述

重要字段:

1.e_magic字段(一个字大小)需要被设置为值5A4Dh,这个值有个#define,名为**IMAGE_DOS_SIGNATURE,**ASCII表示法里,它的ASCII值为“MZ”,是MS-DOS的最初创建者之一Mark Zbikowski字母的缩写。:+1:

2.e_lfanew字段是真正PE文件头的相对偏移(RVA),其指出真正PE头的文件偏移位置,它占用4个字节,位于文件开始偏移3Ch字节中。
这里写图片描述
​ 图3.查看PE文件MS-DOS头部

文件第一个字符“MZ”就是e_magic字段。偏移3Ch就是e_lfanew的值,显示为“B0000000”.e_lfanew的值为000000B0h,这个值就是真正的PE文件头偏移量。

3.PE文件头

1.紧跟着DOS stub的是PE文件头(PE Header)。

2.PE Header是PE相关结构NT映像头(IMAGE_NT_HEADERS)的简称,其中包含许多PE装载器用到的重要字段。

3.执行体在支持PE文件结构的操作系统中执行时,PE装载器将从IMAGE_DOS_HEADER结构中的e_lfanew字段里找到PE Header的起始偏移量,加上基址得到PE文件头的指针。

PNTHeader=ImageBase+dosHeader->e_lfanew

4.IMAGE_NT_HEADER是由三个字段组成(左边的数字是到PE文件头的偏移量):
这里写图片描述

1.Signature字段

在一个有效的PE文件里,Signature字段被设置为00004550h,ASCII码字符是“PE00”。

define IMAGE_NT_SIGNATURE定义了这个值。

#define IMAGE_NT_STGNATURE 0x00004550

PE\0\0”字串是PE文件头的开始,DOS头部的e_lfanew字段正是指向“PE\0\0”,如图3所示。

2.IMAGE_FILE_HEADER结构

IMAGE_FILE_HEADER(映像文件头)结构包含了PE文件的一些基本信息,最重要的是其中一个域指出了IMAGE_OPTIONAL_HEADER的大小

字段前的注释标出了字段相对于PE文件头的偏移

这里写图片描述

IMAGE_FILE_HEADER结构用十六进制工具显示情况如图4所示,图中的标号依次对应着相应的字段。
这里写图片描述

​ 图4.IMAGE_FILE_HEADER结构

(1)Machine:可执行文件的目标CPU类型。PE文件可以在多种机器上使用,不同平台指令机器码是不同的。下表是几种典型的机器类型:
这里写图片描述
(2)NumberOfSections:区块(Section)的数目,块表紧跟在IMAGE_NT_HEADERS后面。

(3)TimeDateStamp:表明文件是何时被创建的。格林威治时间(GMT)计算的秒数,这个值是一个比文件系统的日期/时间更精确的文件创建时间指示器。

(4)PointerToSymbolTable:COFF符号表的文件偏移位置,COFF符号表几乎总能在目标文件中找到,如果没有符号表存在,将此值设为0。

(5)NumberOfSymbols:如果有COFF符号表,它代表其中的符号数目,COFF符号是一个大小固定的结构,如果想找到COFF符号表的结束处,这个域是需要的。

(6)SizeOfOptionalHeader:紧跟着IMAGE_FILE_HEADER后面的数据大小。在PE文件中,这个数据结构叫IMAGE_OPTIONAL_HEADER.对于32位PE文件,这个域通常是00E0h;对于64位PE32+文件,这个域是00F0h。

(7)Characteristics:文件属性.有选择地通过几个值的运算得到,这些标志的有效值是定义于winnt.h内的IMAGE_FILE_xxx值,具体见下表,普通的EXE文件这个字段的值一般是010fh,DLL文件这个字段的值一般是210Eh。
这里写图片描述

3.IMAGE_OPTIONAL_HEADER结构

可选映像头(IMAGE_OPTIONAL_HEADER)是一个可选的结构,但实际上IMAGE_FILE_HEADER结构不足以定义PE文件属性,因此可选映像头中定义了更多的数据,完全不必考虑两个结构区别在哪里,两者连起来就是一个完整的“PE文件头结构”。

​ IMAGE_OPTIONAL_HEADER32结构如下,字段前的注释标出了字段相对于PE文件头的偏移量
这里写图片描述
这里写图片描述
IMAGE_OPTIONAL_HEADER32结构用十六进制工具(winhex等)显示情况如图5所示,图中的标号依次对应着相应的字段。
这里写图片描述

​ 图5 IMAGE_OPTIONAL_HEADER32结构

(1)Magic:是一个标记字,说明文件是ROM映像(0107h),还是普通可执行的映像(010Bh),一般是010Bh,如是PE32+,则是020Bh。

(2)MajorLinkerVersion:链接程序的主版本号。

(3)MinorLinkerVersion:链接程序的次版本号。

(4)SizeOfCode:所有带有IMAGE_SCN_CNT_CODE属性区块的总共大小(只入不舍),这个值是向上对齐某一个值的整数倍。例如,本例是200h,即对齐的是一个磁盘扇区字节数(200h)的整数倍。通常情况下,多数文件只有一个Code块,所以这个字段和.text块的大小匹配。

(5)SizeOfInitializedData:已初始化数据块的大小,即在编译时所构成的块的大小(不包括代码段)。但这个数据并不太准确。

(6)SizeOfUninitializedData:未初始化数据块的大小,装载程序要在虚拟地址空间中为这些数据约定空间。未初始化数据通常在.bss块中。

(7)AddressOfEntryPoint:程序执行入口RVA。在DLL中这个域能被设置为0

(8)BaseOfCode:代码段的起始RVA。在内存中,代码段通常在PE文件头之后、数据块之前。在Microsoft链接器生成的执行文件中,RVA通常是1000h。

(9)BaseOfData:数据段的起始RVA。在64位可执行文件中是不出现的。

(10)ImageBase:文件在内存中的首选装入地址。如果有可能加载器试图在这个地址装入PE文件。如果可执行文件是在这个地址装入的,那么加载器将跳过应用基址重定位的步骤。

(11)SectionAlignment:当被装入内存时的区块对齐大小。每个区块被装入的地址必定是本字段指定数值的整数倍。默认的对齐尺寸是目标CPU的页尺寸。对于运行在Windows 9x/Me下的用户模式可执行文件,最小的对齐尺寸是一页1000h(4KB)。这个字段可以通过链接器的/ALIGN开关来设置。在IA-64上,是按8KB来排列的。

(12)FileAlignment:磁盘上PE文件内的区块对齐大小,组成块的原始数据必须保证从本字段的倍数地址开始。对于x86可执行文件,这个值通常是200h或1000h

(13)MajorOperatingSystemVersion:要求操作系统的最低版本号的主版本号。:laughing:windows版本更新这么快,这个几乎不实用了。

(14)MinorOperatingSystemVersion:要求操作系统的最低版本号的次版本号。

(15)MajorImageVersion:该可执行文件的主版本号,由程序员定义。

(16)MinorImageVersion:该可执行文件的次版本号,由程序员定义。

(17)MajorSubsystemVersion:要求最低子系统版本的主版本号。这个值与下一个字段一起,通常被设置为4

(18)MinorSubsystemVersion:要求最低子系统版本的次版本号。

(19)Win32VersionValue:另一个从来不用的字段,通常被设置为0。

(20)SizeOfImage:映像装入内存后的总尺寸。

(21)SizeOfHeaders:是MS-DOS头部、PE头部、区块表的组合尺寸。

(22)CheckSum:映像的校验和。

(23)Subsystem:一个标明可执行文件所期望的子系统(用户界面类型)的枚举值。这个值只对EXE是重要的,具体下表:
这里写图片描述

(24)DllCharacteristics:DllMain()函数何时被调用,默认为0。

(25)SizeOfStackReserve:在EXE文件里,为线程保留的堆栈大小。它一开始只提交其中一部分,只有在必要时,才提交剩下的部分。

(26)SizeOfStackCommit:在EXE文件里,一开始即被委派给堆栈的内存数量。默认值是4KB。

(27)SizeOfHeapReserve:在EXE文件里,为进程的默认堆保留的内存。默认值是1MB,但是在当前版本的Windows里,堆值在用户不干涉的情况下就能增长超过这个值。

(28)SizeOfHeapCommit:在EXE文件里,委派给堆的内存大小。默认值是4KB。

(29)LoaderFlags:与调试有关,默认为0。

(30)NumberOfRvaAndSizes:数据目录的项数。这个字段从最早的Windows NT发布以来一直是16。

(31)DataDirectory[16]:数据目录表,由数个相同的IMAGE_DATA_DIRECTORY结构组成,指向输出表、输入表、资源块等数据。IMAGE_DATA_DIRECTORY的结构定义如下:
这里写图片描述

数据目录表成员的结构如下表所示,各项成员含义,在目录表下。
这里写图片描述

数据目录表成员表

PE文件中定位输出表、输入表和资源等重要数据时,就是从IMAGE_DATA_DIRECTORY结构开始的。

本例数据目录表位于128h~1A7h之间,每个成员占8个字节,分别指向相关的结构,如下图所示
这里写图片描述

​ 数据目录表

地址128h就是数据目录表的第一项,其值为0,即这个实例的输出表地址与大小皆为0,表示无输出表地址130h是第二项,该组数据表示输入表地址为2040h(RVA),大小为3Ch。

用PE编辑工具(如LordPE)来查看实例PE.exe文件的PE结构。单击LordPE的“PE Editor”打开PE_Offset文件,面板上直接显示出PE结构中的主要字段,如下图所示。
这里写图片描述

​ 用LordPE查看文件PE信息

然后单击“Directories”按钮,打开数据目录表查看面板,如图所示。
这里写图片描述

​ 用LordPE查看PE文件数据目录表结构

4.区块

在PE文件头与原始数据之间存在一个区块表(Section Table),区块表包含每个块在映像中的信息,分别指向不同的区块实体。

1.区块表

1.紧跟着IMAGE_NT_HEADERS后的是区块表,它是一个IMAGE_SECTION_HEADER结构数组

2.每个IMAGE_SECTION_HEADER结构包含了它所关联区块的信息,如位置、长度、属性;

3.该数组的数目由IMAGE_NT_HEADERS.FileHeader.NumberOfSections指出。

IMAGE_SECTION_HEADER结构定义如下:
这里写图片描述
4.PE.exe的区块表含有3个块的描述:.text、.rdata和.data。每个块对应一个IMAGE_SECTION_HEADER结构

十六进制工具查看块表如下图所示。图中的标号依次对应着第一个IMAGE_SECTION_HEADER结构中的相应字段。
这里写图片描述

​ 十六进制工具中的块表

Lord PE中单击“Sections”按钮,打开区块编辑器(下图),这是上面的内容的另一种表现形式。
这里写图片描述

​ LordPE查看的块表

(1)Name:块名。这是一个8位ASCII码名(不是Unicode内码),用来定义块名。多数块名以一个“.”开始(如.text),这个“.”实际上不是必需的。值得注意的是,如果块名超过8个字节,则没有最后的终止标志“NULL”字节。带有一个“ ”的相同名字的区块被合并,在合并后的区块中,它们是按“$”后面的字符字母顺序进行合并的。

(2)VirtualSize:指出实际的、被使用的区块大小,是区块在没对齐处理前的实际大小如果VirtualSize大于SizeOfRawData,那么SizeOfRawData是来自可执行文件初始化数据的大小,与VirtualSize相差的字节用零填充。这个字段在OBJ文件中是被设为0的。

(3)VirtualAddress:该块装载到内存中的RVA。这个地址是按照内存页对齐的,它的数值是SectionAlignment的整数倍。在Microsoft工具中,第一个块的默认RVA为1000h。

(4)SizeOfRawData:该块在磁盘文件中所占的大小。在可执行文件中,该字段包含经过FileAlignment调整后的块的长度。例如,指定FileAlignment的大小为200h,如果VirtualSize中的块长度为19Ah个字节,这一块应保存的长度为200h个字节。

(5)PointerToRawData:该块在磁盘文件中的偏移。程序经编译或汇编后生成原始数据,这个字段用于给出原始数据在文件中的偏移。如果程序自装载PE或COFF文件(而不是由操作系统装入),这一字段比VirtualAddress还重要。在这种状态下,必须完全使用线性映像方法装入文件,所以需要在该偏移处找到块的数据,而不是VirtualAddress字段中的RVA地址。

(6)PointerToRelocations:这部分在EXE文件中无意义。在OBJ文件中,表示本块重定位信息的偏移值。在OBJ文件中如果不是零,它会指向一个IMAGE_RELOCATION结构数组。

(7)PointerToLinenumbers:行号表在文件中的偏移值。这是文件的调试信息。

(8)NumberOfRelocations:这部分在EXE文件中无意义。在OBJ文件中,是本块在重定位表中的重定位数目。

(9)NumberOfLinenumbers:该块在行号表中的行号数目。

(10)Characteristics:块属性。该字段是一组指出块属性(如代码/数据/可读/可写等)的标志。比较重要的标志下表所示,多个标志值求或即为Characteristics的值。
这里写图片描述

​ 字段属性

eg:E0000020h=20000000h|40000000h|80000000h|00000020h表示该块包含执行代码,可读、可写并可执行。

C00000040h=40000000h|80000000h|00000040h表示该块可读、可写,包含已初始化的数据。

60000020h=20000000h|40000000h|00000020h表示该块包含执行代码,可读并可执行。

2.各种区块的描述

1.PE文件一般至少有两个区块:一个是代码块,另一个是数据块

2.每一个区块都有一个截然不同的名字,这个名字是用来传达区块的用途。例如,一个区块叫.rdata,表明它是一个只读区块。

3.区块在映像中是按起始地址(RVA)来排列的,而不是按字母表顺序

EXE和OBJ文件的一些常见区块下表所示,除非另外声明,表中的区块名称来自于微软定义。
这里写图片描述
这里写图片描述
​ 区块名称

:joy:当编程从PE文件中读取需要的内容时,如输入表、输出表等,不能以区块名称作为参考,正确的方法是按照数据目录表中的字段进行定位。

虽然编译器自动产生一系列标准的区块,但这没有什么不可思议。可以创建和命名自己的区块。在Visual C++中,用#pragma来声明,告诉编译器插入数据到一个区块内,像下面这样:

#pragma data_seg("My_data")

3.区块的对齐值

1.区块的大小是要对齐的,有两种对齐值,一种用于磁盘文件内,另一种用于内存中。

2.PE文件头指出了这两个值,它们可以不同

3.PE文件头里FileAlignment定义了磁盘区块的对齐值

4.每一个区块从对齐值的倍数的偏移位置开始。而区块的实际代码或数据的大小不一定刚好是这么多,所以在不足的地方一般以00h来填充,这就是区块间的间隙

eg:例如,在PE文件中,一个典型的对齐值是200h,这样,每个区块从200h之倍数的文件偏移位置开始,假设区块的第一个节在400h处,长度为90h,那么从文件400h到490h为这一区块的内容,而文件对齐值是200h,所以为了使这一节长度为FileAlignment的整数倍,490h到600h会被用零填充,这段空间称为区块间隙,下一个区块的开始地址为600h。

5.PE文件头里SectionAlignment定义了内存中区块的对齐值。PE文件被映射到内存中时,区块总是至少从一个页边界处开始,也就是说,当一个PE文件被映射到内存中,每个区块的第一个字节对应于某个内存页。

eg:在x86系列CPU中,页是按4KB(1000h)来排列的;在IA-64上,是按8KB(2000h)来排列的。所以在x86系统中,PE文件区块的内存对齐值一般等于1000h,每个区块按1000h之倍数的内存偏移位置开始。

6.在上面图种(LordPE查看的块表),.text区块在磁盘文件中的偏移位置是400h,在内存中将是其装入地址之上的1000h字节处。同样,.rdata区块在磁盘文件偏移的600h处,在内存中将是装入地址之上的2000h字节处。

4.文件偏移与虚拟地址转换

1.由于一些PE文件为减少体积,磁盘对齐值不是一个内存页1000h,而是200h,当这类文件被映射到内存后,同一数据相对于文件头的偏移量在内存中和磁盘文件中是不同的,这样就存在着文件偏移地址与虚拟地址的转换问题

2.而那些磁盘对齐值(1000h)与内存页相同的区块同一数据在磁盘文件中的偏移和在内存中的偏移相同,不需要转换。

3.在上面图种(LordPE查看的块表)显示出实例文件在磁盘与内存中各区块的地址、大小等信息虚拟地址和虚拟大小是指该区块在内存中的地址和大小。物理地址和物理大小是指该区块在磁盘文件中的地址和大小。

由于其磁盘对齐值为200h,与内存对齐值不同,故其磁盘映像和内存映像是不同的,如下图所示
这里写图片描述

4.文件被映射到内存中,DOS文件头、PE文件头和块表的偏移位置与大小均没有变化。而各区块映射到内存后,其偏移位置就发生变化了。

eg:磁盘文件中.text块起始端与文件头的偏移量为add1,映射到内存后,.text起始端与文件头(基地址)的偏移量为add2。

同时,.text区块与块表之间形成一大段空隙,这部分数据全是以0填充的。这里,add1的值就是文件偏移地址(File Offset),add2的值就是相对虚拟地址(RVA)

它们的差值为∆k,关系就是这样:

File Offset=RVA-∆k

File Offset=VA-ImageBase-∆k

因为各区块在内存中是以一个页边界为开始的,第一个区块结束后,一直到第二个区块起始端(1000h对齐处)全以数据0填充,所以不同区块在磁盘与内存中的差值不一样

该实例文件各区块在磁盘与内存中的起始地址差值。
这里写图片描述

eg:此实例中某一虚拟地址(VA)=401112h,要求计算它的文件偏移地址。401112h在.text块中,此时∆k=0C00h,故 File Offset =VA-ImageBase-∆k=401112h-400000h-C00h=512h

LordPE工具有RVA-Offset功能,“FLC”按钮打开“文件位址计算器(File Location Calculator)”,如下图
这里写图片描述

在VA域中输入要转换的虚拟地址401112h,单击“DO”按钮,转换后的文件偏移地址为512h。

End :black_flag:

1.最近上课在讲PE,刚好自己在学逆向,就决定总结一下。

2.文章为加密与解密第三版PE的部分学习笔记,(侵图删),内容比较难,可以选择性看看,主要理解某些特殊的位置和字节。

3.接下来有空,会总结完输入表,基址重定位等。:baby_bottle:

4.私下写的markdown,可能无法兼容CSDN,如需要完整版,可私戳~

猜你喜欢

转载自blog.csdn.net/Everywhere_wwx/article/details/78704225