PE学习小结

主要学习了,PE的简单知识,代码进行了实现

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

#include "PEOperate.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include "windows.h"
#include "stdio.h"
#include "string.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;
}

DWORD FileOffsetToRVA(LPVOID pFileBuffer,DWORD dwFoa)
{
	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++)
	{
		DWORD dumpPointerToRawData = pSectionHeader->PointerToRawData;
		DWORD dumpSizeOfRaw = pSectionHeader->SizeOfRawData;

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

}

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);

}

DWORD Align(int size,int filesize)
{
	if(size<=filesize)
	{
		return filesize;
	}else
	{
		int n=0;
		if(size%filesize == 0)
		{
			n = size/filesize;
		}else{
			n = size/filesize;
			n=n+1;
		}

		return filesize*n;
		
	}
}


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");

}

//IMAGE_DATA_DIRECTORY
void printDirectoryData(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_DATA_DIRECTORY DataDirectory=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);

	//定位Directory_Data;
	DataDirectory = pOptionHeader->DataDirectory;
	
	//IMAGE_DIRECTORY_ENTRY_EXPORT
	printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
	
	printf("IMAGE_DIRECTORY_ENTRY_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size);

	printf("IMAGE_DIRECTORY_ENTRY_RESOURCE: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);

	printf("IMAGE_DIRECTORY_ENTRY_EXCEPTION: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size);

	printf("IMAGE_DIRECTORY_ENTRY_SECURITY: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size);
	
	printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

	printf("IMAGE_DIRECTORY_ENTRY_DEBUG: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size);

	printf("IMAGE_DIRECTORY_ENTRY_ARCHITECTURE: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].Size);

	printf("IMAGE_DIRECTORY_ENTRY_GLOBALPTR: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].Size);

	printf("IMAGE_DIRECTORY_ENTRY_TLS: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size);

	printf("IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size);

	printf("IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size);

	printf("IMAGE_DIRECTORY_ENTRY_IAT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size);

	printf("IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size);

	printf("IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size);
	

}

void TestExportDirectory(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_DATA_DIRECTORY DataDirectory=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);

	//定位Directory_Data;
	DataDirectory = pOptionHeader->DataDirectory;
	
	//导出表

	printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);

	//DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
	DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
	//printf("%x \n",FoA);

	DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
	DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
	FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address);

	/*
	typedef struct _IMAGE_EXPORT_DIRECTORY {
		DWORD   Characteristics;
		DWORD   TimeDateStamp;
		WORD    MajorVersion;
		WORD    MinorVersion;
		DWORD   Name;					//指向该导出表文件名字符串
		DWORD   Base;					//导出函数起始序号
		DWORD   NumberOfFunctions;		//所有导出函数的个数
		DWORD   NumberOfNames;			//以函数名字导出的函数个数	
		DWORD   AddressOfFunctions;     // 导出函数地址表 RVA
		DWORD   AddressOfNames;         // 导出函数名称表 RVA
		DWORD   AddressOfNameOrdinals;  // 导出函数序号表 RVA
	} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
	*/
	
	//定位导出表的位置

	PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL;
	pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA);

	printf("Characteristics: %x\n",pExDirectory->Characteristics);
	printf("TimeDateStamp: %x\n",pExDirectory->TimeDateStamp);
	printf("MajorVersion: %x\n",pExDirectory->MajorVersion);
	printf("MinorVersion: %x\n",pExDirectory->MinorVersion);
	printf("Name: %x\n",pExDirectory->Name);
	printf("Base: %x\n",pExDirectory->Base);
	printf("NumberOfFunctions: %x\n",pExDirectory->NumberOfFunctions);
	printf("NumberOfNames: %x\n",pExDirectory->NumberOfNames);
	printf("AddressOfFunctions: %x\n",pExDirectory->AddressOfFunctions);
	printf("AddressOfNames: %x\n",pExDirectory->AddressOfNames);
	printf("AddressOfNameOrdinals: %x\n",pExDirectory->AddressOfNameOrdinals);
	
	printf("------------------------\n");
	//输出函数地址表信息
	//AddressOfFunctions
	DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions;
	DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions);
	DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions;
	
	PDWORD pExAddressOfFunctions = NULL;
	pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA);

	//输出每个函数地址表信息
	DWORD k =0;
	for(k=0;k<ExNumberOfFunctions;k++)
	{
		printf("%d : %x \n",k,*pExAddressOfFunctions);
		pExAddressOfFunctions++;
	}
	printf("------------------------\n");
	//函数名称表
	DWORD ExAddressOfNames = pExDirectory->AddressOfNames;
	DWORD ExAddressOfNamesFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNames);
	DWORD ExNumberOfNames = pExDirectory->NumberOfNames;
	
	PDWORD pExAddressOfNames = NULL;
	pExAddressOfNames = (PDWORD)((DWORD)pFileBuffer + ExAddressOfNamesFoA);

	for(k=0;k<ExNumberOfNames;k++)
	{
		printf("%d : %x   \n",k,*pExAddressOfNames);
		//函数名的地址转换为FoA ,输出函数名
		PDWORD NameAddress = (PDWORD)RVAToFileOffset(pFileBuffer,*pExAddressOfNames);
		//输出函数名
		printf("%s \n",(char*)((DWORD)pFileBuffer + (DWORD)NameAddress));
		pExAddressOfNames++;
	}
	
	//函数序号表
	printf("------------------------\n");
	DWORD ExAddressOfNameOrdinals = pExDirectory->AddressOfNameOrdinals;
	DWORD ExAddressOfNameOrdinalsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNameOrdinals);
	ExNumberOfNames = pExDirectory->NumberOfNames;
	
	PWORD pExAddressOfNameOrdinals = NULL;
	pExAddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + ExAddressOfNameOrdinalsFoA);


	for(k=0;k<ExNumberOfNames;k++)
	{
		printf("%d : %x   \n",k,*pExAddressOfNameOrdinals);
		pExAddressOfNameOrdinals++;
	}
}

DWORD GetFunctionAddrByName(LPVOID pFileBuffer,LPSTR FunctionName)
{
	//LPVOID pFileBuffer = NULL;
	//pFileBuffer= ReadPEFile(lpszFile);
	if(!pFileBuffer)
	{
		printf("文件读取失败\n");
		return 0;
	}

	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_DATA_DIRECTORY DataDirectory=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);

	//定位Directory_Data;
	DataDirectory = pOptionHeader->DataDirectory;
	
	//导出表

	printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);

	//DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
	DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
	//printf("%x \n",FoA);

	DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
	DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
	FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address);

	//定位导出表的位置

	PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL;
	pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA);
	
	printf("------------------------\n");
	

	//输出每个函数地址表信息
	WORD k =0;
	
	//函数名称表
	DWORD ExAddressOfNames = pExDirectory->AddressOfNames;
	DWORD ExAddressOfNamesFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNames);
	DWORD ExNumberOfNames = pExDirectory->NumberOfNames;
	
	PDWORD pExAddressOfNames = NULL;
	pExAddressOfNames = (PDWORD)((DWORD)pFileBuffer + ExAddressOfNamesFoA);

	for(k=0;k<ExNumberOfNames;k++)
	{
		//printf("%d : %x   \n",k,*pExAddressOfNames);
		//函数名的地址转换为FoA ,输出函数名
		PDWORD NameAddress = (PDWORD)RVAToFileOffset(pFileBuffer,*pExAddressOfNames);
		//输出函数名
		//printf("%s \n",(char*)((DWORD)pFileBuffer + (DWORD)NameAddress));
		char* s_name = (char*)((DWORD)pFileBuffer + (DWORD)NameAddress);
		WORD num = strcmp(FunctionName,s_name);
		if(num==0)
		{
			break;
		}
		pExAddressOfNames++;
	}

	
	//函数的位置k
	WORD Location_Fun = k;
	printf("Function: %s\n",FunctionName);
	printf("Location_Fun: %d \n",Location_Fun); 
	
	//return 0;
	//函数序号表
	
	DWORD ExAddressOfNameOrdinals = pExDirectory->AddressOfNameOrdinals;
	DWORD ExAddressOfNameOrdinalsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNameOrdinals);
	ExNumberOfNames = pExDirectory->NumberOfNames;
	PWORD pExAddressOfNameOrdinals = NULL;
	pExAddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + ExAddressOfNameOrdinalsFoA);

	//函数表的序号
	WORD NUM_FUN = pExAddressOfNameOrdinals[Location_Fun];
	
	printf("NUM_FUN: %d \n",NUM_FUN); 
	
	//return 0;
	
	//输出函数地址表信息
	//AddressOfFunctions
	DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions;
	DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions);
	DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions;
	
	PDWORD pExAddressOfFunctions = NULL;
	pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA);
	
	//确定函数的地址

	DWORD Fun_Addr = pExAddressOfFunctions[NUM_FUN];
	return Fun_Addr;
}

DWORD GetFunctionAddrByOrdinals(LPVOID pFileBuffer,WORD FunctionOrdinals)
{
	if(!pFileBuffer)
	{
		printf("文件读取失败\n");
		return 0;
	}

	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_DATA_DIRECTORY DataDirectory=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);

	//定位Directory_Data;
	DataDirectory = pOptionHeader->DataDirectory;
	
	//导出表
	printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);

	//DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
	DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
	//printf("%x \n",FoA);

	DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
	DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
	FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address);

	//定位导出表的位置
	PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL;
	pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA);

	//直接定位函数的位置
	DWORD Function_Index = FunctionOrdinals-pExDirectory->Base; 
	
	//输出函数地址表信息
	//AddressOfFunctions
	DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions;
	DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions);
	DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions;
	
	PDWORD pExAddressOfFunctions = NULL;
	pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA);
	
	//确定函数的地址

	DWORD Fun_Addr = pExAddressOfFunctions[Function_Index];
	return Fun_Addr;

	//return 0;
}

void printDirectoryRelocTable(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_DATA_DIRECTORY DataDirectory=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);

	//定位Directory_Data;
	DataDirectory = pOptionHeader->DataDirectory;
	
	//重定位表

	printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

	//DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
	DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
	
	DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
	DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
	FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address);
	

	//定位到第一个重定位块
	PIMAGE_BASE_RELOCATION pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA);
	
	//输出所有的标信息
	while(pRelocData->VirtualAddress||pRelocData->SizeOfBlock)
	{
		DWORD RelocVirtualAddress = pRelocData->VirtualAddress;
		DWORD RelocSize = pRelocData->SizeOfBlock;

		printf("VirtualSize: %x ,Size: %x , Number: %x  \n",RelocVirtualAddress,RelocSize,(RelocSize-8)/2);
		
		int k = (RelocSize-8)/2;
		PWORD pMyRelocAddress = NULL;
		pMyRelocAddress = (PWORD)((DWORD)pRelocData+8);
		
		for(int i=0;i<k;i++)
		{
			printf("第%x个 : 标志 : %x 偏移 : %x\n",i+1,pMyRelocAddress[i]&0xF000,RelocVirtualAddress+(pMyRelocAddress[i]&0x0FFF));
		}
		pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocData + RelocSize);
	}

}

void TestMoveExportDirectory(LPSTR lpszFile)
{
	/*
	1 在DLL中新增一个节, 并返回新增的FOA
	2 复制AddressOfFunctions  长度:4*NumberOfFunctions
	3 复制AddressOfNameOrdinals  长度:NumberOfNames*2
	4 复制AddressOfNames  长度:NumberOfNames*4
	5 复制所有的函数名
		长度不确定,复制时直接修复AddressOfNames
	6 复制IMAGE_EXPORT_DIRECTORY结构
	7 修复IMAGE_EXPORT_DIRECTORY结构中的
		AddressOfFunctions
		AddressOfNameOrdinals
		AddressOfNames
	8 修复目录中项的值,指向新的IMAGE_EXPORT_DIRECTORY
	*/

}

void TestMoveRelocDirectory(LPSTR lpszFile)
{
	/*
	1 新增一个节
	2 把重定位的表 移动到那个节中
	3 更改标志位
	*/
	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;
	PIMAGE_DATA_DIRECTORY DataDirectory=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 = 0x2000;
	pSectionHeader_ADD->VirtualAddress = pOptionHeader->SizeOfImage;
	pSectionHeader_ADD->SizeOfRawData = 0x2000;
	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);

	
	//修改PE头信息
	pPEHeader->NumberOfSections = pPEHeader->NumberOfSections +1;
	pOptionHeader->SizeOfImage  = pOptionHeader->SizeOfImage+0x2000;

	//写入到文件
	FILE *pOutFile = NULL;	
	//打开文件
	pOutFile = fopen("C://addSec.dll","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(0x2000);
	if(pNewBuffer==NULL)
	{
		printf("pNewBuffer分配空间失败\n");
		return;
	}
	memset(pNewBuffer,0,0x2000);
	writeSize = fwrite(pNewBuffer,0x2000,1,pOutFile);
	//关闭文件
	fclose(pOutFile);
	free(pFileBuffer);
	free(pNewBuffer);

	//读入添加好节的文件
	pFileBuffer= ReadPEFile("C://addSec.dll");
	
	//将重定位表的信息,放到最后一个节中
		//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=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);

	//定位Directory_Data;
	DataDirectory = pOptionHeader->DataDirectory;
	
	//重定位表

	printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

	//DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
	DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
	
	DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
	DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
	FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address);
	

	//定位到第一个重定位块
	PIMAGE_BASE_RELOCATION pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA);
	PIMAGE_BASE_RELOCATION pRelocData_Start = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA);

	DWORD sizeOfRelocDirectory = 0;
	//计算重定位表的大小
	while(pRelocData->VirtualAddress||pRelocData->SizeOfBlock)
	{
		DWORD RelocVirtualAddress = pRelocData->VirtualAddress;
		DWORD RelocSize = pRelocData->SizeOfBlock;

		sizeOfRelocDirectory = sizeOfRelocDirectory + RelocSize;

		pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocData + RelocSize);
	}

	//起始位置pRelocData
	
	
	//移动
	PDWORD myRelocLoc = (PDWORD)pSectionHeader_ADD->PointerToRawData;
	printf("Reloc: %x , Size: %x \n",pRelocData,sizeOfRelocDirectory);

	//memcpy(myRelocLoc,pRelocData,sizeOfRelocDirectory);
	LPVOID destStart = (LPVOID)((DWORD)pFileBuffer + (DWORD)myRelocLoc);
	printf("pFileBuffer:%x, myRelocLoc: %x \n",pFileBuffer,destStart);
	LPVOID srcStart = (LPVOID)(pRelocData_Start);
	memcpy(destStart,srcStart,sizeOfRelocDirectory);
	
	//修改重定位表的参数
	DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = FileOffsetToRVA(pFileBuffer,pSectionHeader_ADD->PointerToRawData);
	//写出到dll中
	DWORD FileSize = pSectionHeader_ADD->PointerToRawData + pSectionHeader_ADD->SizeOfRawData;
	WirteToFile(pFileBuffer,FileSize,"C://addNewSec.dll");

}

