分析
一 移动重定位
直接把整张表复制后修改目录表的RVA即可
二 修改ImageBase
5.17 在看了后面的课程理解了修改ImageBase修复重定位表其实是加载PE文件时系统做的事情, 这个函数相当于在仿照这件事 怪不得之前写错了重定位表的值依然可以运行…
①首先当然是修改ImageBase
②遍历重定位表中的数据加上新旧ImageBase的差值, 就是在打印的基础上加上修改数据
重定位表的结构
SECTION为所属区段, RVA为大表, items为有多少数据(SizeofBlock-8)/2 因为小表为word
RVA为要修改数据的地址(非真实地址) offset为文件偏移 type为数据属性
FarAddress为真正的地址也是修改imagebase后应该修改的值
数据偏移
重定位表的结构是由各个Block组成, 每个Block的前八个字节为RVA和本块的SIZE
11000转换FOA后为8A00 对应2
数据地址应为小表+大表如第一项数据60F+011000=1160F
转换为FOA后为A0F 对应4 5
高四位为3 属性 对应6
真实地址为1001B002 对应7
也就是要修改的值 加上与旧IMAGEBASE的差值即可
代码
differenceOfImageBase = newImageBase - header.pOptionalHeader->ImageBase;
while (pBaseRelocation->SizeOfBlock)
{
//要修改的数据大表在文件中的偏移 大表 + word 型偏移
foaOfBlock = (DWORD)pBaseRelocation - (DWORD)pFileBuffer;
currentBlockItems = (pBaseRelocation->SizeOfBlock - 8) / 2; //word 表示
addressOf_rvaOfData = pBaseRelocation->VirtualAddress;
header.pOptionalHeader->ImageBase = newImageBase;
while (--currentBlockItems)
{
rvaOfData = ((*(WORD*)(foaOfBlock + (DWORD)pFileBuffer + 8)) & 0x0fff) + addressOf_rvaOfData;
foaOfData = (DWORD)RvaDataToFoaData(pFileBuffer, rvaOfData);
pFarAddress = (DWORD*)(foaOfData + (DWORD)pFileBuffer);
*pFarAddress += differenceOfImageBase;
foaOfBlock += 2;
}
pBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pBaseRelocation + pBaseRelocation->SizeOfBlock);
}
结果
一些问题
1 在修改后调用发现反汇编中并没有改变, 然后想到在win10上是动态加载Imagebase, 修改OptionalHeader中的DLLCharacteristic低8位为00即可 具体见ASLR pe分析
2
当IMAGEBASE>7FFFFFFF后系统会自动修正
ps: 建了个学习讨论群, 欢迎新朋友加入:1094301686