目录

基址重定位表

目录

基址重定位表中罗列了硬编码地址的偏移,读取这张表就能获得准确的硬编码地址偏移,基址重定位表就是IMAGE_BASE_RELOCATION的结构体数组。
结构体定义如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
typedef struct _IMAGE_BASE_RELOCATION {  
  DWORD VirtualAddress;  // 基准地址  
  DWORD SizeOfBlock;  // 重定位块的大小  
//    WORD TypeOffset[1];  
} IMAGE_BASE_RELOCATION; //   
typedef IMAGE_BASE_RELOCATION UNALIGNED *PIMAGE_BASE_RELOCATION;  
  
#define IMAGE_SIZEOF_BASE_RELOCATION 8  
  
#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_ARM_MOV32 5  
#define IMAGE_REL_BASED_THUMB_MOV32 7  
#define IMAGE_REL_BASED_MIPS_JMPADDR16 9  
#define IMAGE_REL_BASED_IA64_IMM64 9  
#define IMAGE_REL_BASED_DIR64 10  

最后一项TypeOffset数组不是结构体成员,而是以注释的形式存在的,表示在该结构体之下会出现WORD类型的数组,并且该数组元素的值就是硬编码在程序中的地址偏移。TypeOffset是2字节16位,由4位Type和12位offser组成
/images/32b1ce20a0858750cc63cf23f5e7d9c2/11884068-32621a826a359b06.png
如图是基址重定位表,也就是一个IMAGE_BASE_RELOCATION的结构体数组,图中Page RVA即VirtualAddress, A2608位置处是第一个硬编码在程序中的地址偏移,这里的值为3800,Type是3,Offset是800,3表示IMAGE_REL_BASED_HIGHLOW,在64位PE+文件中常见的Type是A(IMAGE_REL_BASED_DIR64)。
在恶意代码中正常修改文件代码后,有时要修改指向相应区域的重定位表(为了略去PE装载器的重定位过程,常常把Type值修改为0(IMAGE_REL_BASED_ABSOLUTE))