DWORD copyBaseRelocation2NewSection(IN PVOID pFileBuffer,OUT PVOID* pNewFileBuffer)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
if(!pFileBuffer)
{
printf("FileBuffer無效!\n");
free(pFileBuffer);
return;
}
if(*(PWORD)pFileBuffer != IMAGE_DOS_SIGNATURE)
{
printf("不是有效的PE文件\n");
free(pFileBuffer);
return;
}
//新增節表
PVOID pTemOfNewFileBuffer = NULL;
DWORD sizeOfNewBuffer = AddNewSection(pFileBuffer, &pTemOfNewFileBuffer);
free(pFileBuffer);
if(!pTemOfNewFileBuffer)
{
printf("新節表添加失敗!\n");
return;
}
if(*(PWORD)pTemOfNewFileBuffer != IMAGE_DOS_SIGNATURE)
{
printf("不是有效的PE文件\n");
free(pTemOfNewFileBuffer);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pTemOfNewFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)(pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER)(pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionHeader + pPEHeader->SizeOfOptionalHeader);
//定位數據目錄
PIMAGE_DATA_DIRECTORY pDataDirectory = pOptionHeader->DataDirectory;
//獲取數據目錄數組中的第6個結構,重定位表,記錄重定位數據塊的RVA和Size(沒用)
DWORD RVAOfBaseRelocationDataDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
//RVA轉FOA找到第一個重定位數據塊
DWORD FOAOfBaseRelocation = RVA2FOA(pTemOfNewFileBuffer,RVAOfBaseRelocationDataDirectory);
PIMAGE_BASE_RELOCATION pBASERELOCATION = (PIMAGE_BASE_RELOCATION)FOAOfBaseRelocation;
//複製
//定義pLastSection--新節在拉伸後的內存(pTemOfNewFileBuffer)中的地址
PDWORD pLastSection = (PDWORD)((DWORD)pTemOfNewFileBuffer + (pSectionHeader + pPEHeader->NumberOfSections)->PointerToRawData);
//循環複製重定位數據塊到新節,結束條件是最後一個結構的VirtualAddress與SizeOfBlock都爲0
PIMAGE_BASE_RELOCATION pTemOfBASERELOCATION = pBASERELOCATION;
while(*(pTemOfBASERELOCATION)->VirtualAddress != 0 && *(pTemOfBASERELOCATION)->SizeOfBlock != 0)
{
memcpy(pLastSection,pBASERELOCATION,pTemOfBASERELOCATION->SizeOfBlock);
pLastSection = (PDWORD)((DWORD)pLastSection + pTemOfBASERELOCATION->SizeOfBlock);
pTemOfBASERELOCATION = (PIMAGE_BASE_RELOCATION)((DWORD)pTemOfBASERELOCATION + pTemOfBASERELOCATION->SizeOfBlock) ;
}
//修復,使重定位表指向的重定位數據塊的新RVA,也就是新節的RVA,要把FOA轉爲RVA
pDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = pOptionHeader->ImageBase + (pSectionHeader + pPEHeader->NumberOfSections)->PointerToRawData;
//結束返回pNewFileBuffer,sizeOfNewBuffer
pNewFileBuffer = pTemOfNewFileBuffer;
pTemOfNewFileBuffer = NULL;
free(pFileBuffer);
return sizeOfNewBuffer;
}
PE:copyBaseRelocation2NewSection
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.