PE面试题

PE文件格式
1.可执行文件格式NE和可执行国格式文件PE之间的关系是什么
2.PE文件早期衍生建立在
3.什么是COFF文件格式
4.COFF文件与PE文件的关系是什么有什么相似的地方
5.描述PE和COFF格式主要的头文件是
6.EXE文件和DLL文件的区别是什么
7.64位PE于32位PE有什么不同
8.PE基本概念
9.基地址
10.PE文件与DLL文件默认装载基址是多少
11.什么是虚拟地址(Virtual Address VA)
12.什么是相对虚拟地址
13.什么是文件偏移地址
14.什么是MS-DOS头
15.什么是PE文件头
16.IMAGE_FILE_HEADER结构
17.IMAGE_OPTIONAL_HEADER结构
18.SectionAlignment内存中区块对齐PE32和PE32+分别是多少
19.请讲讲FileAlignment文件中区块对齐值
20.IMAGE_OPTIONAL_HEADER中的CheckSum作用是什么
21.IMAGE_DATA_DIRECTORY结构和数组
22.IMAGE_SETCTION_HEADER结构区块与区块表
23.常见区块与说明
24.C++如何高速编译器将数据插入一个数据块
25.文件偏移与虚拟地址的转换
26.什么是输入表
27.什么是隐式链接DLL和运行期显式运行DLL
28.IMAGE_IMPORT_DESCRIPTOR(IID)的作用什么
29.IMAGE_IMPORT_DESCRIPTOR(IID)结构说明
30.IMAGE_THUNK_DATA结构及作用
31.IMAGE_IMPORT_BY_NAME结构及作用
32.INT和IAT的区别是什么
33.什么是基址重定位
34.资源表和资源结构
答案在下面:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
PE文件格式(答案)
1.可执行文件格式NE和可执行文件PE之间的关系是什么
NE可执行格式是win16平台(例如windows 3.x)、PE格式是win32位平台可执行文件格式,PE32+是win64位可执行平台文件。
2.PE文件早期衍生建立在
PE文件衍生与早期建立在VAX/VMS上的COFF文件格式(Common Object File Format),因为Windows NT平台的许多创建者来自于数字设备公司(DEC),所以他们很自然第使用已有的代码。
3.什么是COFF文件格式
COFF:Common Object File FormatCoFF(通用文件对象格式)是一种很流行的对象文件格式(注意:这里不说它是“目标”文件,是为了和编译器产生的文件(.o/.obj)相区别,因为这种格式不只用于目标文件,库文件、可执行文件也经常是这种格式),VC所产生的目标文件(.obj)就是这种格式,其他的编译器,如GCC/ICL/也使用了这种目标文件,不仅仅是C/C++,很多其他语言也使用这种格式的对象文件,统一格式的目标文件为混合语言编程带来极大的方便。
COFF文件结构
(3.1)文件头(File Header)结构_IMAHE_FILE_HEADER
(3.2)可选头(Optional Header)
(3.3)段落头(Section Header)
(3.4)段落数据(Section Data)
(3.5)重定位表(Relpcation Directives)
(3.6)行号表(Line Number)
(3.7)符号表(Symbol Table)
(3.8)字符串标(String Table)
4.COFF文件与PE文件的关系是什么有什么相似的地方
PE文件的前身是COFF文件,其中结构有很多相同比如文件头_IMAGE_FILE_HEADER、可选头_IMAGE_OPTIONAL_HEADER、重定位表等。
5.描述PE和COFF格式的头文件是
winnt.h头文件其中有一节叫做Image Format该节给出了DOS MZ格式和Windows 3.1的NE格式文件头之后就是PE文件内容,在这文件头中,几乎能找到所有关于PE文件的数据结构定义、枚举类型、常量定义、winnt.h是PE文件定义的最终决定者。
6.EXE文件和DLL文件的区别是什么
EXE文件和DLL文件的区别完全是语义上的,它们使用完全相同的PE格式,唯一的区别就是用一个字段标识出这个文件是EXE文件还是DLL文件,还有许多DLL文件拓展,例如OCX控件和控制面板程序(.CPL文件)等都是DLL文件,它们拥有一样的实体。
7.64位PE和32位PE有什么不同
64位的windows只是对PE格式进行了一些简单的修饰,新格式叫做PE32+,没有新的结构加入,只是简单地将以前的32位字段拓展成了64位,对于C++代码,Windows文件头的配置使其拥有不明显的区别。
PE文件中的数据结构一般都有32位和64位之分,例如_IMAGE_NT_HEADERS32、_IMAGE_NT_HEADER64等除了在64位版本中一些拓展域以外,这些结构几乎一模一样,在winnt.h头文件中都有#defines,它可以选择适当的32位或64位结构,并给它们起一个大小无关的别名,该结构依赖于用户正在编译的模式,尤其是_WIN64是否被定义。
8.PE基本概念
PE文件使用一个平面地址空间,所有代码和数据都合并在一起,组成了一个很大的结构。
文件的内容被分割为了不同的块(Section,又称区段,节等)区块中包含代码或数据,各个区块按页边界对齐,区块没有大小限制,是一个连续的结构。
每个块都有它自己在内存中的一套属性,例如这个块是否包含代码,是否只读或者可读/可写等。
PE文件不是作为单一内存映射文件被载入内存,Windows加载器(又称PE装载器)遍历PE文件并决定哪些部分被映射,这种映射方式是将文件较高偏移位置映射到较高的内存地址中,磁盘文件一旦被装入内存,磁盘上数据结构布局和内存数据结构布局就算是一致的,这样在磁盘的数据结构中寻找一些内容,那么几乎都能被载入内存映射文件中找到相同的信息,但是数据之间的的相对位置可能会发生改变,某项的便宜地址可能区别于原始的偏移位置。
9.基地址
当PE文件通过Windows加载器装入内存后,内存中的版本被称为模块(Module)。
映射文件的起始地址称为模块句柄(hModule),可以通过模块句柄访问内存中的其他数据结构,这个初始化内存地址被称为基地址或装载基址(ImageBase)。
准确的说,对于Windows CE,这是不成立的,一个模块句柄在Windows CE下并不等同于安装的起始地址。
内存中的模块代表进程将这个可执行文件所需要的代码、数据、资源、输入表、输出表以及其他有用的数据结构所使用的内存都放在一个连续的内存块中。
PE文件剩余部分可以被读入,但可能无法被映射,例如,在将调试信息放到文件尾部时,PE的一个字段会告诉系统把文件映射到内存需要使用多少内存,不能被映射的数据放置在文件尾部。
在32位的Windows下可以使用GetModuleHandle以取得指向DLL的指针,通过指针访问该DLL Module的内容。
10.PE文件和DLL文件默认的装载基址是多少
PE文件默认装载基址 0x00400000
DLL文件默认装载基址 0x10000000
11.虚拟地址(Virtual Address VA)
在Windows系统中,PE文件系统加载器映射到内存中,每个程序都有自己的虚拟空间,这个虚拟空间的内存地址被称为虚拟地址(Virtual Address VA)
12.相对虚拟地址
在可执行文件中,很多地方需要制定内存中的地址,例如,引用全局变量时需要指定它的地址。
PE文件尽管有一个首选的载入地址(基地址),但是它们可以载入进程空间的任何地方,所以不能依赖PE的载入点,因此必须有一个方法来指定地址(不依赖PE载入地址)。
RVA只是内存中一个简单的,相对于PE文件载入地址的偏移位置,它是一个相对地址,(或称偏移量)例如一个EXE文件从0x00400000处载入,而且它的代码区块开始于0x00401000,代码区块的RVA计算方法如下
目标地址401000 - 载入地址 400000=RVA 1000
虚拟地址(VA)=基地址(ImageBase)+相对虚拟地址(RVA)
13.什么是文件偏移地址
当PE文件存储在磁盘中时,某个数据的位置相对于头文件的偏移称为文件偏移地址,(File Offset)或物理地址(RAW Offset),文件偏移地址从PE文件的第一个字节开始计数,起始值为0。用十六进制工具,打开文件时显示的地址就是文件偏移地址。
14.MS-DOS头
每个PE文件都是以一个DOS程序开始运行的,一旦程序在DOS在运行就能识别出来,MZ header的DOS stub(DOS块)称为_IMAGE_DOS_HEADER
0x0偏移是DOS可执行文件标记ASCII :MZ
0x3C偏移是指向PE文件头
15.什么是PE文件头
紧跟在DOS stub(_IMAGE_DOS_HEADER)是PE文件头(PE Header)是PE相关结构的NT映像头(_IMAGE_NT_HEADERS简称)PE文件头位于DOS偏移0x3CH。
_IMAGE_NT_HEADERS 由三个结构组成
0x0 PE文件标识PE…
在一个有效的PE文件里,该偏移值为0x00004550 ASCII是”PE\0\0”
0x4 FileHeader _IMAGE_FILE_HEADER
IMAGE_FILE_HEADER(映射文件头)结构包含PE文件的一些基本信息,最重要是其中的一个域指出了IMAGE_OPTIONAL_HEADER的大小,这个结构也能在COFF格式的OBJ文件的开始处找到,因此也可以称其为“COFF FILE HEADER”
0x18 Option Header _IMAGE_OPTIONAL_HEADER64
16.IMAGE_FILE_HEADER结构
IMAGE_FILE_HEADER STRAUCT
0x4 Machine WORD 运行平台
对应机器码与说明:
Intel i386 0x14Ch
MIPS R3000 0x162h
MIPS R4000 0x166h
Alpha AXP 0x184h
Power PC 0x1F0h
0x6 NumberOfSections WORD 文件的区块数
0x8 TimeDateStamp DWORD 文件创建日期和时间
0xC PointerToSymbolTable DWORD 指向符号表(用于调试)
0x10 NumberOfSymbols DWORD 符号表中的符号个数(用于调试)
0x14 SizeOfOptionalHeader WORD IMAGE_OPTIONAL_HEADER结构大小
PE32机器码通常为0xE0h、PE32+机器码通常为0xF0h
0x16 Characteristics WORD 文件属性
该字段值可以通过运算得出,EXE文件一般为0x010h、DLL文件一般为0x2102h
属性字段含义
0x1h 文件不存在重定位信息
0x2 文件可执行,如果为0一般是链接时出问题了
0x4 行号信息被移除
0x8 符号信息被移除
0x20 应用程序可以通过处理超过2GB的地址,该功能从NT SP3开始支持的,因为大部分数据库服务器需要很大的内存,而NT仅提供2GB给应用程序,所以从NT SP3开始,通过加载/3GB参数,可以使用应用程序被分配2~3GB区域的地址,而该出原来属于系统内存区
0x80 处理机低位字节是相反的
0x100 目标平台为32位机器
0x200 .DBG 文件的调试信息被移除
0x400 如果映像文件在可移动设备中,则先复制到交换文件中在运行
0x800 如果映像文件在网络中,则复制到交换文件后运行
0x1000 系统文件
0x2000 文件是DLL文件
0x4000 文件只能运行在单处理器上
0x8000 处理机的高位字节时相反的
17.IMAGE_OPTIONAL_HEADER结构
PE32和PE32+的IMAGE_OPTIONAL_HEADER结构有少许不同
关键偏移:
0x18 WORD 标志字
PE32标志字为010B、PE32+标志字为020B、ROM映像0x0107
0x1C DWORD 所有含有代码的区块大小
0x20 DWORD 所有初始化数据区块的大小
0x24 DWORD 所有未初始化
0x28 DWORD 程序执行入口RVA
0x2C DWORD 代码区块起始RVA
0x30 DWORD 数据块区起始RVA
0x34 DWORD 程序默认装载基址
0x38 DWORD 内存中区块的对齐值
0X3C DWORD 文件区块的对齐值
0x50 DWORD 映像载入内存后的总尺寸
IMAGE_OPTIONAL_HEADER64结构有少许变化
PE32中BaseOfData域不存在与PE32+中,在PE32+中Magic的值是0x020B。
18.SectionAlignment 内存中区块的对齐值PE32和PE32+分别是多少
SectionAlignment载入内存时的区块对齐大小,每个区块被加载入的地址必定是本字段指定数值的整数倍,默认的对齐尺寸是目标CPU的页尺寸,对运行在Windows 9x/Me 下的用户模式可执行文件,最小的对齐尺寸是每页0x1000(4KB),这个字段可以通过链接器/ALIGN开关来设置,在IA-64上,这个字段是按8KB排列的。
19.请讲讲FileAlignment文件中区块对齐值
FileAlignment磁盘上PE文件内的区块对齐大小,组成块的原始数据必须保证从本字段的倍数地址开始,对于x86可执行文件这个值通常是0x200或者0x1000,这是为了保证块总是从磁盘的扇区开始,这个字段的功能等价于NE格式文件中段/资源对齐因子,使用不同版本的Microsoft链接器,默认值会改变,这个值必须是2的幂,其最小值0x200,而且如果SectionAlignment小于CPU的页尺寸,这个域必须与SectionAlignment匹配。
20.IMAGE_OPTIONAL_HEADER中的CheckSum的作用
CheckSum映像的校验和,IMAGEHLP.DLL中的CheckSumMappFile函数可以计算该值,一般的EXE文件该值可以为0,但一些内核模式的驱动和系统DLL必须有一个校验和,当链接器的/RELEASE开关被使用时,校验和被置于文件中。
21.IMAGE_DATA_DIRECTORY结构与数组
IMAGE_DATA_DIRECTORY是位于IMAGE_OPTIONAL_HEADER里面的,结构表现形式为DataDirectory[16],IMAGE_OPTIONAL_HEADER结构包含有16个IMAGE_DATA_DIRECTORY。
DataDirectory[16]数据目录表,由数个相同的IMAGE_DATA_DIRECTORY结构组成,指向输出表,输入表,资源块等数据,IMAGE_DATA_DIRECTORY的结构定义如下
IMAGE_DATA_DIRECTORY STRUCT
VirtualAddress DWORD 数据块的起始地址
Size DWORD数据块的长度
IMAGE_DATA_DIRECTORY ENDS
22.IMAGE_SECTION_HEADER结构
区块:
在PE文件头与原始数据之间存在一个区块表(Section Table)区块表中包含了每个块在映像中的信息,分别指向不同的块实体,比如.text块、.rdata块、
区块表:
紧跟在IMAGE_NT_HEADER的是区块表,它是一个IMAGE_SECTION_HEADER结构数组,每个IMAGE_SECTION_HEADER结构包含了它所关联的区块信息,例如位置、长度、属性、该数组IMAGE_SECTION_HEADER结构定义
IMAGE_SECTION_HEADER STRUCT
Name BYTE8 DUP 8字节的块名
union Misc
PhysicalAddress DWORD
VirtualSize DWORD
Ends
VirtualAddress DWORD 区块RVA地址
SizeOfRawData DWORR 在文件中对齐后的尺寸
PoiniterToRawData DWORD 在文件中的偏移
PoiniterToRelocations DWORD 在OBJ文件中的使用,重定位的偏移
PoiniterToLineumbers DWORD 行号表的偏移
NumberOfRelocations WORD 在OBJ文件中使用,重定位的偏移
NumberOfLineumbers WORD 行号表中行号的数目
Characteristics DWORD 在区块的属性
IMAGE_SECTION_HEADER ENDS
23.常见区块与说明
区块中的数据逻辑通常是关联的,PE文件一般至少有两个区块,一个是代码块,另一个是数据块,每个区块都有自己特定的名字这个名字用于表示区块的用途。
.text 默认的代码区块,它的内容全是指令,PE文件运行在32位方式下,不受16位段的约束,所以没有理由把代码放到不同的区块中,链接器把所有目标文件的.text块链接成一个大的.text,如果使用BorlandC++,其编译器将产生的代码存储于名为code的区域。
.data 默认的读/写数据区块,全局变量、静态变量一般都存放在这里
.rdata 默认的只读数据区块,但程序很少用到该块中的数据,至少有两种情况要用到.rdata块,一个是Mircorsotf链接器产生的EXE文件中,用于存放说明字符串,如果程序的DEF文件中指定了DESCRIPTION,字符串会出现在.rdata块中。
.idata 包含其他外来DLL的函数及数据信息,即输入表,将.idata区块合并到另一个区块已成惯例,典型的是.rdata区块,链接器默认仅在创建一个Release模式的可执行文件时才会将.idata区块合并到另一个区块中。
.edata 输出表,当创建一个输出API或数据的可执行文件时,链接器会创建一个EXE文件,这个.EXP文件包含了一个.edata区块,它会被加入最后的可执行文件中,与.idata区块一样,.edata区块也经常被发现合并到了.text或.tdata区块中。
.rsrc 资源,包含模块的全部资源,例如图标,菜单,位图等,这个区块是只读的,无论如何都不应该命名为.rsrc以外的名字,也不能被合并到其他区块中。
.bss 未初始化数据,很少使用,取而代之的是执行文件的.data区块的VirtualSize被扩展到足够大以存放未初始化的数据
.crt 用于支持C++运行时(CRT)所添加的数据
.tls TLS的意思是线程局部存储,用于支持通过_declspec(thread)声明的线程局部存储变量数据,即包括数据的初始化值,也包括运行时所需要的额外变量。
.reloc 可执行文件的基址重定位,基址重定位一般只是DLL文件需要,而不是exe文件需要,在Release模式下,链接器不会给EXE文件加上基址重定位,重定位可以在链接时通过/FIXED开关关闭
.sdata 相对于全局指针的可被定位的短的读写数据,用于IA-64和其他使用一个全局指针寄存器的体系结构,IA-64上的常规大小的全局变量存放在这个区块里。
.pdata 异常表,包含一个CPU特定的IMAGE_RUNTIME_FUNCTION_ENTRY结构数组,DataDirectorty中的IMAGE_DIRECTORY_ENTRY_EXCEPTION指向它,它用于异常处理,是基于表的体系结构,就像IA-64,唯一不使用基于表的异常处理架构的是x86
.debug S O B J 文 件 中 C o d e v i e w 格 式 符 号 , 这 是 一 个 变 量 长 度 的 C o d e V i e w 格 式 的 符 号 记 录 流 。 . d e b u g S OBJ文件中Codeview格式符号,这是一个变量长度的CodeView格式的符号记录流。 .debug SOBJCodeviewCodeView.debugT OBJ文件中Codeview格式的类似记录,这是一个变量长度的Codeview格式的类型记录流
.debug$P 当使用预编译的头时,可以在OBJ文件中找到他。
.drectve 包含链接器命令,只能在OBJ文件中找到他,命令是能被传递给链接器命令的字符串。
.didat 延迟载入的输入数据,只能在非Release模式的可执行文件中找到。在Release模式下,延迟载入的数据会被合并到另一个区块中。
24.C++如何高速编译器将数据插入一个数据块
Vistual C++中用#pragma来声明,告诉编译器将数据插入一个区块
例子: #pragma data_seg(“MY_DATA”) .data变为MY_DATA
25.文件偏移与虚拟地址转换
硬盘对齐值是0x200,内页对齐值是0x1000因此内存RVA需要转换之后才能得到硬盘地址。
(25.1)MS-DOS、PE、块表,内存与硬盘偏移是一样的,但是空余的部分
(小于0x1000)内存以0x0补充。
(25.2)各个区块在磁盘与内存中的起始地址差值
区块 虚拟偏移量 文件偏移量 差值
.text 0x1000h 0x400h 0xC00h(0x1000-0x400)
.rdata 0x2000h 0x600h 0x1A00h(0x2000-0x600)
.data 0x3000h 0x800h 0x2800h (0x3000-0x800)
(25.3)转换公式
虚拟地址(VA)为0x401112h(属于.text区块,差值0xC00)
计算公式:
File Offset = VA-ImageBase -差值
0x401112h-0x400000h-0xC00=512h
26.什么是输入表
可执行文件使用来自其他DLL的代码或数据的动作叫做输入,当PE文件被载入时Windows加载器的工作之一就是定位所有被输入的函数和数据,并让正在载入的文件可以使用那些地址,这个过程是通过PE文件的输入表(Import Table 简称IT也称导入表)完成的,输入表中保存的是函数名和驻留的DLL名等动态链接所需要的信息,输入表在软件外壳技术中的地位非常重要。
在PE文件内有一组数据结构,它们分别对应于被输入的DLL,每一个这样的结构都给出了被输入的DLL名称并指向一组函数DLL,这组函数指针称为输入地址表(Import Address Table IAT),每一个被引入的API在IAT里都有保留的位置,在那里它将被Windows加载器写入输入函数的地址,一旦模块被载入,IAT中将包含所有调用输入函数的地址。
27.什么是隐式链接DLL和运行期显式链接DLL
隐式链接DLL:
对磁盘上的PE文件来说,它无法得知这些输入函数在内存中的地址,只有当PE文件载入内存后,Windows加载器将相关DLL载入,并将调用输入函数的指令和函数实际所处联系起来,当应用程序调用一个DLL的代码和数据时,它被隐式地链接到DLL,这个过程由Windows加载器自动完成。
运行期显式链接DLL:
通过LoadLibrary函数和GetProcAddress函数完成。
28.IMAGE_IMPORT_DESCRIPTOR是什么结构
IMPORT_DECRIPTOR是输入表的结构,在PE文件头的可选映像头中,数据目录表(IMAGE_DATA_DIRECTORY)的第2个成员指向数据表,输入表是一个以IMAGE_IMPORT_DESCRIPTOR(IID)数组开始,每个被PE文件隐式链接的DLL,都有一个IID,在这个数组中,没有字段指出该结构数组的项数,但是它最后一个单元是NULL,由此可以得出数组个数。
例如某个PE文件从两个DLL文件中引入函数,因此存在两个IID结构来描述这些DLL文件,并在两个IID结构的最后一个由一个内容全为0的IID结构体来作为结束。
29.IMAGE_IMPORT_DESCRIPTOR(IID)结构说明
IMAGE_IMPORT_DESCRIPTOR STRUCT
union
Characteristics DWORD
OriginalFirstThunk DWORD
ends
TimeDateStamp DWORD
ForwarderChain DWORD
Name DWORD
FirstThunk DWORD
IMAGE_IMPORT_DESCRIPTOR ENDS
30.IMAGE_THUNK_DATA结构的作用
IMAGE_THUNK_DATA是IMAGE_IMPORT_DESCRIPTOR结构中OriginalFirstThunk(INT输入名称表)和FirstThunk(IAT表)属性的结构,INT是是一个IMAGE_THUNK_DATA结构数组,数组中每一个IMAGE_THUNK_DATA结构都指向IMAGE_IMPORT_BY_NAME结构,数组以一个内容为0的IMAGE_THUNK_DATA结构结束,FirstThunk包含指向输入地址表(IAT),IAT也是一个IMAGE_THUNK_DATA结构的数组。
IMAGE_THUNK_DATA结构:

