windows PE Image 文件分析(6)--- .reloc 节与 base relocation table
来源:互联网 发布:电脑视频剪辑软件中文 编辑:程序博客网 时间:2024/06/11 13:45
.reloc 节和 base relocation table 仅存在于 Image 文件中,用于当映像被加载运行的 ImageBase 改变后,对映像内的使用的地址进行重定位。
需要进行 ImageBase 重定位的映像性能会变得很糟糕。32 位的应用程序在 64 位系统上运行就是一个典型的例子。
下面以前面的 32 位 helloworld.exe 映像为例子
1. ImageBase 重定位
编译器会为每个映像建立一个首选的 ImageBase 值,ImageBase 是映像被加载运行时所有地址的基地址,因此 ImageBase 显得非常重要。
1.1 映像的 ImageBase 值
典型地 helloworld.exe 映像的 ImageBase 被设为:0x00400000
OPTIONAL HEADER VALUES
10B magic # (PE32)
10.00 linker version
3C00 size of code
12000 size of initialized data
0 size of uninitialized data
1120D entry point (0041120D) @ILT+520(_wWinMainCRTStartup)
1000 base of code
1000 base of data
400000 image base (00400000 to 00428FFF)
1000 section alignment
200 file alignment
5.01 operating system version
0.00 image version
5.01 subsystem version
0 Win32 version
29000 size of image
400 size of headers
0 checksum
2 subsystem (Windows GUI)
32 位映像的 ImageBase 都被设为 0x00400000,而 64 位映像的 ImageBase 被设为 0x00000001_40000000
1.2 映像内的地址使用
下面是从 helloworld.exe 映像中的 .text 节摘下来的数据:
00411490: 6A 64 68 00 72 41 00 6A 67 8B 45 08 50 FF 15 C0 jdh.rA.jg.E.P?.à
004114A0: 83 41 00 3B F4 E8 D2 FC FF FF 8B F4 6A 64 68 38 .A.;?èòü??.?jdh8
注意上面的蓝色粗体部分,实际上这是一条 call 指令的机器代码,这条指令是:
0041149D: FF 15 C0 83 41 00 call dword ptr [004183C0h]
实际上,这就是调用 LoadString() 函数的一条指令,LoadString() 的地址就放在 0x004183C0 地址上。
当映像被加载后的 ImageBase 还是 0x00400000,那么这个映像就不需要 ImageBase 重定位,但是很遗憾,特别是当 32 位程序在 64 位系统上运行时,这个情况就发生。
1.3 ImageBase 重定位
在我的实例中,这一次 helloworld.exe 的运行,ImageBase 被加载到 0x012b0000,没错就需要进行 ImageBase 重定位处理。
call dword ptr [004183C0h]
这个情况下,这个 0x004183C0 地址就会产生错误,加载器需要将它重新重位在:0x012C83C0 地址上。
这个 0x012C83C0 是等于:0x004183C0 - 0x00400000 + 0x012b0000 = 0x012C83C0
计算方法就是得到基于 ImageBase 的偏移量再加上新的 ImageBase 值,这个 0x012C83C0 就是正确的函数地址:
012C14B9 FF 15 C0 83 2C 01 call dword ptr [__imp__LoadStringW@16 (12C83C0h)]
上面就是 visual studio 2010 调试下得出的 call 指令
2. .reloc 节
现在转入正题,看看 helloworld.exe 映像的 .reloc 节,如下表:
helloworld.exe 的 .reloc 位置在 0x00428000(ImageBase + VritualAddress),它在映像文件的位置是 0x00015400 占用 0x600 bytes 的文件空间
3. base relocation table
base relocation table 存放在 .reloc 节里,大小为 0x340 bytes
base relocation table 由 IMAGE_BASE_RELOCATION 结构和它的 Entry 组成
3.1 IMAGE_BASE_RELOCATION 结构
这个结构在 WinNT.h 的定义为:
//
// Based relocation format.
//
typedef struct _IMAGE_BASE_RELOCATION {
DWORD VirtualAddress;
DWORD SizeOfBlock;
// WORD TypeOffset[1];
} IMAGE_BASE_RELOCATION;
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;
VirtualAddress 是 base relocation table 的位置,它是一个 RVA 值,SizeOfBlock 是 Base Relocation Table 的大小
3.2 Entry 结构
Entry 结构只有一个 WORD 值,它紧跟着 IMAGE_BASE_RELOCATION 结构后面,但是这个 WORD 却分为两个部分:
这个 12 位的 Offset 值是基于 IMAGE_BASE_RELOCATION 结构的 VirtualAddress, 而 VirtualAddress 是基于 ImageBase 的 RVA 值
因此最终的 Offset 值应该是 ImageBase + VirtualAddress + Offset
在 WinNT.h 中定义了 Base Relocation Table 的类型:
//
// Based relocation types.
//
#define IMAGE_REL_BASED_ABSOLUTE 0
#define IMAGE_REL_BASED_HIGH 1
#define IMAGE_REL_BASED_LOW 2
#define IMAGE_REL_BASED_HIGHLOW 3
#define IMAGE_REL_BASED_HIGHADJ 4
#define IMAGE_REL_BASED_MIPS_JMPADDR 5
#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
#define IMAGE_REL_BASED_IA64_IMM64 9
#define IMAGE_REL_BASED_DIR64 10
大部分的 Base Relocation Table 类型都是 IMAGE_REL_BASED_HIGHLOW 类型,表示被重定位的是 32 位的值。
举个例子,有如下的 Entry 值:
- 93 34
这个 Entry 是 0x3493,那么 Base Relocation Table 类型是 3 也就是 IMAGE_REL_BASED_HIGHLOW 类型,它的 Offset 值是 0x0493,那么需要重定位的位置在 0x00411493
这个值计算方法是:ImageBase + VirtualAddress + Offset = 0x00400000 + 0x11000 + 0x493 = 0x00411493
4. helloworld.exe 映像的 Base Relocation Table
00428000 00 10 01 00 // VirtualAddress = 0x00011000
00428004 DC 00 00 00 // SizeOfBlock = 0x000000DC
// Entries
00428008 93 34 // type = 3, offset = 493
0042800A 9F 34 // type = 3, offset = 49F
0042800C AF 34 // type = 3, offset = 4AF
0042800E BB 34 // type = 3, offset = 4BB
00428010 F4 34 // type = 3, offset = 4F4
00428012 10 35 // type = 3, offset = 510
00428014 2F 35 // type = 3, offset = 52F
00428016 46 35 // type = 3, offset = 546
00428018 59 35 // type = 3, offset = 559
0042801A 6F 35 // type = 3, offset = 56F
0042801C 94 35 // type = 3, offset = 594
0042801E A0 35 // type = 3, offset = 5A0
... ...
004280DC 00 20 01 00 // VirtualAddress = 0x00012000
004280E0 20 01 00 00 // SizeOfBlock = 0x00000120
004280E4 0C 30 // type = 3, offset = 00C
004280E6 15 30 // type = 3, offset = 015
004280E8 1E 30 // type = 3, offset = 01E
004280EA 23 30 // type = 3, offset = 023
004280EC 4D 30 // type = 3, offset = 04D
004280EE 57 30 // type = 3, offset = 057
... ...
第 1 个 base relocation table 的 size 是 0xDC bytes,因此,下一个 base relocation table 就在 0x004280DC 处
下面是使用 dumpbin 得出的 base relocation table 结果:
BASE RELOCATIONS #7
11000 RVA, DC SizeOfBlock
493 HIGHLOW 00417200 ?szTitle@@3PA_WA (wchar_t * szTitle)
49F HIGHLOW 004183C0 __imp__LoadStringW@16
4AF HIGHLOW 00417138 ?szWindowClass@@3PA_WA (wchar_t * szWindowClass)
4BB HIGHLOW 004183C0 __imp__LoadStringW@16
4F4 HIGHLOW 004183C4 __imp__LoadAcceleratorsW@8
510 HIGHLOW 004183C8 __imp__GetMessageW@16
52F HIGHLOW 004183CC __imp__TranslateAcceleratorW@12
546 HIGHLOW 004183D0 __imp__TranslateMessage@4
559 HIGHLOW 004183D4 __imp__DispatchMessageW@4
56F HIGHLOW 00411590
594 HIGHLOW 00411598
5A0 HIGHLOW 004115A4
... ...
12000 RVA, 120 SizeOfBlock
C HIGHLOW 00417734 ___native_startup_state
15 HIGHLOW 00417734 ___native_startup_state
1E HIGHLOW 00415618 ___xi_z
23 HIGHLOW 0041530C ___xi_a
4D HIGHLOW 0041733C
57 HIGHLOW 00417734 ___native_startup_state
与 dumpbin 的结果是相符的。
版权 mik 所有,转载请注明出处
- windows PE Image 文件分析(6)--- .reloc 节与 base relocation table
- windows PE Image 文件分析(5)--- .rsrc 节与 resource table
- windows PE Image 文件分析(3)--- .idata 节与 import table
- windows PE Image 文件分析(5)--- .rsrc 节与 resource table
- windows PE Image 文件分析(1)
- windows PE Image 文件分析(2)--- .text 节
- windows PE Image 文件分析
- PE 文件中.reloc节 删除记录
- PE文件学习笔记(四):重定位表(Relocation Table)解析
- windows PE Image 文件分析(4)--- 导入函数的绑定
- 【EXE PE】.rsrc 节与 resource table
- PE文件-分析vc示范所有代码[包含EXPORT TABLE]
- PE 格式之 relocation
- 深入浅出Windows PE(一) PE文件头
- 深入浅出Windows PE(一) PE文件头
- 深入浅出Windows PE(一) PE文件头
- Windows Pe 第三章 PE头文件(上)
- Windows Pe 第三章 PE头文件(中)
- windows PE Image 文件分析(4)--- 导入函数的绑定
- windows PE Image 文件分析(5)--- .rsrc 节与 resource table
- 【转载】DSP看门狗定时器
- 个人的Spring
- LeetCode Remove Element
- windows PE Image 文件分析(6)--- .reloc 节与 base relocation table
- Java 代码优化常见注意点
- Effective Objective-C 2.0: Item 37: Understand Blocks
- linux用户态与内核态通信netlink
- Binary Tree Level Order Traversal
- Oracle之 dmp导入/导出、数据库操作等过程中的字符集问题
- 国务院办公厅关于2014年部分节假日安排的通知
- Galileo Ganymede Europa 代表不同的版本
- cocos2d-x在win32测试时响应键盘消息