PE编程汇总

这篇博客主要汇总了关于PE编程的相关知识,包括如何判断一个文件是否为有效的PE文件,使用C语言进行文件的读写操作,以及通过文件指针对PE文件的处理。内容将涉及RVA转换、输入输出表的获取和文件目录等核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

判断是否为有效PE文件:

(c 版读写文件)

//通过判断DOS头标志和PE头标志以及PE头属性值来确定文件是否可执行文件
BOOL IsExeFile(HANDLE hFile)
{
	DWORD nCount;
	BOOL bResult = FALSE;
	IMAGE_DOS_HEADER dosHeader;
	IMAGE_NT_HEADERS ntHeader;

	ReadFile(hFile,&dosHeader,sizeof(dosHeader),&nCount,NULL);
	if (nCount == sizeof(dosHeader))
	{
		//有效的DOS头
		if (IMAGE_DOS_SIGNATURE == dosHeader.e_magic)
		{
			if (SetFilePointer(hFile,dosHeader.e_lfanew,NULL,FILE_BEGIN) != -1)
			{//NT头检查
				ReadFile(hFile,&ntHeader,sizeof(ntHeader),&nCount,NULL);
				if(nCount == sizeof(ntHeader))
					if(IMAGE_NT_SIGNATURE == ntHeader.Signature)
						if(ntHeader.FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)
						{
							bResult = TRUE;
						}
			}
		}
	}
	SetFilePointer(hFile,0,NULL,FILE_BEGIN);

	return bResult;
}

(以下通过文件指针操作)

//通过ImageBase 文件指针判断,映像基址由MapViewOfFile函数获得
BOOL IsPEFile(LPVOID ImageBase)
{
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNtHeader = NULL;
	
	if(!ImageBase)    //指针安全检查
		return FALSE;
	//DOS头和PE头检查	
	pDosHeader = (PIMAGE_DOS_HEADER)ImageBase; //转换ImageBase为PIMAGE_DOS_HEADER结构变量类型
	if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
		return FALSE;
	pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew); 
	//一般可等同于 pNtHeader = (PIMAGE_NT_HEADERS32)(pDosHeader->e_lfanew);
	if(pNtHeader->Signature != IMAGE_NT_SIGNATURE)
		return FALSE;
	return TRUE;
}

//映像基址的获取
	HANDLE hFile;
	HANDLE hMapping;
	LPVOID ImageBase;
	HANDLE hFile = CreateFile(szFilePath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if(INVALID_HANDLE_VALUE == hFile) 
		 return  FALSE;
	//可以添加判断空文件语句
    hMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
	if(!hMapping)
	{									
		CloseHandle(hFile);
		return FALSE;
	}
	ImageBase = MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);
    if(!ImageBase)
	{									
		CloseHandle(hMapping);
		CloseHandle(hFile);
		return FALSE;
	}

//获取 NT头、文件头、可选头、区块
PIMAGE_NT_HEADERS32 GetNtHeader(LPVOID ImageBase)
{
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS32 pNtHeader = NULL;

	if(!ImageBase)
		return NULL;

	pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
	pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);

	return  pNtHeader;
}

PIMAGE_FILE_HEADER GetFileHeader(LPVOID	Imagebase)
{  
	PIMAGE_NT_HEADERS pNtHeader = NULL;
	pNtHeader = GetNtHeader(Imagebase);
	if(!pNtHeader)
		return NULL;
	else
		return &pNtHeader->FileHeader; 
}

PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase)
{
  PIMAGE_NT_HEADERS32 pNtHeader = NULL;
  pNtHeader=GetNtHeaders(ImageBase);
  if(!pNtHeader)
     return NULL;
  else
     return &pNtHeader->OptionalHeader;
}

//获得区块表指针
PIMAGE_SECTION_HEADER GetSectionHeader(LPVOID ImageBase)
{
	return (PIMAGE_SECTION_HEADER)
	(GetOptionalHeader(ImageBase)+sizeof(IMAGE_OPTIONAL_HEADER));
}	

//待添加: rva转化、输入输出表获取、文件目录等



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值