IMAGE_THUNK_DATA STRUCT
union u1
ForwarderString DWORD 指向一个转向者字符串的RVA
Function DWORD 被输入的函数的内存地址
Ordinal DWORD 被输入的API的序数值
AddressOfData 指向IMAGE_IMPORT_BY_NAME
ends
IMAGE_THUNK_DATA ENDS
当IMAGE_THUNK_DATA值最高位为1时,表示函数以序号方式输入,这时低31位(或者一个64位就是低63位)被看成一个函数序号,当双字的最高位为0时,表示函数以字符串类型的函数名方式输入,这时双字的值是一个RVA,指向一个IMAGE_IMPORT_BY_NAME结构。
31.IMAGE_IMPORT_BY_NAME结构及作用
IMAGE_IMPORT_BY_NAME结构
Hint WORD
Hint:
本函数在其所驻留DLL的输出表中的序号,该域被PE装载器用来在DLL的输出表里快速查询函数,该值不是必需的,一些链接器将它设置为0。
Name BYTE
Name:
含有输入函数的函数名,函数名是一个ASCII字符串,以NULL结尾,注意这里虽然将Name的大小以字节为单位进行定义,但其实它是一个可变尺寸域,由于没有更好的表示方法,只要在定义上写成BYTE。
IMAGE_IMPORT_NAME_END
32.INT和IAT表的区别是什么
INT:输入名称表
INT是IMAGE_IMPORT_DESCRIPTOR结构中OriginalFirstThunk属性,该属性不可写
OriginalFirstThunk是IMAGE_THUNK_DATA结构,功能为Ordinal属性、AddressOFdata属性、ForwarderString(不清楚是否属于)INT表主要作用是现实API序号和函数名
IAT:输入地址表
IAT是IMAGE_IMPORT_DESCRIPTOR结构中的FirstThunk属性结构,该IMAGE_THUNK_DATA结构主要功能室被输入函数的内存地址,该地址一般为PE装载器重写的地址。
33.什么是基址重定位
链接器生成一个PE文件时,会假设文件在执行时被装载到默认的基地址处,并把code和data的相关地址都写入PE文件,如果载入时将默认值作为基址载入,则不需要重定位,但是,如果PE文件被装载虚拟地址内存的另一个地址中,基址被占用PE装载器会重新分配新的基址,EXE文件都是独立的虚拟地址因此不会被基址重定位,而DLL可能会发生地址被占用情况。
34.资源表和资源结构
资源用类似于磁盘目录结构方式保存,目录通常包含3层,第一层目录类似于一个文件系统的根目录,每个根目录下的目总是在它自己权限下的一个目录,第二层目录中每一个都对应于一个资源类型,每个第二层资源类型目录下的第三层目录。
(34.1)资源目录结构IMAGE_RESOURCE_DIRECTORY
该结构重点是说明了名字资源条目个数和ID数字资源条目个数
(34.2)资源目录入口结构IMAGE_RESOURCES_DIRECTORY_ENTRY
根据情况不同结构含义不同,Name字段为名称或ID当前结构用于第一层目录时,定义的是资源类型,结构用于第二层目录时,定义的资源名称,结构用于第三层目录时,定义的是代码也编号,当最高位为0时,表示字段的值作为ID使用,当最高位为1时,表示字段是最低位作为指针使用,资源名称字符串使用Unicode编码,这个指针不直接使用字符串,而是指向一个IMAGE_RESOURCE_DIR_STRING_U结构。
IMAGE_RESOURCES_DIRECTORY_ENTRY第三层目录结构中的OffsetToData将指向IMAGE_RESOURCES_DATA_ENTRY结构,该结构描述了资源数据的为位置和大小。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚构之人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值