模仿系统PE重定位实现

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);


猜你喜欢

转载自blog.csdn.net/windows_nt/article/details/30452897