滴水三期PE文件结构之新增节
这节的练习,我断断续续研究了好久,因为我本人编程能力还有待提高所以有些痛苦,不过还好搞定了
要点:
0x1修改NumberOfSections,增加了几个节就加几,这修改不对会导致程序报错。
0x2新节内存中偏移,你需要先找到最后一个节,比较VirtualSize和SizeOfRawData,谁大取谁作为最后一个节的大小。
0x3新节文件中偏移,无需再比较,直接取SizeOfRawData;
//SizeOfFile为文件中的大小
DWORD AddSection(PVOID PFileBuffer, PVOID* PNewFileBuffer,DWORD SizeOfFile)
{
PIMAGE_DOS_HEADER PDos_Header = NULL;
PIMAGE_NT_HEADERS PNT_Header = NULL;
PIMAGE_FILE_HEADER PFile_Header = NULL;
PIMAGE_OPTIONAL_HEADER POptional_Header = NULL;
PIMAGE_SECTION_HEADER PSection_Header = NULL;
PIMAGE_SECTION_HEADER PLastSection = NULL;
PVOID PTemFile = NULL;
DWORD PSizeOfNewFile =SizeOfFile+0x1000;//增加0x1000的内存空间
if (!PFileBuffer)
{
printf("AddSection:文件无效\n");
return 0;
}
if (*((PWORD)PFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("AddSection:文件不含MZ标识\n");
return 0;
}
PDos_Header = (PIMAGE_DOS_HEADER)PFileBuffer;
if (*((PDWORD)((DWORD)PFileBuffer + PDos_Header->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("AddSection:不含PE标识,不是exe程序\n");
return 0;
}
PTemFile = (PVOID)malloc(PSizeOfNewFile);//分配临时储存空间
if (!PTemFile)
{
printf("AddSection:分配空间失败\n");
free(PTemFile);
return 0;
}
memset(PTemFile, 0, PSizeOfNewFile);//初始化为0
memcpy(PTemFile, PFileBuffer, PSizeOfNewFile);//将FileBuffer复制到临时空间
//初始化头部结构体
PNT_Header = (PIMAGE_NT_HEADERS)((DWORD)PTemFile + PDos_Header->e_lfanew);
PFile_Header = (PIMAGE_FILE_HEADER)((DWORD)PTemFile + PDos_Header->e_lfanew + 4);
POptional_Header = (PIMAGE_OPTIONAL_HEADER)((DWORD)PTemFile + PDos_Header->e_lfanew + 0x18);
PSection_Header = (PIMAGE_SECTION_HEADER)((DWORD)POptional_Header + PFile_Header->SizeOfOptionalHeader);
//计算所有头部结构的大小
DWORD lfanew = PDos_Header->e_lfanew;
DWORD SizeOfHeader = POptional_Header->SizeOfHeaders;
DWORD NumberOfSection = PFile_Header->NumberOfSections;
DWORD SizeOfNFO = 0x4 + 0x18 + PFile_Header->SizeOfOptionalHeader;
//计算剩余空间
DWORD Remain = SizeOfHeader - lfanew - SizeOfNFO - NumberOfSection * sizeof(*PSection_Header);
//将节表指向最后一个
PLastSection = &PSection_Header[PFile_Header->NumberOfSections - 1];
//判断剩余空间是否满足条件
if (Remain < 2 * sizeof(*PSection_Header))
{
printf("剩余空间大小不足,将移动头部\n");
//移动头部
memcpy((PDWORD)PTemFile + 0x40, (PDWORD)PTemFile + PDos_Header->e_lfanew, Remain);
PDos_Header->e_lfanew = 0x40;//指向新的NT头开始位置
//重新初始化PE头结构体
PDos_Header = (PIMAGE_DOS_HEADER)PTemFile;
PNT_Header = (PIMAGE_NT_HEADERS)((DWORD)PTemFile + PDos_Header->e_lfanew);
PFile_Header = (PIMAGE_FILE_HEADER)((DWORD)PTemFile + PDos_Header->e_lfanew + 4);
POptional_Header = (PIMAGE_OPTIONAL_HEADER)((DWORD)PTemFile + PDos_Header->e_lfanew + 0x18);
PSection_Header = (PIMAGE_SECTION_HEADER)((DWORD)POptional_Header + PFile_Header- >SizeOfOptionalHeader);
}
//初始化新节表信息
PWORD PNumberOfSection = &PFile_Header->NumberOfSections;
PDWORD PSizeOfImage = &POptional_Header->SizeOfImage;
PVOID PSectionName = &PSection_Header[PFile_Header->NumberOfSections].Name;
PDWORD PSectionMisc = &PSection_Header[PFile_Header->NumberOfSections].Misc.VirtualSize;
PDWORD PSectionVirtualAddress = &PSection_Header[PFile_Header->NumberOfSections].VirtualAddress;
PDWORD PSectionPointerToRawData = &PSection_Header[PFile_Header->NumberOfSections].PointerToRawData;
PDWORD PSectionSizeOfRawData = &PSection_Header[PFile_Header->NumberOfSections].SizeOfRawData;
PDWORD PSectionCharacteristic = &PSection_Header[PFile_Header->NumberOfSections].Characteristics;
//节表数量+1
* PNumberOfSection = PFile_Header->NumberOfSections + 1;
printf("NumberOfSection:%x\n", PFile_Header->NumberOfSections);
//新节表赋值
*PSizeOfImage = POptional_Header->SizeOfImage + 0x1000;
memcpy(PSectionName, ".zhijian", 8);
*PSectionMisc = 0x1000;
//计算上一个节表大小,VirtualSize和SizeOfRawData
DWORD PSize = PLastSection->Misc.VirtualSize > PLastSection->SizeOfRawData ?
PLastSection->Misc.VirtualSize : PLastSection->SizeOfRawData;
*PSectionVirtualAddress = PLastSection->VirtualAddress + PSize;//新内存中节表开始地址
*PSectionSizeOfRawData = 0x1000;
//新节表文件中开始地址
*PSectionPointerToRawData = PLastSection->PointerToRawData + PLastSection->SizeOfRawData;
*PSectionCharacteristic = 0xFFFFFFFF;
*PNewFileBuffer = PTemFile;
PTemFile = NULL;
return PSizeOfNewFile;
}
暂无评论