PE_合并节

参考:Revival_S

1、拉伸到内存 (这里是真的拉伸到一块内存空间)

2、将第一个节的内存大小、文件大小改成一样

VirtualSize = SizeOfRawData = 整个文件拉伸后的大小 - 第一节VirtualAddress

即相当于在拉伸后的文件中 从第一个节表开始到 最后 都作为第一个节的内存长度与文件长度

3、将第一个节的属性改为包含所有节的属性 (所有节的Characteristics 全部按位或在一起)

4、修改节的数量为1

5、其他节表的空间全部置0

6、最后将这个拉伸的空间直接拷贝到文件

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


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

	pFile = fopen(file_path, "rb");
	
	if(!pFile){
		printf("Can not open file\n");
		return 0;
	}

	fseek(pFile, 0, SEEK_END);
	FileSize = ftell(pFile);
	printf("FileBuffer Size: %x\n",FileSize);
	fseek(pFile, 0, SEEK_SET);

	pFileBufferTemp = malloc(FileSize);
	if(!pFileBufferTemp){
		printf("malloc fail!\n");
		fclose(pFile);
	}

	DWORD n = fread(pFileBufferTemp, FileSize, 1, pFile);

	if(!n){
		printf("read file failed!\n");
		free(pFileBufferTemp);
		fclose(pFile);
		return 0;
	}
	*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;
	}
}

int write2file(PVOID ImageBuffer,DWORD Size, PSTR FilePath)
{
	if(!ImageBuffer){
		printf("没有东西可以写入\n");
	}
	FILE* fp1 = fopen(FilePath,"wb");
	if(!fp1)
	{
		printf("不能打开要写入的文件\n");
	}else{
		fwrite(ImageBuffer,Size,1,fp1);
	}
	fclose(fp1);
	return 1;

}

DWORD CopyFileBufferToImageBuffer(PVOID pFileBuffer, PVOID* pImageBuffer){
	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("file loader failed!\n");
		return 0;
	}

	if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE){
		printf("(CopyFileBufferToImageBuffer)Don not hava MZ!\n");
		return 0;
	}
	
	// 找出各个结构的起始地址
	pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;

	if(*((LPDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){
		printf("没有PE符号");
		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);

	// 头部,节表等内容拉伸放入内存
	PVOID pImageTemp = malloc(pOptionHeader -> SizeOfImage);
	if(!pImageTemp){
		printf("申请内存映像失败!");
		free(pImageTemp);
		return 0;
	}

	memset(pImageTemp, 0, pOptionHeader->SizeOfImage);
	memcpy(pImageTemp, pFileBuffer, pOptionHeader->SizeOfHeaders);

	int n;
	PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;

	printf("节表数量:%d\n", pPEHeader->NumberOfSections);

	for(n=0; n < pPEHeader->NumberOfSections; n++, pSectionHeaderTemp++){
		memcpy((PVOID)((DWORD)pImageTemp + pSectionHeaderTemp->VirtualAddress), (PVOID)((DWORD)pFileBuffer + pSectionHeaderTemp ->PointerToRawData), pSectionHeaderTemp->SizeOfRawData);
		printf("第%d节表:内存偏移%x,磁盘偏移%x\n", n, pSectionHeaderTemp->VirtualAddress, pSectionHeaderTemp->PointerToRawData);
	}

	*pImageBuffer = pImageTemp;
	pImageTemp = NULL;
	return pOptionHeader->SizeOfImage;

}
DWORD CopyImageBufferToNewBuffer(PVOID pImageBuffer, PVOID* pNewFileBuffer){
	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(!pImageBuffer){
		printf("内存加载失败!\n");
		return 0;
	}

	if(*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE){
		printf("(CopyImageBufferToNewBuffer)Don not hava MZ!\n");
		return 0;
	}
	
	// 找出头部各个结构的起始地址
	pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;

	if(*((PDWORD)((DWORD)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){
		printf("没有PE符号");
		return 0;
	}	
	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + 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);


	// 计算要申请空间
	int new_file_size = pOptionHeader->SizeOfHeaders;
	for(int i=0; i < pPEHeader->NumberOfSections; i++){
		new_file_size += pSectionHeader[i].SizeOfRawData;
		printf("每个节:%x\n",pSectionHeader[i].SizeOfRawData);
	}
	printf("头加节:%x\n",new_file_size);
	// 申请文件存盘空间
	LPVOID pNewFileBufferTemp = malloc(new_file_size);
	if(!pNewFileBufferTemp){
		printf("存盘空间申请失败!");
		return 0;
	}
	// 头部放进去
	memset(pNewFileBufferTemp, 0, new_file_size);
	memcpy(pNewFileBufferTemp, pDosHeader, pOptionHeader->SizeOfHeaders);
	// 各个节表放进去
	PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
	for(i=0; i < pPEHeader->NumberOfSections; i++, pSectionHeaderTemp++){
		memcpy((PVOID)((DWORD)pNewFileBufferTemp + pSectionHeaderTemp->PointerToRawData), (PVOID)((DWORD)pImageBuffer + pSectionHeaderTemp->VirtualAddress), pSectionHeaderTemp->SizeOfRawData);
	}

	*pNewFileBuffer = pNewFileBufferTemp;
	pNewFileBufferTemp = NULL;
	
	return new_file_size;

}

DWORD HBSection(PVOID* pImageBuffer){
	PVOID ppImageBuffer = NULL;

	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;
	
	pDosHeader = (PIMAGE_DOS_HEADER)(*pImageBuffer);
	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
	pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);

	pSectionHeader->SizeOfRawData = Align(pOptionHeader->SizeOfImage - pSectionHeader->VirtualAddress, pOptionHeader->FileAlignment);
	printf("duiqi:%x\n",pSectionHeader->SizeOfRawData);
	pSectionHeader->Misc.VirtualSize = pSectionHeader->SizeOfRawData;

	PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
	DWORD Characteristics = pSectionHeader->Characteristics;
	pSectionHeaderTemp++;
	for(DWORD n=1; n < pPEHeader->NumberOfSections; n++, pSectionHeaderTemp++){
		Characteristics = pSectionHeaderTemp->Characteristics | Characteristics;
		memset(pSectionHeaderTemp, 0, IMAGE_SIZEOF_SECTION_HEADER);
	}
	// 修改第一个节表属性
	pSectionHeader->Characteristics = Characteristics;
	printf("Name:%s\n",pSectionHeader->Name);
	pPEHeader->NumberOfSections = 1;

	return 0;
}



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

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

	DWORD sizeOfImage = CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
	printf("文件在内存中的大小:%x\n", sizeOfImage);

	HBSection(&pImageBuffer);

	DWORD sizeOfFile = CopyImageBufferToNewBuffer(pImageBuffer, &ppImageBuffer);

	
	BOOL isSuccess = write2file(ppImageBuffer, sizeOfFile, write_path);
	if(isSuccess){
		printf("yes\n");
	}else{
		printf("no\n");
	}
	
	return 0;
}

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值