CPEHeaderUtils.h
#pragma once
#include <wtypesbase.h>
#include <string>
#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif
class CPEHeader
{
public:
CPEHeader();
~CPEHeader();
CPEHeader& operator = (const CPEHeader& r) = delete;
// 从文件加载PE文件头信息
bool Load(const _tstring strFile);
// 是否为有效PE信息
bool IsValidPEHeader() const;
// 获取计算机的体系结构类型
WORD GetMachine() const;
// 获取映像文件特征
WORD GetCharacteristics() const;
// 获取运行映像所需的子系统
WORD GetSubSystem() const;
// 获取Dll特征
WORD GetDllCharacteristics() const;
// 获取校验和
DWORD GetCheckSum() const;
// 计算机的体系结构类型检查
bool IsX86() const; //是否为 X86 平台
bool IsX64() const; //是否为 X64 平台
bool IsARM64() const; //是否为 ARM64 平台
bool IsIA64() const; //是否为 英特尔的安腾(Intel Itanium) 平台
// 文件特征检查
bool IsDllFile() const; //映像是否为一个 DLL 文件
bool IsExecutable() const; //映像是否为一个 可执行文件
bool IsSystemFile() const; //映像是否为一个 系统文件
bool IsLargeAddressAware() const; //映像是否 可以处理大于 2 GB 的地址
// 子系统检查
bool IsWindowsGUI() const; //是否运行于windows 图形用户界面 (GUI) 子系统
bool IsWindowsCUI() const; //是否运行于Windows 字符模式用户界面 (CUI) 子系统
bool IsWindowsBootApplication() const; //是否为启动应用程序
private:
void Clear();
private:
//基础PE信息
IMAGE_DOS_HEADER m_DosHeader; //Dos头
IMAGE_NT_HEADERS32 m_NtHeaders32; //NT头(32位)
IMAGE_NT_HEADERS64 m_NtHeaders64; //NT头(64位)
IMAGE_ROM_HEADERS m_RomHeaders; //ROM头
WORD m_NtHeadersMagic; //NT头魔数
};
CPEHeaderUtils.cpp
#include "CPEHeaderUtils.h"
CPEHeader::CPEHeader()
{
Clear();
}
CPEHeader::~CPEHeader()
{
}
void CPEHeader::Clear()
{
memset(&m_DosHeader, 0, sizeof(m_DosHeader));
memset(&m_NtHeaders32, 0, sizeof(m_NtHeaders32));
memset(&m_NtHeaders64, 0, sizeof(m_NtHeaders64));
memset(&m_RomHeaders, 0, sizeof(m_RomHeaders));
m_NtHeadersMagic = 0;
}
bool CPEHeader::Load(const _tstring strFile)
{
HMODULE hModule = NULL;
bool fResult = false;
LPVOID OldValue = NULL;
BOOL isDisableWow64Fs = ::Wow64DisableWow64FsRedirection(&OldValue);
Clear();
do
{
hModule = ::LoadLibraryEx(strFile.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
if (NULL == hModule)
{
break;
}
LPBYTE pHeader = (BYTE*)hModule;
BYTE* pImageData = (BYTE*)((ULONG_PTR)pHeader & ~((ULONG_PTR)0x03));
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pImageData;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
break;
}
m_DosHeader = *pDosHeader;
PIMAGE_NT_HEADERS pNtHeader = (IMAGE_NT_HEADERS*)((BYTE*)(pDosHeader)+(DWORD)(pDosHeader->e_lfanew));
if (IMAGE_NT_SIGNATURE != pNtHeader->Signature)
{
break;
}
// 检查 是否为 32位程序可选头
if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == pNtHeader->OptionalHeader.Magic)
{
m_NtHeaders32 = *((PIMAGE_NT_HEADERS32)pNtHeader);
}
// 检查 是否为 64位程序可选头
else if (IMAGE_NT_OPTIONAL_HDR64_MAGIC == pNtHeader->OptionalHeader.Magic)
{
m_NtHeaders64 = *((PIMAGE_NT_HEADERS64)pNtHeader);
}
// ROM可选头
else if (IMAGE_ROM_OPTIONAL_HDR_MAGIC == pNtHeader->OptionalHeader.Magic)
{
m_RomHeaders = *((PIMAGE_ROM_HEADERS)pNtHeader);
}
else
{
break;
}
m_NtHeadersMagic = pNtHeader->OptionalHeader.Magic;
fResult = true;
} while (false);
if (isDisableWow64Fs)
{
::Wow64RevertWow64FsRedirection(OldValue);
}
if (!fResult)
{
Clear();
}
if (NULL != hModule)
{
::FreeLibrary(hModule);
}
return fResult;
}
bool CPEHeader::IsValidPEHeader() const
{
if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == m_NtHeadersMagic ||
IMAGE_NT_OPTIONAL_HDR64_MAGIC == m_NtHeadersMagic)
{
return true;
}
return false;
}
WORD CPEHeader::GetMachine() const
{
if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == m_NtHeadersMagic)
{
return m_NtHeaders32.FileHeader.Machine;
}
if (IMAGE_NT_OPTIONAL_HDR64_MAGIC == m_NtHeadersMagic)
{
return m_NtHeaders64.FileHeader.Machine;
}
return 0;
}
WORD CPEHeader::GetCharacteristics() const
{
if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == m_NtHeadersMagic)
{
return m_NtHeaders32.FileHeader.Characteristics;
}
if (IMAGE_NT_OPTIONAL_HDR64_MAGIC == m_NtHeadersMagic)
{
return m_NtHeaders64.FileHeader.Characteristics;
}
return 0;
}
WORD CPEHeader::GetSubSystem() const
{
if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == m_NtHeadersMagic)
{
return m_NtHeaders32.OptionalHeader.Subsystem;
}
if (IMAGE_NT_OPTIONAL_HDR64_MAGIC == m_NtHeadersMagic)
{
return m_NtHeaders64.OptionalHeader.Subsystem;
}
return 0;
}
WORD CPEHeader::GetDllCharacteristics() const
{
if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == m_NtHeadersMagic)
{
return m_NtHeaders32.OptionalHeader.DllCharacteristics;
}
if (IMAGE_NT_OPTIONAL_HDR64_MAGIC == m_NtHeadersMagic)
{
return m_NtHeaders64.OptionalHeader.DllCharacteristics;
}
return 0;
}
DWORD CPEHeader::GetCheckSum() const
{
if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == m_NtHeadersMagic)
{
return m_NtHeaders32.OptionalHeader.CheckSum;
}
if (IMAGE_NT_OPTIONAL_HDR64_MAGIC == m_NtHeadersMagic)
{
return m_NtHeaders64.OptionalHeader.CheckSum;
}
return 0;
}
bool CPEHeader::IsX86() const
{
return IMAGE_FILE_MACHINE_I386 == GetMachine();
}
bool CPEHeader::IsX64() const
{
return IMAGE_FILE_MACHINE_AMD64 == GetMachine();
}
bool CPEHeader::IsARM64() const
{
return IMAGE_FILE_MACHINE_ARM64 == GetMachine();
}
bool CPEHeader::IsIA64() const
{
return IMAGE_FILE_MACHINE_IA64 == GetMachine();
}
bool CPEHeader::IsDllFile() const
{
return IMAGE_FILE_DLL & GetCharacteristics();
}
bool CPEHeader::IsExecutable() const
{
return IMAGE_FILE_EXECUTABLE_IMAGE & GetCharacteristics();
}
bool CPEHeader::IsSystemFile() const
{
return IMAGE_FILE_SYSTEM & GetCharacteristics();
}
bool CPEHeader::IsLargeAddressAware() const
{
return IMAGE_FILE_LARGE_ADDRESS_AWARE & GetCharacteristics();
}
bool CPEHeader::IsWindowsGUI() const
{
return IMAGE_SUBSYSTEM_WINDOWS_GUI == GetSubSystem();
}
bool CPEHeader::IsWindowsCUI() const
{
return IMAGE_SUBSYSTEM_WINDOWS_CUI == GetSubSystem();
}
bool CPEHeader::IsWindowsBootApplication() const
{
return IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION == GetSubSystem();
}
main.cpp
#include <locale.h>
#include <tchar.h>
#include "Win32Utils/CPEHeaderUtils.h"
int _tmain(int argc, LPCTSTR argv[])
{
::setlocale(LC_ALL, "");
CPEHeader obj;
obj.Load(_T(R"(kernel32.dll)"));
_tprintf(_T("IsDllFile: %d\n"), obj.IsDllFile());
_tprintf(_T("IsExecutable: %d\n"), obj.IsExecutable());
_tprintf(_T("IsARM64: %d\n"), obj.IsARM64());
_tprintf(_T("IsIA64: %d\n"), obj.IsIA64());
_tprintf(_T("IsX64: %d\n"), obj.IsX64());
_tprintf(_T("IsX86: %d\n"), obj.IsX86());
_tprintf(_T("IsLargeAddressAware: %d\n"), obj.IsLargeAddressAware());
_tprintf(_T("IsSystemFile: %d\n"), obj.IsSystemFile());
_tprintf(_T("IsWindowsBootApplication: %d\n"), obj.IsWindowsBootApplication());
_tprintf(_T("IsWindowsCUI: %d\n"), obj.IsWindowsCUI());
_tprintf(_T("IsWindowsGUI: %d\n"), obj.IsWindowsGUI());
return 0;
}