pRelocTable=&(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]);
//得到第一个重定位块
pRelocBlock=(PIMAGE_BASE_RELOCATION)(hModule+pRelocTable->VirtualAddress);
//开始处理所有重定位数据
do
{//处理一个接一个的重定位块,最后一个重定位块以RAV=0结束
//需要重定位的个数,是本块的大小减去块头的大小,结果是以DWORD表示的大小
//而重定位数据是16位的,因此除以2
int numofReloc=(pRelocBlock->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2;
//printf("Reloc Data num=%d\n",numofReloc);
//重定位数据是16位的
WORD minioffset=0;
WORD *pRelocData=(WORD*)((char*)pRelocBlock+sizeof(IMAGE_BASE_RELOCATION));
for (i=0;i<numofReloc;i++)//循环,或直接判断*pData是否为0也可以作为结束标记
{
DWORD *RelocAddress=0;//需要重定位的地址
//重定位的高4位是重定位类型,
if (((*pRelocData)>>12)==IMAGE_REL_BASED_HIGHLOW)//判断重定位类型是否为IMAGE_REL_BASED_HIGHLOW
{
//计算需要进行重定位的地址
//重定位数据的低12位再加上本重定位块头的RAV即真正需要重定位的数据的RAV
minioffset=(*pRelocData)&0xFFF;//小偏移
//模块基址+重定位基址+每个数据表示的小偏移量
RelocAddress=(DWORD*)(hModule+pRelocBlock->VirtualAddress+minioffset);
//对需要重定位的数据进行修正
//修正方法:减去IMAGE_OPTINAL_HEADER中的基址,再加上实际基址即可
*RelocAddress=*RelocAddress-pOptHeader->ImageBase+hModule;
}
//指向下一个重定位数据
pRelocData++;
}
//指向下一个重定位块
pRelocBlock=(PIMAGE_BASE_RELOCATION)((char*)pRelocBlock+pRelocBlock->SizeOfBlock);
}while (pRelocBlock->VirtualAddress);