判断是不是PE文件

#include <stdio.h>
#include "assert.h"
#include <windows.h>
#include "TCHAR.H"

#ifdef UNICODE
#define IsPEFile  IsPEFileW
#define IsDigiSig IsDigiSigW
#else
#define IsPEFile  IsPEFileA
#define IsDigiSig IsDigiSigA
#endif // !UNICODE

//获得DOS头
LPVOID GetDosHeader(LPVOID lpFile)
{
	assert(lpFile != NULL);
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	if (lpFile != NULL)
		pDosHeader = (PIMAGE_DOS_HEADER)lpFile;

	return (LPVOID)pDosHeader;
}

//获得NT头
LPVOID GetNtHeader(LPVOID lpFile,BOOL& bX64)
{
	assert(lpFile != NULL);
	bX64 = FALSE;
	PIMAGE_NT_HEADERS32 pNtHeader32 = NULL;
	PIMAGE_NT_HEADERS64 pHeaders64 = NULL;

	PIMAGE_DOS_HEADER pDosHeader = NULL;
	if (lpFile != NULL)
		pDosHeader = (PIMAGE_DOS_HEADER)GetDosHeader(lpFile);
	//判断是否合法
    if (pDosHeader->e_magic !=IMAGE_DOS_SIGNATURE)
	    return NULL;

	pNtHeader32 = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader + pDosHeader->e_lfanew);
	//判断是不是正常的PE文件
	if (pNtHeader32->Signature != IMAGE_NT_SIGNATURE)
	    return NULL;

	if (pNtHeader32->FileHeader.Machine==IMAGE_FILE_MACHINE_AMD64) //64bit
	{
		bX64 = TRUE;
		pHeaders64 = (PIMAGE_NT_HEADERS64)((DWORD)pDosHeader + pDosHeader->e_lfanew);
		return pHeaders64;
	}

	return pNtHeader32;
}

//获得可选头
LPVOID GetOptionHeader(LPVOID lpFile,BOOL& bX64)
{
	assert(lpFile != NULL);
	bX64 = FALSE;
	LPVOID pOptionHeader = NULL;
	BOOL bX64Nt = FALSE;

	LPVOID pNtHeader = (LPVOID)GetNtHeader(lpFile,bX64Nt);
	if (pNtHeader == NULL)
	    return NULL;

	if (bX64Nt) //64bit
	{
		bX64 = TRUE;		
		pOptionHeader = (LPVOID) PIMAGE_OPTIONAL_HEADER64((DWORD)pNtHeader +sizeof( IMAGE_FILE_HEADER )+ sizeof(DWORD)) ;
	}else
	{
		pOptionHeader = (LPVOID) PIMAGE_OPTIONAL_HEADER32((DWORD)pNtHeader + sizeof( IMAGE_FILE_HEADER )+ sizeof(DWORD));
	}	
	return pOptionHeader;
}

/*
*  获取字段
*/
BOOL IsDigiSigEX(HANDLE hFile)
{
	if (hFile == INVALID_HANDLE_VALUE)  //文件对象
		return FALSE;
	HANDLE hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0, 0, NULL);
	if (hFileMapping == NULL)  
	{
		CloseHandle(hFile);
		return FALSE;
	}
	LPVOID lpFile = MapViewOfFile(hFileMapping,FILE_MAP_READ,0, 0, 0);
	if (lpFile==NULL)  //文件视图对象
	{
		CloseHandle(hFileMapping);
		CloseHandle(hFile);
		return FALSE;
	}

	IMAGE_DATA_DIRECTORY secData = { 0 };
	LPVOID pOptionHeader = NULL;
	BOOL bX64Opheader = FALSE;

	pOptionHeader     = (LPVOID)GetOptionHeader( lpFile,bX64Opheader );
	if(pOptionHeader != NULL && bX64Opheader)
	{
		secData = ((PIMAGE_OPTIONAL_HEADER64)pOptionHeader)->DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
	}
	else if(pOptionHeader != NULL)
	{
		secData = ((PIMAGE_OPTIONAL_HEADER32)pOptionHeader)->DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
	}

	UnmapViewOfFile(lpFile);
	CloseHandle(hFileMapping);
	CloseHandle(hFile);
	if ( ( secData.VirtualAddress != 0 ) && ( secData.Size != 0 ) )
		return TRUE;
	return FALSE;
}
//A版函数
BOOL IsDigiSigA(LPCSTR pPath)
{
	HANDLE hFile = CreateFileA(pPath,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
    return IsDigiSigEX(hFile);
}
//W版函数
BOOL IsDigiSigW(LPCWSTR pPath)
{
	HANDLE hFile = CreateFileW(pPath,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
	return IsDigiSigEX(hFile);
}

//实际判断PE文件操作
BOOL IsPEFileEX(HANDLE hFile,BOOL &bIsSucceed)
{
	if (hFile == INVALID_HANDLE_VALUE)  //文件对象
		return FALSE;
	HANDLE hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0, 0, NULL);
	if (hFileMapping == NULL)  
	{
		CloseHandle(hFile);
		return FALSE;
	}
	LPVOID lpFile = MapViewOfFile(hFileMapping,FILE_MAP_READ,0, 0, 0);
	if (lpFile==NULL)  //文件视图对象
	{
		CloseHandle(hFileMapping);
		CloseHandle(hFile);
		return FALSE;
	}

	PIMAGE_DOS_HEADER pDosHeader=NULL;
	PIMAGE_NT_HEADERS32 pNtHeader32 = NULL;
	//取得Dos头部
	pDosHeader = (PIMAGE_DOS_HEADER)lpFile;
	if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
	{
		UnmapViewOfFile(lpFile);
		CloseHandle(hFileMapping);
		CloseHandle(hFile);
		return TRUE;
	}

	//获取NT头
	pNtHeader32 = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader + pDosHeader->e_lfanew);
	//判断是不是PE文件
	if (pNtHeader32->Signature != IMAGE_NT_SIGNATURE)
	{
		UnmapViewOfFile(lpFile);
		CloseHandle(hFileMapping);
		CloseHandle(hFile);
		return TRUE;
	}

	UnmapViewOfFile(lpFile);
	CloseHandle(hFileMapping);
	CloseHandle(hFile);

	bIsSucceed = TRUE;
	return TRUE;
}

/*
*  函数执行成功返回true,失败返回false,A版
*  第二个参数为true表示是PE文件,false表示非PE文件
*/
BOOL IsPEFileA(LPCSTR pPath,BOOL &bIsSucceed)
{
	bIsSucceed = FALSE;
	HANDLE hFile = CreateFileA(pPath,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);	
	return IsPEFileEX(hFile,bIsSucceed);
}
//W版
BOOL IsPEFileW(LPCWSTR pPath,BOOL &bIsSucceed)
{
	bIsSucceed = FALSE;
	HANDLE hFile = CreateFileW(pPath,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);	
	return IsPEFileEX(hFile,bIsSucceed);
}

int main()
{
	char *test = "D:\\1.txt";
	//WCHAR *test = _T("D:\\tes.exe");

	BOOL bIsSucceed = FALSE;
	printf("%d\n",IsPEFile(test,bIsSucceed));  //实现的第一个函数
	printf("%d\n",bIsSucceed);
	printf("%d",IsDigiSig(test));  //实现的第二个函数,参数文件句柄

	getchar();
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值