VOID MoveRelocation(){
//定义文件头部的信息
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNtHeaders = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
PIMAGE_BASE_RELOCATION pRelocation = NULL;
LPVOID newBuffer;
LPVOID pFileBuffer = NULL;
int a = 2;
//读取文件
if (!ReadPEFile(INDLLPATH, &pFileBuffer)){
printf("读取缓冲区失败\n");
free(pFileBuffer);
}
//为每个头赋值
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeaders + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)((DWORD)pOptionalHeader + 96);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
//定位到数据目录项的第六个数据也就是重定向表
for (size_t i = 0; i < 5; pDataDirectory++, i++);
DWORD RelocationFOA = 0;
RelocationFOA = RVATOFOA(pDataDirectory->VirtualAddress, RelocationFOA, pFileBuffer);
//定位到冲顶向表在文件中的偏移
pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + RelocationFOA);
printf("sizeofcode->%x,sizeofdata->%x,sizeofundata->%x", pOptionalHeader->SizeOfCode, pOptionalHeader->SizeOfInitializedData, pOptionalHeader->SizeOfUninitializedData);
//计数,计算总的重定向表的大小
DWORD count = 0;
size_t num = 1;
for (size_t i = 1; pRelocation->VirtualAddress&&pRelocation->SizeOfBlock; i++){
count += pRelocation->SizeOfBlock;
printf("VirtualAddress->%x\tSizeOfBlock->%x\n", pRelocation->VirtualAddress, pRelocation->VirtualAddress);
pRelocation = (PIMAGE_BASE_RELOCATION)((BYTE*)pRelocation + pRelocation->SizeOfBlock);
num++;
}
printf("重定位表总大小是:%x字节 %x字 %x双字\n,表的数目是:%d\n", count, (count / 2), (count / 4), num);
//开始重新分配空间
DWORD size = 0; //加上重定位表以后的内存的总大小
DWORD SectionOneFoA = 0;
DWORD FOA = 0;
//节里边的pointertorawdata 可以计算出整个的大小
//定位到最后一个节
for (size_t i = 1; i < pFileHeader->NumberOfSections ; i++, pSectionHeader++)
{
printf("%s\n", pSectionHeader->Name);
};
printf("%s\t%x\t%x\n", pSectionHeader->Name, pSectionHeader->PointerToRawData, pSectionHeader->SizeOfRawData);
//计算出该申请空间的大小 如果重定向表的大小小于文件对齐的大小那么加上文件对齐的大小
DWORD FileAlignment = pOptionalHeader->FileAlignment;
/*int a = 0;
int j = 0;
for (size_t i = 0; count>FileAlignment; i++)
{
FileAlignment = FileAlignment*a;
a++;
}
printf("需要%x个文件对齐的空间才能保存重定位表,重定位表大小为%x,文件对齐大小为%x\n", a, count, FileAlignment);
*/
size = pSectionHeader->PointerToRawData + pSectionHeader->SizeOfRawData + FileAlignment;
pOptionalHeader->SizeOfImage += 0x400;
printf("内存总大小:%x\n", size);
//将节表移动到第一个节表
for (size_t i = 1; i < pFileHeader->NumberOfSections ; i++, pSectionHeader--)
{
printf("%s\n", pSectionHeader->Name);
}
printf("%s\n", pSectionHeader->Name);
newBuffer = malloc(size);
if (!newBuffer){
printf("内存申请失败\n");
free(newBuffer);
free(pFileBuffer);
return;
}
memset(newBuffer, 0, size);
//复制头
memcpy(newBuffer, pFileBuffer, pOptionalHeader->SizeOfHeaders);
//复制节表
PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader;
for (size_t i = 1; i < pFileHeader->NumberOfSections; i++, pSectionHeader++, pTempSectionHeader++)
{
//memcpy异常!有错误
memcpy((void*)((DWORD)newBuffer + pTempSectionHeader->PointerToRawData),
(void*)((DWORD)pFileHeader + pSectionHeader->PointerToRawData),
pSectionHeader->SizeOfRawData);
printf("%s\t", pTempSectionHeader->Name);
}
//将原始节表指针移动到初始位置
for (size_t i = 0; i < pFileHeader->NumberOfSections; i++, pSectionHeader--);
printf("%s\n",pSectionHeader->Name);
/***************************************************************/
//为新的内存空间的属性的节更改数据
PIMAGE_DOS_HEADER pNewDosHeader = NULL;
PIMAGE_NT_HEADERS pNewNtHeaders = NULL;
PIMAGE_FILE_HEADER pNewFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER pNewOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pNewSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY pNewDataDirectory = NULL;
PIMAGE_BASE_RELOCATION pNewRelocation = NULL;
pNewDosHeader = (PIMAGE_DOS_HEADER)newBuffer;
pNewNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)newBuffer + pNewDosHeader->e_lfanew);
pNewFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNewNtHeaders + 4);
pNewOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pNewFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pNewDataDirectory = (PIMAGE_DATA_DIRECTORY)((DWORD)pNewOptionalHeader + 96);
pNewSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNewOptionalHeader + pNewFileHeader->SizeOfOptionalHeader);
/***************************************************************/
printf("最后一个节的结尾地址是:%x\n", (pTempSectionHeader->PointerToRawData + pTempSectionHeader->SizeOfRawData));
//新添加一个节,然后移动重定位表,先将重定位表移动过来,然后再将原来的重定位表清零 全部填充为00
//新增节
printf("原节表数目为%d\n", pNewFileHeader->NumberOfSections);
pNewFileHeader->NumberOfSections++;
printf("节表数目%d\n", pNewFileHeader->NumberOfSections);
//定位到新增的节表的位置
/*pNewSectionHeader-》1 1,2,3,4,5,6,7,8*/
for (size_t i = 0; i < pNewFileHeader->NumberOfSections-1; i++, pNewSectionHeader++);
//为新节表复制
pNewSectionHeader->Characteristics = 0x20000060;
pNewSectionHeader->NumberOfLinenumbers = 0;
pNewSectionHeader->NumberOfRelocations = 0;
pNewSectionHeader->PointerToRawData = 0x7600;
pNewSectionHeader->PointerToRelocations = 0;
pNewSectionHeader->SizeOfRawData = 0x400;
//VirtualAddress 的大小是上一个节的virtualAddress+virtualsize
pNewSectionHeader->VirtualAddress = pTempSectionHeader->VirtualAddress + pTempSectionHeader->Misc.VirtualSize;
pNewSectionHeader->Misc.VirtualSize = pNewOptionalHeader->SectionAlignment ;
pNewSectionHeader->Name[0] = '.';
pNewSectionHeader->Name[1] = 'n';
pNewSectionHeader->Name[2] = 'e';
pNewSectionHeader->Name[3] = 'w';
//将重定位表的数据移动到新的内存空间 然后memcpy到新增的节表处 先修改完virtualAddress
//移动到最后一个节表
for (size_t i = 0; i < 5; i++, pNewDataDirectory++);
pNewDataDirectory->VirtualAddress = pNewSectionHeader->VirtualAddress+pNewSectionHeader->Misc.VirtualSize; //这是文件地址
//根据重定位表的大小分配空间
LPVOID Relocation = NULL;
Relocation = malloc(a*pOptionalHeader->FileAlignment);
memset(Relocation, 0, a*pOptionalHeader->FileAlignment);
//将重定位表的文件地址开始的地方复制到新的节表的文件地址开始的地方
memcpy((void*)(pNewSectionHeader->PointerToRawData), ((void*)((DWORD)pFileBuffer + RelocationFOA)), 0x320);
// memcpy((void*)pNewSectionHeader->PointerToRawData, Relocation, pOptionalHeader->FileAlignment*a);
size_t size_ = 0;
size_ = (pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData);
SaveFile(newBuffer, size_, OUTFILEPATH);
free(pFileBuffer);
free(Relocation);
free(newBuffer);
}