合并节并且遇到逆天情况 + 打印目录表

文章讲述了在合并PE文件时遇到的一个特殊情况,即第一个节的PointerToRawData和SizeOfRawData值为0,导致的问题及解决方案,涉及对PE结构的理解和内存操作的处理。
摘要由CSDN通过智能技术生成

如果说合并的第一个节的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);
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值