滴水逆向PE作业——扩大一个节

扩大一个节:
在这里插入图片描述
流程如下:
在这里插入图片描述
注意:修改完ImageBuffer后需要将其再压缩(拉伸的逆过程)后再存盘。

代码:

// ExtendLastSection.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "malloc.h"

// exe->filebuffer
DWORD ReadFile2Buffer(char* file_path,PVOID* FileBuffer);
// filebuffer->imagebuffer 
DWORD Read2ImageBuffer(PVOID FileBuffer,PVOID* ImageBuffer);
// 求对齐后的大小
DWORD Align(DWORD actuall_size,DWORD Align_size);

DWORD CopyImageBufferToNewBuffer(PVOID pImageBuffer,PVOID* pNewBuffer);

// 存盘
void StoreNewBuffer(PVOID pNewBuffer,DWORD new_file_size,char* save_path);

void ExtendLastSection()
{
	PVOID FileBuffer = NULL;
	PVOID ImageBuffer = NULL;
	PVOID SaveBuffer = NULL;
	DWORD FileBuffersize = 0;
	DWORD ImageBuffersize = 0;
	DWORD Save_size = 0;
	
	char file_path[] = "D:\\2020学习\\逆向\\IPMSG2007.exe";
	char save_path[] = "D:\\Lib\\IPMSG2007_extend_last_section.exe";

	// 1.将exe文件转化为filebuffer
	FileBuffersize = ReadFile2Buffer(file_path,&FileBuffer);
	// 2.filebuffer -> imagebuffer(并修改)
	ImageBuffersize = Read2ImageBuffer(FileBuffer,&ImageBuffer);
	
	Save_size = CopyImageBufferToNewBuffer(ImageBuffer,&SaveBuffer);
	// 3.存盘
	StoreNewBuffer(SaveBuffer,Save_size,save_path);
}

// exe->filebuffer 返回filebuffer的大小
DWORD ReadFile2Buffer(char* file_path,PVOID* FileBuffer)
{
	PVOID FileTempBuffer = NULL;
	DWORD file_size = 0;
	FILE* pFile = NULL;

	// 打开文件
	pFile = fopen(file_path,"rb");
	if(!pFile)
	{
		printf("打开文件失败!\n");
		return 0;
	}

	// 获取大小
	fseek(pFile,0,SEEK_END);
	file_size = ftell(pFile);
	fseek(pFile,0,SEEK_SET);

	// 分配内存
	FileTempBuffer = (PVOID)malloc(file_size);
	if(!FileTempBuffer)
	{
		printf("分配内存失败!\n");
		fclose(pFile);
		return 0;
	}
	// 数据存入内存
	size_t n = fread(FileTempBuffer,file_size,1,pFile);
	if(!n)
	{
		printf("文件中数据读取到内存中失败!\n");
		fclose(pFile);
		free(FileTempBuffer);
		return 0;
	}
	// 关闭文件返回filebuffer的长度
	*FileBuffer = FileTempBuffer;
	FileTempBuffer = NULL;
	fclose(pFile);
	return file_size;

}
// filebuffer->imagebuffer 返回imagebuffer的大小
DWORD Read2ImageBuffer(PVOID FileBuffer,PVOID* ImageBuffer)
{	
	// 初始化
	PVOID ImageTempBuffer = NULL;
	DWORD imagebuffer_size = 0;
	
	// 初始化PE结构体
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;

	// 判断filebuffer是否合法
	if(!FileBuffer)
	{
		printf("打开filebuffer失败!\n");
		return 0;
	}

	// 判断是否为合法exe文件
	if(*((PWORD)FileBuffer) != IMAGE_DOS_SIGNATURE)
	{
		printf("不含有MZ标志,不是合法exe文件!\n");
		return 0;
	}
	pDosHeader = PIMAGE_DOS_HEADER(FileBuffer);
	if(*((PDWORD)((DWORD)FileBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
	{
		printf("不是有效的PE标志!\n");
		return 0;
	}

	// 强制结构体类型转换 
	pDosHeader = (PIMAGE_DOS_HEADER)(FileBuffer);
	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)FileBuffer+pDosHeader->e_lfanew);
	pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
	pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pPEHeader->SizeOfOptionalHeader);

	// 需要修改的部分
	PDWORD pVirtualSize = &pSectionHeader[pPEHeader->NumberOfSections-1].Misc.VirtualSize;
	PDWORD pSizeOfRawData = &pSectionHeader[pPEHeader->NumberOfSections-1].SizeOfRawData;
	PDWORD pSizeOfImage = &pOptionalHeader->SizeOfImage;
	// printf("pPEHeader->NumberOfSections:%#X\n",pPEHeader->NumberOfSections);
	// 需要修改的部分
	printf("*pVirtualSize:%#X\n",*pVirtualSize);
	printf("pOptionalHeader->SectionAlignment:%#X\n",pOptionalHeader->SectionAlignment);
	*pVirtualSize = Align(*pVirtualSize,pOptionalHeader->SectionAlignment)+0x1000;
	printf("*pVirtualSize:%#X\n",*pVirtualSize);
	printf("*pSizeOfRawData:%#X\n",*pSizeOfRawData);
	*pSizeOfRawData = Align(*pSizeOfRawData,pOptionalHeader->SectionAlignment)+0x1000;
	printf("*pSizeOfRawData:%#X\n",*pSizeOfRawData);
	printf("*pSizeOfImage:%#X\n",*pSizeOfImage);	
	*pSizeOfImage += 0x1000;
	printf("*pSizeOfImage:%#X\n",*pSizeOfImage);
	printf("================================\n");

	// 分配内存
	DWORD ImageBuffer_size = pOptionalHeader->SizeOfImage;
	ImageTempBuffer = (PVOID)malloc(ImageBuffer_size);
	if(!ImageTempBuffer)
	{
		printf("分配内存ImageTempBuffer失败!\n");
		return 0;
	}
	memset(ImageTempBuffer,0,ImageBuffer_size);
	memcpy(ImageTempBuffer,pDosHeader,pOptionalHeader->SizeOfHeaders);

	// 创建一个临时的节结构体指针,遍历存储
	PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader;
	// printf("pTempSectionHeader:%#X\n",pTempSectionHeader);
	// printf("(void*)((DWORD)pFileBuffer+pTempSectionHeader->PointerToRawData):%#X\n",(void*)((DWORD)FileBuffer+pTempSectionHeader->PointerToRawData));
	for(int i = 0;i<pPEHeader->NumberOfSections;i++,pTempSectionHeader++)
	{	
		// 第二个参数是 imagebuffer开始的位置,FileBuffer+PointerToRawData(image中的偏移)
		memcpy((PVOID)((DWORD)ImageTempBuffer+pTempSectionHeader->VirtualAddress),(void*)((DWORD)FileBuffer+pTempSectionHeader->PointerToRawData),pTempSectionHeader->SizeOfRawData);
	}

	*ImageBuffer = ImageTempBuffer;
	ImageTempBuffer = NULL;
	return *pSizeOfImage;
}