void testUseReloc(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_DATA_DIRECTORY DataDirectory=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);
	//定位Directory_Data;
	DataDirectory = pOptionHeader->DataDirectory;
	
	//重定位表

	printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
		DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

	//DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
	DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
	
	DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
	DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
	FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address);
	

	//定位到第一个重定位块
	PIMAGE_BASE_RELOCATION pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA);
	
	//输出所有的标信息
	while(pRelocData->VirtualAddress||pRelocData->SizeOfBlock)
	{
		DWORD RelocVirtualAddress = pRelocData->VirtualAddress;
		DWORD RelocSize = pRelocData->SizeOfBlock;

		printf("VirtualSize: %x ,Size: %x , Number: %x  \n",RelocVirtualAddress,RelocSize,(RelocSize-8)/2);
		
		int k = (RelocSize-8)/2;
		PWORD pMyRelocAddress = NULL;
		pMyRelocAddress = (PWORD)((DWORD)pRelocData+8);
		
		for(int i=0;i<k;i++)
		{
			printf("第%x个 : 标志 : %x 偏移 : %x\n",i+1,pMyRelocAddress[i]&0xF000,RelocVirtualAddress+(pMyRelocAddress[i]&0x0FFF));
			//依次进行修改
			DWORD changeRVA = RelocVirtualAddress+(pMyRelocAddress[i]&0x0FFF);
			DWORD changeFoa = RVAToFileOffset(pFileBuffer,changeRVA);

			printf("changeRVA:%x   changeFoa: %x \n",changeRVA,changeFoa);

			if((pMyRelocAddress[i]&0xF000) == 0x3000)
			{
				//修改数据:
				PDWORD myAddress = (PDWORD)((DWORD)pFileBuffer + changeFoa);
				printf("myAddress: %x\n",*myAddress);
				*myAddress = *myAddress - 0x10000000 + 0x20000000;
				printf("change :myAddress: %x\n",*myAddress);
			}
		}
		pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocData + RelocSize);
	}

	//写出dll
	//确定大小
	LPVOID pFileBuffer_Start = pFileBuffer;
	DWORD FileSize = pSectionHeader_LAST->PointerToRawData + pSectionHeader_LAST->SizeOfRawData;	
	WirteToFile(pFileBuffer,FileSize,"C://changeDll.dll");

}



void TestPrintImportDirectory(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;
	PIMAGE_DATA_DIRECTORY pDataDirectory = 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);
	pDataDirectory = pOptionHeader->DataDirectory;

	//IMAGE_DIRECTORY_ENTRY_IMPORT 
	/*
	#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
	#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
	*/
	
	//确定导入表
	//pImportDirectory = NULL;
	IMAGE_DATA_DIRECTORY pImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
	
	DWORD ImportVirtualAddress = pImportDirectory.VirtualAddress;
	DWORD ImportFoa = RVAToFileOffset(pFileBuffer,ImportVirtualAddress);

	printf("ImportVirtualAddress: %x \n",ImportVirtualAddress);
	printf("Size: %x \n",pImportDirectory.Size);
	printf("ImportFoa: %x \n",ImportFoa);

	//输出所有的导入表
	//PIMAGE_THUNK_DATA32 pThunkData = NULL;
	//第一个导入表
	PIMAGE_IMPORT_DESCRIPTOR pImportDes = NULL;
	pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + ImportFoa);
	
	while(pImportDes->OriginalFirstThunk != 0x0 && pImportDes->FirstThunk != 0x0 )
	{
		//输出所有的dll
		printf("OriginalFirstThunk: %x\n",pImportDes->OriginalFirstThunk);
		DWORD pNameAddress =  RVAToFileOffset(pFileBuffer,pImportDes->Name);
		PSTR pDllName = (PSTR)((DWORD)pFileBuffer + pNameAddress);
		printf("name: %s \n",pDllName);
		printf("------------------------------------------\n");
		//输出OriginalFirstThunk的信息
		DWORD Thunk_Address = RVAToFileOffset(pFileBuffer,pImportDes->OriginalFirstThunk);
		PIMAGE_THUNK_DATA32 pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pFileBuffer + Thunk_Address);
		
		//根据pThunkData 的最高为来判断
		DWORD ImportOrdinal = pThunkData->u1.Ordinal;
		while(ImportOrdinal)
		{
			//输出所有所有的信息
			//#define IMAGE_ORDINAL_FLAG32 0x80000000
			if(ImportOrdinal & IMAGE_ORDINAL_FLAG32)
			{
				printf("按序号导入:%x\n",ImportOrdinal&0x0FFF);
			}else
			{
				DWORD ImageNameAddress  = RVAToFileOffset(pFileBuffer,ImportOrdinal);
				PIMAGE_IMPORT_BY_NAME pImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+ImageNameAddress);
				printf("按名字导入:%x - %s \n",pImageName->Hint,pImageName->Name);
			}
			//向下移动
			pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pThunkData + 4);
			ImportOrdinal = pThunkData->u1.Ordinal;
		}

		printf("------------------------------------------\n");
		//printf("FirstThunk:%x \n",pImportDes->FirstThunk);
		DWORD pFirstThunk = (DWORD)pImportDes->FirstThunk;
		printf("FirstThunk:%x \n",pImportDes->FirstThunk);
	
		printf("------------------------------------------\n");
		
		DWORD FirstThunk_Address = RVAToFileOffset(pFileBuffer,pFirstThunk);
		PIMAGE_THUNK_DATA32 pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pFileBuffer + FirstThunk_Address);

		DWORD newImportOrdinal = pNewThunkData->u1.Ordinal;
		while(newImportOrdinal)
		{
			//输出所有所有的信息
			//#define IMAGE_ORDINAL_FLAG32 0x80000000
			if(newImportOrdinal & IMAGE_ORDINAL_FLAG32)
			{
				printf("按序号导入:%x\n",newImportOrdinal&0x0FFF);
			}else
			{
				DWORD newImageNameAddress  = RVAToFileOffset(pFileBuffer,newImportOrdinal);
				PIMAGE_IMPORT_BY_NAME pNewImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+newImageNameAddress);
				printf("按名字导入:%x - %s \n",pNewImageName->Hint,pNewImageName->Name);
			}
			//向下移动
			pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pNewThunkData + 4);
			newImportOrdinal = pNewThunkData->u1.Ordinal;
		}

		printf("------------------------------------------\n");
		pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportDes + 20);

		//getchar();
	}
}

