网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 
中国网管联盟
Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道
 当前位置: > bitsCN.com > 网络攻防 > 黑客技术 > 系列教程 > 《加密解密 技术内幕》1.29 PE 档的基底重定位(Base Relocations)(图)  

《加密解密 技术内幕》1.29 PE 档的基底重定位(Base Relocations)(图)

2008-03-15  作者:bitsCN整理  来源:中国网管联盟  点评 投稿 收藏

当联结器产生一个 EXE 档,它假设这个文件会被加载内存的某处,并且把code 和 data

的相关假设地址都写入 EXE 文件中。如果可执行档最终被加载到虚拟地址空间的另一

个地址,没有按预期来,联结器所登记的那个地址就是错误的。储存在 .reloc 的信息就

是用来帮助 PE 加载器修正加载模块的地址。如果加载器能够把模块加载到预定地址

上,.reloc 就可以弃而不用。.reloc 中的资料项被称为「基底重定位(base relocations )

资料项」,原因是它们的用途视被加载模块的基地址而定。

和NE 格式的重定位方式不同,PE 档的作法十分简单。它们并不参考到外部DLLs 或模

组中的其它sections ,而是把image (译注)中所有可能需要修改的地址串成一个串行。

译注:文件中的模块资料被加载内存后,我们称其为模块的 "image" 。我保留这个原 文,不译它。

下面是一个例子。假设有一个可执行文件,基地址是 0x400000 。在这个 image 偏移位

置 0x2134 处是一个指针,指向一个字符串。字符串始于实际地址 0x404002 处,所以指针

内容应该是 0x404002 。你可以把文件加载,但是加载器决定把它映像到实际地址 网管u家u.bitscn@com

0x600000 处。联结器假设的基地址和实际加载的起始地址之间的差额称为 delta 。此

例之 delta 为 0x20000 。整个 image 的位置提高了 0x20000 ,其中的字符串当然也是(现

在应该是 0x604002 )。所以指向字符串的指针就错误了,delta 应该加到指针值中。

为了让 Windows 加载器有能力做这样的调整,可执行档内含许多个「基底重定位资料

项」,给那些存放指针的位置(本例为 0x2134 )使用。加载器必须把 delta 加到各个位

址上。本例之中加载器应该把 0x20000 加给原来的指针值(0x404002 ),并将结果0x604002

写回原处。图8-12 显示这个过程。



图8-12 PE 文件的基底重定位动作。

「基底重定位资料项」的格式有点儿奇怪。它们被包装为一系列连续区段,长短不一。

每一个区段描述 image 中的一个 4K page 的重定位信息。它们以一个

IMAGE_BASE_RELOCATION 结构做为开始,格式如下: 网管下载dl.bitscn.com

DWORD VirtualAddress

此一字段内含这些个「基底重定位资料项」的起始 RVA 值。每一个「基底重定位资料

项」的偏移位置必须加上此值才能够构成一个真正的 RVA ,指向「基底重定位资料项」。

DWORD SizeOfBlock

结构大小,再加上所有跟随在后的「基底重定位资料项」(都是 WORDs )。为了决定

区块中的「基底重定位资料项」的个数,先把此值减去IMAGE_BASE_RELOCATION 结

构大小(8 个字节),再除以 2 (WORD 大小)。如果此字段为 44 ,就表示有 18 个

「基底重定位资料项」:

( 44 - sizeof(IMAGE_BASE_RELOCATION) ) / sizeof(WORD) = 18

WORD TypeOffset

这并不是单独一个 WORD ,事实上它是一个 WORDs 数组。数组元素个数可由上一个

式子计算获得。每一个 WORD 的最底部 12 个位代表「基底重定位资料项」偏移位

置,但必须再加上「基底重定位资料项」区块表头的 VirtualAddress 字段值。最高的4

个位是「基底重定位资料项」的型态。对于在 Intel CPUs 中执行的 PE 档,你将看到

两种型态:

中国网管联盟bitsCN.com



·0 (IMAGE_REL_BASED_ABSOLUTE ):此一「基底重定位资料项」无意义,

只是用来充数而已,使所有「基底重定位资料项」的总共大小成为 DWORD 的

倍数。

·3 (IMAGE_REL_BASED_HIGHLOW ):把delta 值加到欲计算的RVA 值去。

另外还有其它型态,在 WINNT.H 中定义。它们大部份是给 i386 以外的CPU 使用。

图8-13 描绘出一些「基底重定位资料项」,这是 PEDUMP 的输出结果。请注意图中

的RVA 值已经被 IMAGE_BASE_RELOCATION 结构中的 VirtualAddress 字段校正过

了。

Virtual Address: 00001000 Size: 0000012C

00001032 HIGHLOW

0000106D HIGHLOW

000010AF HIGHLOW

000010C5 HIGHLOW

// Rest of chunk omitted...

Virtual Address: 00002000 Size: 0000009C

000020A6 HIGHLOW

00002110 HIGHLOW

00002136 HIGHLOW

00002156 HIGHLOW

// Rest of chunk omitted...

Virtual Address: 00003000 Size: 00000114
中国网管论坛bbs.bitsCN.com
0000300A HIGHLOW

0000301E HIGHLOW

0000303B HIGHLOW

0000306A HIGHLOW

// Rest of chunk omitted...

TAGs   定位   技术   内幕   资料   一个   加载   地址   HIGHLOW   指针   文件      
 上一篇:《加密解密技术内幕》1.28 DocNet学习笔记之Anti ILDASM研究(4千字)(图)   下一篇:《加密解密技术内幕》1.30 JIURL PE 格式学习总结(一)
《加密解密 技术内幕》1.29 PE 档的基底重定位(Base Relocations)(图) 评论:
loading.. 评论加载中…
评论:请自觉遵守互联网相关政策法规,评论不得超过250字。

验证码: 注册用户
本类热门排行:
最新推荐文章:
网管论坛交流: