PE段的合并

开始以为很简单(直接可以进行文件更改)

一开始的思路

主要是是对节表进行合并

1: 更改节表(变为一个,更改内存大小, 更改文件大小)

2:更改属性

3: 更改节的数目


直接使用文件修改的方法(手动修改方法)

全部无法运行, 蛋疼的厉害

然后,直接先转换为 ImageBuffer,  再次修改, 几个属性,才搞定

我也不知道为什么.


贴一下修改的代码


// PEOperate.cpp: implementation of the PEOperate class.
//
//////////////////////////////////////////////////////////////////////

#include "PEOperate.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include "windows.h"
#include "stdio.h"

#define MESSAGEBOXADDR	0x77D507EA
#define SHELLCODELENGTH 0x12

BYTE shellCode[]={
		0x6A,00,0x6A,00,0x6A,00,0x6A,00,
		0xE8,00,00,00,00,
		0xE9,00,00,00,00
};

//加载PE文件到内存中
LPVOID ReadPEFile(LPSTR lpszFile)
{
	FILE *pFile = NULL;
	DWORD fileSize = 0;
	LPVOID pFileBuffer = NULL;
	
	//打开文件
	pFile = fopen(lpszFile,"rb");
	
	if(!pFile)
	{
		printf("无法打开文件EXE文件");
		return NULL;
	}
	
	fseek(pFile,0,SEEK_END);
	fileSize = ftell(pFile);
	fseek(pFile,0,SEEK_SET);
	
	//分配缓冲区
	pFileBuffer = malloc(fileSize);
	if(!pFileBuffer)
	{
		printf("分配空间失败!\n");
		fclose(pFile);
		return NULL;
	}
	
	//文件读取
	
	size_t n = fread(pFileBuffer,fileSize,1,pFile);
	
	if(!n)
	{
		printf("读取数据失败\n");
		free(pFileBuffer);
		fclose(pFile);
		return NULL;
	}
	
	//关闭文件
	fclose(pFile);
	return pFileBuffer;
	
}

//内存直接写入到文件
void WirteToFile(LPVOID pFileBuffer,size_t fileSize,LPSTR lpszFile)
{
	FILE *pFile = NULL;	
	//打开文件
	pFile = fopen(lpszFile,"wb");
	
	if(!pFile)
	{
		printf("无法打开文件EXE文件");
		return;
	}
	
	size_t writeSize = fwrite(pFileBuffer,fileSize,1,pFile);
	printf("WirteSize:%d\n",writeSize);
	
	//关闭文件
	fclose(pFile);
	return;
	
}


//打印所有的PE头信息
VOID PrintNTHeaders(LPSTR lpszFile)
{
	LPVOID pFileBuffer = 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;
	
	pFileBuffer= ReadPEFile(lpszFile);
	if(!pFileBuffer)
	{
		printf("文件读取失败\n");
		return;
	}
	
	//MZ标志
	if(*((PWORD)pFileBuffer)!=IMAGE_DOS_SIGNATURE)
	{
		printf("不是有效的MZ标志\n");
		free(pFileBuffer);
		return;
	}
	
	pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	
	//打印DOS头
	printf("------------DOS头------------\n");
	printf("MZ标志: %x\n",pDosHeader->e_magic);
	printf("PE偏移: %x\n",pDosHeader->e_lfanew);

	//判断是否是有效的PE 
	if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew))!=IMAGE_NT_SIGNATURE)
	{
		printf("不是有效的PE标志\n");
		free(pFileBuffer);
		return;
	}

	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);

	//打印NT头
	printf("------------NT头------------\n");
	printf("Signature: %x\n",pNTHeader->Signature);
	pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
	printf("------------标准PE头--------\n");
	printf("Machine: %x\n",pPEHeader->Machine);
	printf("节的数量: %x\n",pPEHeader->NumberOfSections);
	printf("SizeOfOptionHeaders: %x\n",pPEHeader->SizeOfOptionalHeader);

	//可选择PE头
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
	printf("------------OPTION_PE头--------\n");
	printf("Machine: %x \n",pOptionHeader->Magic);
	printf("OEP: %x \n",pOptionHeader->AddressOfEntryPoint);
	printf("ImageBase: %x \n",pOptionHeader->ImageBase);
	printf("SectionAlignment: %x \n",pOptionHeader->SectionAlignment);
	printf("FileAlignment: %x \n",pOptionHeader->FileAlignment);
	printf("SizeOfImage: %x \n",pOptionHeader->SizeOfImage);
	printf("SizeOfHeaders: %x \n",pOptionHeader->SizeOfHeaders);
	
	
	//节表的信息(分别打印)
	//确定节表的个数:
	int Section_Number = pPEHeader->NumberOfSections;
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

	for(int i=0;i<Section_Number;i++)
	{
		printf("------------节表信息:%d--------\n",i+1);
		printf("Name: %s \n",pSectionHeader->Name);
		printf("VirualSize : %x\n",pSectionHeader->Misc);
		printf("VirualAddress: %x\n",pSectionHeader->VirtualAddress);
		printf("SizeOfRawData: %x \n",pSectionHeader->SizeOfRawData);
		printf("PointerToRowData: %x \n",pSectionHeader->PointerToRawData);
		
		//下一个节表
		pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);

	}
	//释放内存
	free(pFileBuffer);
}


//将PE的FileBuffer拷贝到ImageBuffer
LPVOID CopyFileBufferToImageBuffer(LPVOID pFileBuffer)
{
	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("文件读取失败\n");
		return NULL;
	}

	//Header信息
	pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	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);
	
	DWORD ImageSize = pOptionHeader->SizeOfImage;
	
	//LPVOID pImageBuffer=NULL;
	//分配缓冲区
	LPVOID pImageBuffer=NULL;
	pImageBuffer = malloc(ImageSize);

	if(!pImageBuffer)
	{
		printf("pImageBuffer分配空间失败!\n");
		return NULL;
	}
	//printf("%x \n",ImageSize);

	memset(pImageBuffer,0,ImageSize);

	//分段拷贝数据到ImageBuffer中
	//1 拷贝头
	DWORD HeaderSize = pOptionHeader->SizeOfHeaders;
	//DWORD Head_i = 0;
	//copy header
	memcpy(pImageBuffer,pFileBuffer,HeaderSize);
	
	//2 拷贝节 pSectionHeader
	//数量,位置
	int Section_Number = pPEHeader->NumberOfSections;
	//分节进行写入

	LPVOID pFileBuffer_sec = pFileBuffer;
	LPVOID pImageBuffer_sec = pImageBuffer;

	//printf("pFileBuffer_sec: %x \n",pFileBuffer_sec);
	//printf("pImageBuffer_sec: %x \n",pImageBuffer_sec);

	for(int i=0;i<Section_Number;i++)
	{
		DWORD FileSizeOfRawData = pSectionHeader->SizeOfRawData;
		DWORD FilePointerToRawData = pSectionHeader->PointerToRawData;
		DWORD MemVirtualAddress = pSectionHeader->VirtualAddress;
		pFileBuffer_sec=(LPVOID)((DWORD)pFileBuffer+FilePointerToRawData);
		pImageBuffer_sec=(LPVOID)((DWORD)pImageBuffer+MemVirtualAddress);
	
		//printf("pFileBuffer_sec: %x \n",pFileBuffer_sec);
		//printf("pImageBuffer_sec: %x \n",pImageBuffer_sec);

		memcpy(pImageBuffer_sec,pFileBuffer_sec,FileSizeOfRawData);
		//下一个节表
		pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);
	}
	
	//写出
	//WirteToFile(pImageBuffer,ImageSize,"c://image.exe");

	return pImageBuffer;
}

LPVOID CopyImageBuffertoNewBuffer(LPVOID pImageBuffer)
{
	

	return NULL;
}

BOOL MemeryTOFile(LPVOID pMemBuffer,LPSTR lpszFile)
{
	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;
	
	//Header信息
	pDosHeader = (PIMAGE_DOS_HEADER)pMemBuffer;
	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pMemBuffer+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);
	

	//将内存中的文件转入到File中
	FILE *pFile = NULL;	
	//打开文件
	pFile = fopen(lpszFile,"a+b");
	
	if(!pFile)
	{
		printf("无法打开文件EXE文件");
		return FALSE;
	}
	
	//写header
	DWORD SIZE_HEADER =  pOptionHeader->SizeOfHeaders;
	fwrite(pMemBuffer,SIZE_HEADER,1,pFile);

	//写节表
	int Section_Number = pPEHeader->NumberOfSections;

	LPVOID pImageBuffer_sec = pMemBuffer;
	
	printf("pImageBuffer_SEC : %x \n",pImageBuffer_sec);
	for(int i=0;i<Section_Number;i++)
	{
		DWORD FileSizeOfRawData = pSectionHeader->SizeOfRawData;
		DWORD FilePointerToRawData = pSectionHeader->PointerToRawData;
		DWORD MemVirtualAddress = pSectionHeader->VirtualAddress;

		pImageBuffer_sec=(LPVOID)((DWORD)pMemBuffer+MemVirtualAddress);
		printf("pImageBuffer_SEC : %x \n",pImageBuffer_sec);

		fwrite(pImageBuffer_sec,FileSizeOfRawData,1,pFile);

		pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);	
	}

	
	
	//关闭文件
	fclose(pFile);
	
	return TRUE;
}

DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
{
	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("文件读取失败\n");
		return NULL;
	}

	//Header信息
	pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	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);

	DWORD ImageSize = pOptionHeader->SizeOfImage;
	int Section_Number = pPEHeader->NumberOfSections;
	int i=0;
	for(i=0;i<Section_Number;i++)
	{
		printf("VirualSize : %x\n",pSectionHeader->Misc);
		printf("VirualAddress: %x\n",pSectionHeader->VirtualAddress);
		
		DWORD dumpVirualSize = pSectionHeader->Misc.VirtualSize;
		DWORD dumpVirualAddress = pSectionHeader->VirtualAddress;

		if(dwRva>=dumpVirualAddress && dwRva <=dumpVirualAddress+dumpVirualSize)
		{
			printf("地址在第:%d 节 %s \n",i+1,pSectionHeader->Name);
			break;
		}
		//下一个节表
		pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);
	}
	
	//确定是第i+1节
	//确定偏移距离
	DWORD fileOff = pSectionHeader->PointerToRawData + (dwRva-pSectionHeader->VirtualAddress);

	return fileOff;
}


void TestAddCodeInCodeSec(LPSTR lpszFile)
{
	LPVOID pFileBuffer = NULL;
	pFileBuffer= ReadPEFile(lpszFile);
	if(!pFileBuffer)
	{
		printf("文件读取失败\n");
		return;
	}
	
	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;
	
	LPVOID pImageBuffer = CopyFileBufferToImageBuffer(pFileBuffer);

	//Header信息
	pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
	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);
	

	//确定添加代码的位置
	//1判断能否添加
	if((pSectionHeader->SizeOfRawData-pSectionHeader->Misc.VirtualSize)<=SHELLCODELENGTH){
		printf("空余字节大小不够添加shellCode\n");
		free(pFileBuffer);
		return;
	}

	//size_t file_size = pSectionHeader->SizeOfRawData-pSectionHeader->Misc.VirtualSize;
	//printf("%x \n",file_size);

	//2代码加的位置
	printf("pImageBuffer: %x\n",pImageBuffer);
	DWORD shellLocation =  pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize;
	//确定位置
	LPVOID pShellLoc = (LPVOID)((DWORD)pImageBuffer + shellLocation);
	printf("pShellLoc: %x\n",pShellLoc);
	
	//拷贝初始化代码到内存
	memcpy(pShellLoc,shellCode,SHELLCODELENGTH);
	
	//修改E8地址
	DWORD  pE8Content = MESSAGEBOXADDR - (((DWORD)pShellLoc+13 )- ((DWORD)pImageBuffer)+ pOptionHeader->ImageBase);
	*(PDWORD)((DWORD)pShellLoc+9)=pE8Content;

	//修改E9地址
	DWORD pE9Content = (pOptionHeader->AddressOfEntryPoint+pOptionHeader->ImageBase) - (((DWORD)pShellLoc+0x12 )- ((DWORD)pImageBuffer)+ pOptionHeader->ImageBase);
	*(PDWORD)((DWORD)pShellLoc+14)=pE9Content;

	//修改OEP
	pOptionHeader->AddressOfEntryPoint = (DWORD)pShellLoc-(DWORD)pImageBuffer;

	//更改完的ImageBuffer,写出到File中
	MemeryTOFile(pImageBuffer,"C://testShell.exe");

	//释放
	free(pFileBuffer);
	free(pImageBuffer);
	return;
}

void TestAddSecToFile(LPSTR lpszFile)
{
	LPVOID pFileBuffer = NULL;
	pFileBuffer= ReadPEFile(lpszFile);
	if(!pFileBuffer)
	{
		printf("文件读取失败\n");
		return;
	}
	
	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;
	PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL;

	//Header信息
	pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	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);
	pSectionHeader_ADD = pSectionHeader;
	

	//1 判断能否添加节
	DWORD Header_size = pDosHeader->e_lfanew + 4 + 20 + pPEHeader->SizeOfOptionalHeader + pPEHeader->NumberOfSections*40;
	if(pOptionHeader->SizeOfHeaders-Header_size<80)
	{
		printf("没有可用空间填充节表\n");
		free(pFileBuffer);
		return;
	}
	
	printf("空间:%d\n",pOptionHeader->SizeOfHeaders-Header_size);
	
	

	//添加一个节
	//确定参数
	PIMAGE_SECTION_HEADER pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);
	pSectionHeader_ADD=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader_ADD+(pPEHeader->NumberOfSections)*40);
	//="NewSec";
	strcpy((char*)pSectionHeader_ADD->Name,"NewSec");
	pSectionHeader_ADD->Misc.VirtualSize = 0x1000;
	pSectionHeader_ADD->VirtualAddress = pOptionHeader->SizeOfImage;
	pSectionHeader_ADD->SizeOfRawData = 0x1000;
	pSectionHeader_ADD->PointerToRawData = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData;
	pSectionHeader_ADD->Characteristics = pSectionHeader->Characteristics;

	//填充0
	LPVOID pSectionEND = (LPVOID)((DWORD)pSectionHeader_ADD+40);
	memset(pSectionEND,0,IMAGE_SIZEOF_SECTION_HEADER);
	

	printf("pFileBuffer: %x\n",pFileBuffer);
	printf("pSectionHeader: %x\n",pSectionHeader);
	printf("pSectionHeader_LAST: %x\n",pSectionHeader_LAST);
	printf("pSectionHeader_ADD: %x\n",pSectionHeader_ADD);
	printf("pSectionEND: %x\n",pSectionEND);
	
	//修改PE头信息
	pPEHeader->NumberOfSections = pPEHeader->NumberOfSections +1;
	pOptionHeader->SizeOfImage  = pOptionHeader->SizeOfImage+0x1000;

	//写入到文件
	FILE *pOutFile = NULL;	
	//打开文件
	pOutFile = fopen("C://addSec.exe","a+b");
	
	if(!pOutFile)
	{
		printf("无法打开文件EXE文件");
		return;
	}
	//写出第一部分
	printf("length: %x \n ",pSectionHeader_ADD->PointerToRawData+pSectionHeader_ADD->SizeOfRawData);

	size_t writeSize = fwrite(pFileBuffer,pSectionHeader_ADD->PointerToRawData,1,pOutFile);
	printf("WirteSize:%d\n",writeSize);
	//写出第二部分
	LPVOID pNewBuffer=(LPVOID)malloc(0x1000);
	if(pNewBuffer==NULL)
	{
		printf("pNewBuffer分配空间失败\n");
		return;
	}
	memset(pNewBuffer,0,0x1000);
	writeSize = fwrite(pNewBuffer,0x1000,1,pOutFile);
	
	//关闭文件
	fclose(pOutFile);
	


	free(pFileBuffer);
	free(pNewBuffer);

}

void TestAddLastSectionToFile(LPSTR lpszFile)
{
	LPVOID pFileBuffer = NULL;
	pFileBuffer= ReadPEFile(lpszFile);
	if(!pFileBuffer)
	{
		printf("文件读取失败\n");
		return;
	}
	
	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;
	PIMAGE_SECTION_HEADER pSectionHeader_LAST = NULL;

	//Header信息
	pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	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);
	pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);
	int fileLength = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData;

	//更改ImageSize
	pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage+0x1000;
	
	//更改最后一个节的SizeOfRawData 以及 VirtualSize
	pSectionHeader_LAST->SizeOfRawData = 	pSectionHeader_LAST->SizeOfRawData+0x1000;
	pSectionHeader_LAST->Misc.VirtualSize = pSectionHeader_LAST->Misc.VirtualSize+0x1000;
	
	//写出文件
	
	//写入到文件
	FILE *pOutFile = NULL;	
	//打开文件
	pOutFile = fopen("C://addSecLength.exe","a+b");
	
	if(!pOutFile)
	{
		printf("无法打开文件EXE文件");
		return;
	}
	//写出第一部分
	printf("length: %x \n ",fileLength);

	size_t writeSize = fwrite(pFileBuffer,fileLength,1,pOutFile);
	printf("WirteSize:%d\n",writeSize);
	//写出第二部分
	LPVOID pNewBuffer=(LPVOID)malloc(0x1000);
	if(pNewBuffer==NULL)
	{
		printf("pNewBuffer分配空间失败\n");
		return;
	}
	memset(pNewBuffer,0,0x1000);
	writeSize = fwrite(pNewBuffer,0x1000,1,pOutFile);
	
	//关闭文件
	fclose(pOutFile);
	free(pFileBuffer);
	free(pNewBuffer);

}



void TestChangeOneSec(LPSTR lpszFile)
{
	LPVOID pFileBuffer = NULL;
	pFileBuffer= ReadPEFile(lpszFile);
	if(!pFileBuffer)
	{
		printf("文件读取失败\n");
		return;
	}
	
	LPVOID pImageBuffer =NULL;
	pImageBuffer = CopyFileBufferToImageBuffer(pFileBuffer);


	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;
	PIMAGE_SECTION_HEADER pSectionHeader_LAST = NULL;

	//Header信息
	pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
	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);
	pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);

	//合并节的操作
	DWORD LastSize = (pSectionHeader_LAST->SizeOfRawData > pSectionHeader_LAST->Misc.VirtualSize)?pSectionHeader_LAST->SizeOfRawData:pSectionHeader_LAST->Misc.VirtualSize;

	pSectionHeader->Misc.VirtualSize = pSectionHeader_LAST->VirtualAddress + LastSize - pSectionHeader->VirtualAddress;
	pSectionHeader->SizeOfRawData = pSectionHeader_LAST->VirtualAddress + LastSize - pSectionHeader->VirtualAddress;
	pSectionHeader->PointerToRawData = pSectionHeader->VirtualAddress;

	//设置属性值
	//pSectionHeader->Characteristics
	DWORD MyCharacteristics = pSectionHeader->Characteristics;
	for(int k=0;k<pPEHeader->NumberOfSections;k++)
	{
		PIMAGE_SECTION_HEADER pSectionHeader_NEXT;
		pSectionHeader_NEXT= (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+k*40);
		MyCharacteristics = MyCharacteristics |(pSectionHeader_NEXT->Characteristics);
	}

	printf("MyCharacteristics: %x \n",MyCharacteristics);
	pSectionHeader->Characteristics = MyCharacteristics;
	
	
	pPEHeader->NumberOfSections = 0x1;

	DWORD ImageSize  = pOptionHeader->SizeOfImage;

	//直接写出到文件
	WirteToFile(pImageBuffer,ImageSize,"C://hebing.exe");


}

关键是最后一个测试函数,其他 都是自己的测试代码





原文链接: PE段的合并 版权所有,转载时请注明出处,违者必究。
注明出处格式:流沙团 ( https://gyarmy.com/post-303.html )

发表评论

0则评论给“PE段的合并”