void TestPrintBindImportDirectory(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;
	PIMAGE_DATA_DIRECTORY pDataDirectory = 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);
	pDataDirectory = pOptionHeader->DataDirectory;

	//IMAGE_DIRECTORY_ENTRY_IMPORT 
	/*
		#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory
		#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers
	*/
	
	//确定导入表
	//pImportDirectory = NULL;
	IMAGE_DATA_DIRECTORY pBindImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT];
	
	DWORD BindImportVirtualAddress = pBindImportDirectory.VirtualAddress;
	DWORD BindImportFoa = BindImportVirtualAddress;

	/*
	printf("BindImportVirtualAddress: %x \n",BindImportVirtualAddress);
	printf("Size: %x \n",pBindImportDirectory.Size);
	printf("BindImportFoa: %x \n",BindImportFoa);
	*/
	PIMAGE_BOUND_IMPORT_DESCRIPTOR pBindImport = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + BindImportFoa);

	while(pBindImport->TimeDateStamp !=0x0)
	{
		//输出第一个绑定
		DWORD bindTime = pBindImport->TimeDateStamp;
		WORD ModuleName = pBindImport->OffsetModuleName;
		WORD numberModule = pBindImport->NumberOfModuleForwarderRefs;
		
		//输出名字
		PSTR pModuleName = (PSTR)((DWORD)pFileBuffer+(DWORD)BindImportVirtualAddress+ModuleName);
		printf("ModuleName:%s \n",pModuleName);
		printf("--numberModule:%x \n",numberModule);

		for(int i=0;i<numberModule;i++)
		{
			PIMAGE_BOUND_FORWARDER_REF pBoundRef = (PIMAGE_BOUND_FORWARDER_REF)((DWORD)pBindImport+i*8);
			pBindImport =  (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pBindImport+i*8);

			//输出名字
			DWORD refTime = pBoundRef->TimeDateStamp;
			WORD refName = pBoundRef->OffsetModuleName;
			PSTR pRefName = (PSTR)((DWORD)pFileBuffer+(DWORD)BindImportVirtualAddress+refName);	
			printf("        RefName:%s \n",pRefName);
		}

		pBindImport =  (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pBindImport+8);
	}
}

