如果说合并的第一个节的PointerToRawData和SizeOfRawData 都为0该怎么办,没想到我随便用vs生成的测试软件能测试的这么极端…解决方法放在代码里了
大概就是PointerOfRawData会影响pe headers的覆盖,所以说合并第一节时需要做一个循环判断
SizeOfRawData会影响内存写入到文件里ImageBuffer To FileBuffer,毕竟他在文件中大小为0,那么我们就只需要在前面做一个判断是否为0,为0就不写
算是多踩几个雷,对pe结构理解更深了吧
BOOL MergeSections(PVOID fileName) {
//准备工作
PVOID pBuffer = FileToFileBuffer(fileName);
pBuffer = FileBufferToImageBuffer(pBuffer);
PIMAGE_DOS_HEADER pDosHeader = pBuffer;
PIMAGE_NT_HEADERS pNTHeader = (DWORD)pDosHeader + pDosHeader->e_lfanew;
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) {
printf("File is not PE\n");
free(pBuffer);
return FALSE;
}
PIMAGE_FILE_HEADER pFileHeader = &pNTHeader->FileHeader;
PIMAGE_OPTIONAL_HEADER pOptHeader = (DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER);
PIMAGE_SECTION_HEADER pSecHeader = (DWORD)pOptHeader + pFileHeader->SizeOfOptionalHeader;
//修改权限,每个节表的属性或运算一下,改一下节表数量,改一下vs=SizeOfRawData = ImageBase - pSecHeader->VirtualAddress 最后存盘
for (size_t i = 1; i < pFileHeader->NumberOfSections; i++) {
pSecHeader->Characteristics |= (pSecHeader + i)->Characteristics;
}
//测试的文件太逆天了,第一个节的PointerToRawData是0,大小也是0,导致了很多问题...吃一堑长一智吧
for (size_t i = 0; i < pFileHeader->NumberOfSections; i++) {
if ((pSecHeader + i)->PointerToRawData == 0) {
continue;
}
pSecHeader->PointerToRawData = (pSecHeader + i)->PointerToRawData;
}
pFileHeader->NumberOfSections = 1;
DWORD virtualSize = pOptHeader->SizeOfImage - pSecHeader->VirtualAddress;
pSecHeader->Misc.VirtualSize = virtualSize;
pSecHeader->SizeOfRawData = virtualSize;
strcpy(pSecHeader->Name, ".gggg");
ImageBufferToFileBuffer("C:\\Users\\12459\\Downloads\\111.exe", pBuffer);
}
//ImageBufferToFileBuffer
for (size_t i = 0; i < pFileHeader->NumberOfSections; i++) {
//如果他的文件大小为0,那么我们就不需要往里写入东西
if (!pSecHeader->SizeOfRawData) {
continue;
}
memcpy((DWORD)pFileBuffer + pSecHeader->PointerToRawData, (DWORD)pImageBuffer + pSecHeader->VirtualAddress,
pSecHeader->SizeOfRawData);
pSecHeader++;
}
最后还有一个很简单的打印目录表
BOOL PrintDirectoryTable(BYTE* fileName) {
PVOID pFileBuffer = FileToFileBuffer(fileName);
pFileBuffer = FileBufferToImageBuffer(pFileBuffer);
PIMAGE_DOS_HEADER pDosHeader = pFileBuffer;
PIMAGE_NT_HEADERS pNTHeader = (DWORD)pDosHeader + pDosHeader->e_lfanew;
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) {
printf("File is not PE\n");
free(pFileBuffer);
return FALSE;
}
PIMAGE_FILE_HEADER pFileHeader = &pNTHeader->FileHeader;
PIMAGE_OPTIONAL_HEADER pOptHeader = (DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER);
for (size_t i = 0; i < pOptHeader->NumberOfRvaAndSizes; i++) {
PIMAGE_DATA_DIRECTORY pDataDirectory = pOptHeader->DataDirectory + i;
printf("pDataDirectory[%d] Size:%x,VirtualAddress:%x\n", i, pDataDirectory->Size, pDataDirectory->VirtualAddress);
}
}