很笨的方法
(写过才能知道,哪些地方,需要注意,开始想的很简单,就三部,写了 一个多小时!!)
void TestMoveRelocDirectory(LPSTR lpszFile) { /* 1 新增一个节 2 把重定位的表 移动到那个节中 3 更改标志位 */ LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL; PIMAGE_DATA_DIRECTORY DataDirectory=NULL; //Header信息 pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew); pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4); pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader); pSectionHeader_ADD = pSectionHeader; //1 判断能否添加节 DWORD Header_size = pDosHeader->e_lfanew + 4 + 20 + pPEHeader->SizeOfOptionalHeader + pPEHeader->NumberOfSections*40; if(pOptionHeader->SizeOfHeaders-Header_size<80) { printf("没有可用空间填充节表\n"); free(pFileBuffer); return; } printf("空间:%d\n",pOptionHeader->SizeOfHeaders-Header_size); //添加一个节 //确定参数 PIMAGE_SECTION_HEADER pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40); pSectionHeader_ADD=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader_ADD+(pPEHeader->NumberOfSections)*40); //="NewSec"; strcpy((char*)pSectionHeader_ADD->Name,"NewSec"); pSectionHeader_ADD->Misc.VirtualSize = 0x2000; pSectionHeader_ADD->VirtualAddress = pOptionHeader->SizeOfImage; pSectionHeader_ADD->SizeOfRawData = 0x2000; pSectionHeader_ADD->PointerToRawData = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData; pSectionHeader_ADD->Characteristics = pSectionHeader->Characteristics; //填充0 LPVOID pSectionEND = (LPVOID)((DWORD)pSectionHeader_ADD+40); memset(pSectionEND,0,IMAGE_SIZEOF_SECTION_HEADER); //修改PE头信息 pPEHeader->NumberOfSections = pPEHeader->NumberOfSections +1; pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage+0x2000; //写入到文件 FILE *pOutFile = NULL; //打开文件 pOutFile = fopen("C://addSec.dll","a+b"); if(!pOutFile) { printf("无法打开文件EXE文件"); return; } //写出第一部分 printf("length: %x \n ",pSectionHeader_ADD->PointerToRawData+pSectionHeader_ADD->SizeOfRawData); size_t writeSize = fwrite(pFileBuffer,pSectionHeader_ADD->PointerToRawData,1,pOutFile); printf("WirteSize:%d\n",writeSize); //写出第二部分 LPVOID pNewBuffer=(LPVOID)malloc(0x2000); if(pNewBuffer==NULL) { printf("pNewBuffer分配空间失败\n"); return; } memset(pNewBuffer,0,0x2000); writeSize = fwrite(pNewBuffer,0x2000,1,pOutFile); //关闭文件 fclose(pOutFile); free(pFileBuffer); free(pNewBuffer); //读入添加好节的文件 pFileBuffer= ReadPEFile("C://addSec.dll"); //将重定位表的信息,放到最后一个节中 //Header信息 pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew); pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4); pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader); //最后一个节 pSectionHeader_ADD=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40); //定位Directory_Data; DataDirectory = pOptionHeader->DataDirectory; //重定位表 printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva) DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10); DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address); //定位到第一个重定位块 PIMAGE_BASE_RELOCATION pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA); PIMAGE_BASE_RELOCATION pRelocData_Start = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA); DWORD sizeOfRelocDirectory = 0; //计算重定位表的大小 while(pRelocData->VirtualAddress||pRelocData->SizeOfBlock) { DWORD RelocVirtualAddress = pRelocData->VirtualAddress; DWORD RelocSize = pRelocData->SizeOfBlock; sizeOfRelocDirectory = sizeOfRelocDirectory + RelocSize; pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocData + RelocSize); } //起始位置pRelocData //移动 PDWORD myRelocLoc = (PDWORD)pSectionHeader_ADD->PointerToRawData; printf("Reloc: %x , Size: %x \n",pRelocData,sizeOfRelocDirectory); //memcpy(myRelocLoc,pRelocData,sizeOfRelocDirectory); LPVOID destStart = (LPVOID)((DWORD)pFileBuffer + (DWORD)myRelocLoc); printf("pFileBuffer:%x, myRelocLoc: %x \n",pFileBuffer,destStart); LPVOID srcStart = (LPVOID)(pRelocData_Start); memcpy(destStart,srcStart,sizeOfRelocDirectory); //修改重定位表的参数 DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = FileOffsetToRVA(pFileBuffer,pSectionHeader_ADD->PointerToRawData); //写出到dll中 DWORD FileSize = pSectionHeader_ADD->PointerToRawData + pSectionHeader_ADD->SizeOfRawData; WirteToFile(pFileBuffer,FileSize,"C://addNewSec.dll"); }
0则评论给“重定位表的移动”