DWORD Align(DWORD actuall_size,DWORD Align_size)
{
	if(actuall_size%Align_size == 0)
	{
		return actuall_size;
	}
	else
	{
		int n = actuall_size / Align_size;
		return Align_size*(n+1);
	}
}

//imagebuffer->newbuffer
DWORD CopyImageBufferToNewBuffer(PVOID pImageBuffer,PVOID* pNewBuffer)
{
	// ???PE?????
	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;

	// ???NEW_BUFFER??(temparay)
	LPVOID pTempNewbuffer = NULL;

	// ??pImageBuffer????
	if(!pImageBuffer)
	{
		printf("(2pnewbuffer??)??????pimagebuffer??!\n");
		return 0;
	}
	//?????exe??
	if(*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE)
	{
		printf("(2pnewbuffer??)??MZ??,??exe??!\n");
		return 0;
	}
	// ?????????
	pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
	if(*((PDWORD)((DWORD)pImageBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
	{
		printf("(2pnewbuffer??)?????PE??!\n");	
		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);

	//??new_buffer???
	int new_buffer_size = pOptionHeader->SizeOfHeaders;
	for(DWORD i = 0;i<pPEHeader->NumberOfSections;i++)
	{
		new_buffer_size += pSectionHeader[i].SizeOfRawData;  // pSectionHeader[i]?????
	}
	// ????(newbuffer)
	pTempNewbuffer = malloc(new_buffer_size);
	if(!pTempNewbuffer)
	{
		printf("(2pnewbuffer??)??Newbuffer??!\n");
		return 0;
	}
	memset(pTempNewbuffer,0,new_buffer_size);
	// ????
	memcpy(pTempNewbuffer,pDosHeader,pOptionHeader->SizeOfHeaders);
	// ??????
	PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader;
	for(DWORD j = 0;j<pPEHeader->NumberOfSections;j++,pTempSectionHeader++)
	{	//PointerToRawData?????????,VirtualAddress???????????,SizeOfRawData???????????
		memcpy((PDWORD)((DWORD)pTempNewbuffer+pTempSectionHeader->PointerToRawData),(PDWORD)((DWORD)pImageBuffer+pTempSectionHeader->VirtualAddress),pTempSectionHeader->SizeOfRawData);
	}
	//????
	*pNewBuffer = pTempNewbuffer; //????????????
	pTempNewbuffer = NULL;
	return new_buffer_size;  // ??????????????
}

//存盘
void StoreNewBuffer(PVOID pNewBuffer,DWORD new_file_size,char* save_path)
{
	FILE* fp2;
	fp2 =  fopen(save_path,"wb");
	if(!fp2)
	{
		printf("写入文件失败!\n");
		fclose(fp2);
		return;
	}
	fwrite(pNewBuffer,new_file_size,1,fp2);
	fclose(fp2);
}

int main(int argc, char* argv[])
{
	ExtendLastSection();
	getchar();
	return 0;
}

结果如下:
原本exe:
在这里插入图片描述
最后一个节:
在这里插入图片描述
在这里插入图片描述
扩大最后一个节后:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值