概述
数据目录项的第6个结构,就是重定位表。
结构
重定位表的结构
typedef struct _IMAGE_BASE_RELOCATION {
DWORD VirtualAddress;
DWORD SizeOfBlock;
} IMAGE_BASE_RELOCATION;
typedef IMAGE_BASE_RELOCATION ,* PIMAGE_BASE_RELOCATION;
该结构体有两个成员:一个是地址,一个是大小。如下图所示:一个重定位表由多个大小SizeOfBlock的Block组成。(Block在SizeOfBlock结构之后)
VirtualAddress 当前的RVA
宽度:四字节
真正的RVA = VirtualAddress + 具体项的低12位
SizeOfBlock
宽度:四字节
当前块的总大小
Block
Block的内的数据为需要重定位的数据的情况。其中高4位表示重定位的类型。低12位表示需要重定位的数据的偏移。
Block结构每个成员四个字节,2^12位就可以完全表示4GB的内存空间。所以可以用低12位表示大偏移位置。高4位用来表示重定位数据的类型。
打印重定位表
思路: 用重定位表的FOA定位各项结构,遍历重定位表的各项结构。遍历的过程中,需要判断重定位表在哪个节。然后定位重定位表内的数据的地址与信息:
定位12位偏移
DWORD offset = (recAddr[j] & 0x0FFF) + FOA ;//12位偏移
定位高四位
WORD type = recAddr[j] >> 12;//四位
演示代码
#include <stdio.h>
#include <windows.h>
unsigned char* FileBuffer(const char* FileName);
void PrintReloadTb();
DWORD RVA2Offset(PIMAGE_NT_HEADERS pNTHeader, DWORD dwRVA);
int main(int argc, char* argv[])
{
PrintReloadTb();
return 0;
}
//打印重定位表
void PrintReloadTb()
{
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS pNtHeaders;
PI