void TestPrintResourceICO(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;
	PIMAGE_DATA_DIRECTORY pDataDirectory = 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);
	pDataDirectory = pOptionHeader->DataDirectory;

	//IMAGE_DATA_DIRECTORY pBindImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT];
	IMAGE_DATA_DIRECTORY ResourceDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
	
	DWORD ResourceVirtualAddress = ResourceDirectory.VirtualAddress;
	DWORD ResourceSize = ResourceDirectory.Size;

	printf("ResourceVirtualAddress : %x \n",ResourceVirtualAddress);
	printf("ResourceSize: %x \n",ResourceSize);
	
	/*
		typedef struct _IMAGE_RESOURCE_DIRECTORY {
			DWORD   Characteristics;
			DWORD   TimeDateStamp;
			WORD    MajorVersion;
			WORD    MinorVersion;
			WORD    NumberOfNamedEntries;
			WORD    NumberOfIdEntries;
		//  IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
		} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;

  	//第一个导入表
	PIMAGE_IMPORT_DESCRIPTOR pImportDes = NULL;
	pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + ImportFoa);
	*/
	DWORD dwFoa = RVAToFileOffset(pFileBuffer,ResourceVirtualAddress);
	PIMAGE_RESOURCE_DIRECTORY  pResource = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + dwFoa);
	//输出PIMAGE_RESOURCE_DIRECTORY 的信息
	
	printf("NumberOfNamedEntries: %x \n",pResource->NumberOfNamedEntries);
	printf("NumberOfIdEntries: %x \n",pResource->NumberOfIdEntries);

	//第一层类型的解析
	//第一个资源表
	PIMAGE_RESOURCE_DIRECTORY_ENTRY pResdirectoryEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResource + sizeof(IMAGE_RESOURCE_DIRECTORY));
	DWORD NumberOfResType  =  pResource->NumberOfNamedEntries + pResource->NumberOfIdEntries;

	//找到图标资源
	PIMAGE_RESOURCE_DIRECTORY pResICODir=NULL;
	

	for(DWORD i=0;i<NumberOfResType;i++)
	{
		//解析内容:
		DWORD NameIsString = pResdirectoryEntry->NameIsString;
		DWORD ResName = pResdirectoryEntry->Name;
		DWORD OffsetToData = pResdirectoryEntry->OffsetToData;
		DWORD DataIsDirectory = pResdirectoryEntry->DataIsDirectory;
		
		//printf("Info: %d -NameIsString: %d - Name: %x -- OffToDa: %x - IsD - %d \n",i+1,
			//NameIsString,ResName,OffsetToData,DataIsDirectory);

		if(ResName == 0x3)
		{
			//PIMAGE_RESOURCE_DIRECTORY  pResource = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + dwFoa);
			pResICODir = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource +pResdirectoryEntry->OffsetToDirectory);
			break;
		}

		pResdirectoryEntry  = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResdirectoryEntry + 8);
	}
	
	


	//IMAGE_RESOURCE_DIR_STRING_U;
	/*
	NameIsString = 1 的时候指向的结构

	typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
		WORD    Length;
		WCHAR   NameString[ 1 ];
	} IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;
	
  */
	
	//确定图标的地址,找第二层
	DWORD NumberOffICO = pResICODir->NumberOfIdEntries + pResICODir->NumberOfNamedEntries;
	printf("NumberOffICO : %d \n",NumberOffICO);

	/*
		typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
			union {
				struct {
					DWORD NameOffset:31;
					DWORD NameIsString:1;
				};
				DWORD   Name;
				WORD    Id;
			};
			union {
				DWORD   OffsetToData;
				struct {
					DWORD   OffsetToDirectory:31;
					DWORD   DataIsDirectory:1;
				};
			};
		} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
	*/

	//第一个图标描述
	PIMAGE_RESOURCE_DIRECTORY_ENTRY pICOEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResICODir + sizeof(IMAGE_RESOURCE_DIRECTORY));
	
	PIMAGE_RESOURCE_DIRECTORY pICOContent = NULL;

	for(DWORD j = 0;j<NumberOffICO;j++)
	{
		//解析内容:
		DWORD NameIsString = pICOEntry->NameIsString;
		DWORD ResName = pICOEntry->Name;
		DWORD OffsetToData = pICOEntry->OffsetToData;
		DWORD DataIsDirectory = pICOEntry->DataIsDirectory;
		
		printf("Info: %d -NameIsString: %d - Name: %x -- OffToDa: %x - IsD - %d \n",i+1,
			NameIsString,ResName,OffsetToData,DataIsDirectory);
	
		//依次解析页码表
		pICOContent = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource +pICOEntry->OffsetToDirectory);
		//页码表解析
		DWORD NumberOfICOContent = pICOContent->NumberOfIdEntries + pICOContent->NumberOfNamedEntries;
		printf("NumberOfICOContent: %d \n",NumberOfICOContent);
		//图标测试只有一个,不循环测试
		//找到关键点:
		PIMAGE_RESOURCE_DIRECTORY_ENTRY pICOGetVS =  (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pICOContent + sizeof(IMAGE_RESOURCE_DIRECTORY));
		//找到图标资源的VistrualAddress 和 Size
		PIMAGE_DATA_DIRECTORY pDataIco = (PIMAGE_DATA_DIRECTORY)((DWORD)pResource + pICOGetVS->OffsetToDirectory);
		//输出每个图标信息
		printf("VirtualAddress: %x, Size: %x \n",pDataIco->VirtualAddress,pDataIco->Size);
		pICOEntry  = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pICOEntry + 8);
	}
}

 

原文链接: PE学习小结 版权所有,转载时请注明出处,违者必究。
注明出处格式:流沙团 ( https://gyarmy.com/post-330.html )

发表评论

0则评论给“PE学习小结”