PE_扩大节

1、拉伸到内存(只是逻辑上,实际代码操作并不需要这一步)

2、分配一块新的空间:SizeOfImage + sizeof ( 新增的大小)

3、扩大节,修改最后一个节的 SizeOfRawData 和 VirtualSize

4、修改SizeOfImage大小(内存对齐)

扩大节

#include<stdio.h>
#include<windows.h>

DWORD toLordPE(PSTR file_path, PVOID* pFileBuffer){
	FILE *pFile;
	DWORD FileSize = 0;
	PVOID pFileBufferTemp = NULL;

	pFile = fopen(file_path, "rb");
	if(!pFile){
		printf("不能打开文件!\n");
		return 0;
	}
	fseek(pFile, 0, SEEK_END);
	FileSize = ftell(pFile);
	fseek(pFile, 0, SEEK_SET);

	pFileBufferTemp = malloc(FileSize);
	if(!pFileBufferTemp){
		printf("不能分配内存空间!\n");
		return 0;
	}

	fread(pFileBufferTemp, FileSize, 1, pFile);
	*pFileBuffer = pFileBufferTemp;
	pFileBufferTemp = NULL;
	fclose(pFile);

	return FileSize;
}

DWORD Align(DWORD ad, DWORD alignment){
	if(ad % alignment == 0){
		return ad;
	}else{
		return ((ad / alignment) +1) * alignment;
	}
}
DWORD EnlargeSection(PVOID* pFileBuffer, PVOID* pNewFileBuffer, DWORD FileSize, DWORD exSize){

	DWORD FileTotal = 0;
	PVOID pNewFileBufferTemp = NULL;

	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;
 
	if (!(*pFileBuffer))
	{
		printf("(TestEnlargeSection)Can't open file!\n");
		return 0;
	}

	
	//判断是否是有效的MZ标志	
	if (*((PWORD)(*pFileBuffer)) != IMAGE_DOS_SIGNATURE)
	{
		printf("(TestEnlargeSection)No MZ flag, not exe file!\n");
		return 0;
	}
	pDosHeader = (PIMAGE_DOS_HEADER)(*pFileBuffer);
 
	//判断是否是有效的PE标志	
	if (*((PDWORD)((DWORD)(*pFileBuffer) + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
	{
		printf("(EnlargeSection)Not a valid PE flag!\n");
		return 0;
	}
	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);


	

	FileTotal = FileSize + Align(exSize, pOptionHeader->FileAlignment);
	*pNewFileBuffer = malloc(FileTotal);
	if(!pNewFileBuffer){
		printf("(enlargeSection)内存分配失败\n");
		return 0;
	}
	memset(*pNewFileBuffer, 0, FileTotal);
	memcpy(*pNewFileBuffer, *pFileBuffer, FileSize);

		

	pDosHeader = (PIMAGE_DOS_HEADER)(*pNewFileBuffer);

	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)(*pNewFileBuffer) + 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);

	//遍历到最后一个节表
	PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
	for (DWORD i = 1; i < pPEHeader->NumberOfSections; i++, pSectionHeaderTemp++)
	{
		// i=0,for结束后,pSectionHeaderTemp指向之后一个节表的后面,不是最后一个节表
		// i=1,pSectionHeaderTemp指向的是最后一个
	}


	

	DWORD max = pSectionHeaderTemp->Misc.VirtualSize > pSectionHeaderTemp->SizeOfRawData ? pSectionHeaderTemp->Misc.VirtualSize : pSectionHeaderTemp->SizeOfRawData;

	pSectionHeaderTemp->Misc.VirtualSize = Align(max + exSize, pOptionHeader->FileAlignment);
	pSectionHeaderTemp->SizeOfRawData = Align(max + exSize, pOptionHeader->FileAlignment);
	pOptionHeader->SizeOfImage = Align(pSectionHeaderTemp->VirtualAddress + pSectionHeaderTemp->Misc.VirtualSize, pOptionHeader->SectionAlignment);


	return FileTotal;
}

BOOL Memory2File(PVOID pNewFileBuffer, DWORD size, PSTR write_path){
	FILE *fp;
	fp = fopen(write_path, "wb");
	if(!fp){
		printf("(MemoryToFile)写入失败!\n");
		return 0;
	}
	printf("mtf :%x\n", pNewFileBuffer);
	fwrite(pNewFileBuffer, size, 1, fp);
	fclose(fp);
	return 1;
}

int main(){
	PSTR file_path = "C:\\Users\\lolol\\Desktop\\3.exe";
	PSTR write_path = "C:\\Users\\lolol\\Desktop\\5.exe";
	PVOID pFileBuffer = NULL;
	PVOID pNewFileBuffer = NULL;

	DWORD FileSize = toLordPE(file_path, &pFileBuffer);
	printf("文件大小:%x\n", FileSize);

	DWORD FileTotal = EnlargeSection(&pFileBuffer, &pNewFileBuffer, FileSize, 0x1500);
	printf("%x\n",FileTotal);

	if(FileTotal){
		BOOL IsSuccess = Memory2File(pNewFileBuffer, FileTotal, write_path);
		if(IsSuccess){
			printf("扩大成功!\n");
		}
	}else{
		printf("扩大失败!\n");
	}

	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值