PE文件格式(基址重定位)

华盟原创文章投稿奖励计划

向进程的虚拟内存加载PE文件(EXE/DLL/SYS)时,文件会被加载到PE头的ImageBase所指的地址处。若加载的是DLL(SYS)文件,且在ImageBase位置处已经加载了其他DLL(SYS)文件,那么PE装载器就会将其加载到其他未被占用的空间。这就涉及PE文件重定位的问题


PE重定位是指PE文件无法加载到ImageBase所指的位置,而是被加载到其他地址时发生的一系列处理行为。在PE文件中,重定位表往往单独作为一块,用“.reloc”表示

//
// Based relocation format.
//

typedef struct _IMAGE_BASE_RELOCATION {
    DWORD   VirtualAddress;        // RVA,这组重定位数据的开始的地址,各重定位项的地址加上这个指才是该重定位项的完整RVA地址
    DWORD   SizeOfBlock;        // 当前重定位数据结构的大小,以字节位单位,减8就是TypeOffset数组大小
//  WORD    TypeOffset[1];          // 以注释形式存在,是一个数组,每项大小位2字节,共16位,其中高4位表示重定向的类型,低12位表示重定位的地址
} IMAGE_BASE_RELOCATION;
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;

//
// 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_MACHINE_SPECIFIC_5    5
#define IMAGE_REL_BASED_RESERVED              6
#define IMAGE_REL_BASED_MACHINE_SPECIFIC_7    7
#define IMAGE_REL_BASED_MACHINE_SPECIFIC_8    8
#define IMAGE_REL_BASED_MACHINE_SPECIFIC_9    9
#define IMAGE_REL_BASED_DIR64                 10                // 出现在64位PE文件中,对指向的整个地址进行修正

在程序中涉及到直接寻址的指令都需要进行重定位处理

PE文件格式(基址重定位) 

如下程序的数据目录表指向重定位表的指针是00005000h,换算成文件偏移地址就是00000E00h。

PE文件格式(基址重定位) 
PE文件格式(基址重定位) 

VirtualAddress:00001000
SizeOfBlock:00000010((10h-8h)/ 2h = 4h),4个重定位数据
  重定位数据1:300F
  重定位数据2:3023
  重定位数据3:0000(用于对齐)
  重定位数据4:0000(用于对齐)

PE文件格式(基址重定位) 

PE文件格式(基址重定位) 

华盟知识星球入口

分别指向00402000和00403030,即为所需要重定位的数据

本文原创,作者:congtou,其版权均为华盟网所有。如需转载,请注明出处:https://www.77169.net/html/275292.html

发表评论