移動重定位表到新增節

一、爲什麼要移動重定位表

數據目錄中的表是分散在各個節裏的,如果對節進行加密,操作系統找不到表,就無法加載程序。因此加密前要先把表移動到新的節裏。

二、怎麼移動

計算重定位表的大小,首先要遍歷重定位表,累加 SizeOfBlock,然後新增一個節,大小是表的大小文件對齊。最後把表複製到新增節的開頭,然後更新數據目錄的VirtualAddress指向新的重定位表。

三、代碼

// 移動重定位表到新增節,返回新緩衝區的大小
DWORD MoveRelocationTableToNewSection(LPVOID pFileBuffer, LPVOID *pNewFileBuffer, DWORD dwFileBufferSize)
{
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)(pDosHeader->e_lfanew + (DWORD)pDosHeader + 4);
	PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));
	PIMAGE_SECTION_HEADER pSectionHeader = \
		(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
	
	PIMAGE_BASE_RELOCATION pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + \
		RvaToFoa(pFileBuffer, pOptionHeader->DataDirectory[5].VirtualAddress));

	size_t i = 0;
	DWORD dwRelocationTableSize = 0;
	while (pRelocationTable->VirtualAddress || pRelocationTable->SizeOfBlock)
	{
		dwRelocationTableSize += pRelocationTable->SizeOfBlock;
		//printf("%x\n", (pRelocationTable->SizeOfBlock - 8) / 2 );
		pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocationTable + pRelocationTable->SizeOfBlock);
	}
	
	DWORD dwNewBufferSize = AddSection(pFileBuffer, pNewFileBuffer, dwFileBufferSize, \
		Align(dwRelocationTableSize, pOptionHeader->FileAlignment));
	
	pDosHeader = (PIMAGE_DOS_HEADER)*pNewFileBuffer;
	pPEHeader = (PIMAGE_FILE_HEADER)(pDosHeader->e_lfanew + (DWORD)pDosHeader + 4);
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
	
	// 修改新增節屬性爲可讀、含已初始化數據
	pSectionHeader[pPEHeader->NumberOfSections - 1].Characteristics = 0x40000040;
	// 指針指向重定位表
	pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)*pNewFileBuffer + \
		RvaToFoa(*pNewFileBuffer, pOptionHeader->DataDirectory[5].VirtualAddress));
	// 定義插入點爲新增節的起始地址
	LPVOID pInsert = (LPVOID)((DWORD)*pNewFileBuffer + pSectionHeader[pPEHeader->NumberOfSections - 1].PointerToRawData);
	// 拷貝重定位表
	memcpy(pInsert, (LPVOID)pRelocationTable, dwRelocationTableSize);
	// 更新目錄項,指向新的重定位表
	pOptionHeader->DataDirectory[5].VirtualAddress = FoaToRva(*pNewFileBuffer, \
		(DWORD)pInsert - (DWORD)*pNewFileBuffer);
	
	return dwNewBufferSize;
}

四、運行結果

修改前和修改後對比
在這裏插入圖片描述

五、完整代碼

https://blog.csdn.net/Kwansy/article/details/106234264

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章