FileBuffer->ImageBuffer->FileBuffer

1、从磁盘读取内容
2、拉伸到运行时状态一样
3、还原成磁盘上内容一样
4、保存到磁盘上,并且能够运行

问题:
1、拉伸后,再还原磁盘上的形式,和读取前大小不一样,但是能够运行。
问题1

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


// 读取PE,返回PE大小
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 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("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("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;
	}
	// 申请文件存盘空间
	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;

}

int newbuffer_write2_exe(PVOID NewFileBuffer,DWORD FileSize, char* FilePath)
{
	FILE* fp1 = fopen(FilePath,"wb");
	if(fp1 != NULL)
	{
		fwrite(NewFileBuffer,FileSize,1,fp1);
	}
	fclose(fp1);
	return 1;

}

int main(){
	LPSTR file_path = "C:\\Users\\lolol\\Desktop\\geek2.exe";
	LPSTR write_file_path = "D:\\2.exe";

	LPVOID pFileBuffer = NULL; // 从磁盘读取到缓存
	LPVOID pImageBuffer = NULL;// 缓存拉伸存放到内存
	LPVOID pNewFileBuffer = NULL; // 存盘
	

	// 读取PE到缓存
	DWORD FileSize = ToLoaderPE(file_path, &pFileBuffer);
	printf("exe to buffer : %x\n", FileSize);

	// 缓存拉伸到内存
	DWORD ImageSize = CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
	printf("拉伸到内存的大小 : %x\n", ImageSize);

	DWORD NewFileSize = CopyImageBufferToNewBuffer(pImageBuffer, &pNewFileBuffer);
	printf("要存盘的大小:%x\n", NewFileSize);

	int ret4 = newbuffer_write2_exe(pNewFileBuffer, NewFileSize, write_file_path);
	printf("newbuffer->存盘返回值为:%d\n",ret4);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值