#pragma once
#include <DbgHelp.h> //ImageRvaToVa使用到
#pragma comment(lib,"Dbghelp")
#define _in
#define _out
typedef struct MAP_FILE_STRUCT
{
HANDLE hFile; //文件句柄
HANDLE hMap; //映射句柄
LPVOID ImageBase; //文件基地址
DWORD dwSize; //文件大小
char FileName[MAX_PATH]; //文件名
}MAP_FILE_STRUCT,*PMAP_FILE_STRUCT;
enum{
LFILE_FROM_NOMAL=0, //文件打開時的處理方式
LFILE_FROM_FILE, //從文件打開
LFILE_FROM_MEMORY //從內存打開
};
class LPEFile
{
public:
LPEFile(void);
~LPEFile(void);
private:
BYTE m_IsOpen; //文件打開狀態
MAP_FILE_STRUCT* m_pstMapFile; //文件及PE信息結構體
public:
//獲得文件名稱
void GetFileName(char* FileName);
BOOL LoadPeFile(char* lpFile,DWORD dwGeneric);
BOOL Free();
MAP_FILE_STRUCT* GetInfo(); //返回文件及PE信息對應的結構體
void SetInfo(MAP_FILE_STRUCT* pstMapFile);
void operator=(LPEFile& lPeFile);
BYTE* GetImage(void);
DWORD GetImageSize(void);
////獲得Dos頭
PIMAGE_DOS_HEADER GetDosHeader(void);
////獲得NT頭
PIMAGE_NT_HEADERS GetNtHeader(void);
PIMAGE_FILE_HEADER GetFileHeader(void);
PIMAGE_OPTIONAL_HEADER GetOptionalHeader(void);
PIMAGE_DATA_DIRECTORY GetDataDirectory(void);
PIMAGE_DATA_DIRECTORY GetDataDirectory(int nIndex);
PIMAGE_SECTION_HEADER GetFirstSection(void);
BOOL GetFileIsPE(void);
bool GetMachineString(WORD nValue,char* wchBuf);
void GetSubSystemString(WORD nValue,char* wchBuf);
PIMAGE_SECTION_HEADER GetSection(int nIndex);
int GetSectionCount(void);
LPVOID RvaToPtr(DWORD dwRVA);
LPVOID GetDataDirectoryEntryToData(USHORT DirectoryEntry);
HANDLE GetFileHandle();
//int StrMtoW(char* chBuf, wchar_t* wchBuf);
//int StrWtoM(wchar_t* wchBuf, char* chBuf);
};
下面是具體實現部分
#include "StdAfx.h"
#include "LPEFile.h"
#include <string.h> //strcpy_s
//構造函數
LPEFile::LPEFile(void)
{
m_IsOpen = LFILE_FROM_NOMAL;
m_pstMapFile = 0;
}
//析構函數
LPEFile::~LPEFile(void)
{
if(Free())
{
delete m_pstMapFile;
}
}
void LPEFile::GetFileName(char* FileName)
{
strcpy_s( FileName, MAX_PATH,m_pstMapFile->FileName);
}
/*/載入PE文件
參數一:指向文件名的長指針
參數二:打開後對文件的操作權限
返回值:成功或失敗*/
BOOL LPEFile::LoadPeFile(char* lpFile,DWORD dwGeneric)
{
HANDLE hFile,hMap; //文件句柄與映射文件句柄
hFile = CreateFile( lpFile, //FileName
dwGeneric, //打開後的權限
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, //其它程序文件的權限
NULL, //安全屬性
OPEN_EXISTING, //打開方式
0, //文件屬性,如果系統屬性,隱藏屬性等
0 //hTemplateFile
);
if(hFile == INVALID_HANDLE_VALUE) //如果CreateFile失敗,則返回失敗
{
return FALSE;
}
//更新文件的打開狀態,這裏爲以文件方式打開
m_IsOpen = LFILE_FROM_FILE;
//創建文件映射
hMap = CreateFileMapping(
hFile, //CreateFile返回的句柄
0, //安全屬性 LPSECURITY_ATTRIBUTES
PAGE_READONLY, //打開映射後返回的權限,這裏爲只讀
0, //DWORD dwMaximumSizeHigh
0, //DWORD dwMaximumSizeLow
0); //LPCTSTR lpName
if(hMap == 0)
{ //如果map失敗,則關閉文件句柄
CloseHandle(hFile);
return FALSE;
}
//文件及PE信息結構體
m_pstMapFile = new MAP_FILE_STRUCT;
m_pstMapFile->dwSize = GetFileSize( hFile, 0);
m_pstMapFile->ImageBase = MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, m_pstMapFile->dwSize);
m_pstMapFile->hFile = hFile;
strcpy_s(m_pstMapFile->FileName, lpFile);
return TRUE;
}
BOOL LPEFile::Free()
{
if(m_IsOpen == LFILE_FROM_FILE)
{ //如果打開方式是以文件方式打開
if(m_pstMapFile == NULL)
{
return TRUE;
}
if(m_pstMapFile->hMap)
{
UnmapViewOfFile( m_pstMapFile->hMap);
if(m_pstMapFile->hFile)
{
CloseHandle( m_pstMapFile->hFile);
m_pstMapFile = 0;
return TRUE;
}
}
}
return FALSE;
}
MAP_FILE_STRUCT* LPEFile::GetInfo()
{
return m_pstMapFile;
}
//更新 PE結構信息,科用於修改PE信息
void LPEFile::SetInfo(MAP_FILE_STRUCT* pstMapFile)
{
m_pstMapFile = pstMapFile;
}
//看看具體的MAP_FILE_STRUCT有沒有內容
BYTE* LPEFile::GetImage(void)
{
if(m_pstMapFile == ((MAP_FILE_STRUCT*)0xCCCCCCCC) ||
m_IsOpen == LFILE_FROM_NOMAL)
return 0;
return (BYTE*)m_pstMapFile->ImageBase;
}
//獲得鏡像大小
DWORD LPEFile::GetImageSize(void)
{
if(m_pstMapFile == 0)
return 0;
return m_pstMapFile->dwSize;
}
//獲得DOS頭
PIMAGE_DOS_HEADER LPEFile::GetDosHeader(void)
{
BYTE* ImageBase = GetImage();
if(ImageBase != 0)
return (PIMAGE_DOS_HEADER)ImageBase;
return 0;
}
//獲得NT頭
PIMAGE_NT_HEADERS LPEFile::GetNtHeader(void)
{
PIMAGE_DOS_HEADER pDosH = GetDosHeader();
if(pDosH != 0)
return (PIMAGE_NT_HEADERS)(pDosH->e_lfanew + GetImage());
return false;
}
//獲得文件頭
PIMAGE_FILE_HEADER LPEFile::GetFileHeader(void)
{
PIMAGE_NT_HEADERS pNtH = GetNtHeader();
if(pNtH != NULL)
return (PIMAGE_FILE_HEADER)&pNtH->FileHeader;
return 0;
}
//獲得可選頭信息
PIMAGE_OPTIONAL_HEADER LPEFile::GetOptionalHeader(void)
{
PIMAGE_NT_HEADERS pNtH = GetNtHeader();
if(pNtH != 0)
return (PIMAGE_OPTIONAL_HEADER)&pNtH->OptionalHeader;
return 0;
}
PIMAGE_DATA_DIRECTORY LPEFile::GetDataDirectory(void)
{
PIMAGE_OPTIONAL_HEADER poh = GetOptionalHeader();
if(poh != 0)
return (PIMAGE_DATA_DIRECTORY)&poh->DataDirectory;
return 0;
}
//通過索引方式獲得數據目錄
PIMAGE_DATA_DIRECTORY LPEFile::GetDataDirectory(int nIndex)
{
PIMAGE_DATA_DIRECTORY pDataDir = GetDataDirectory();
if(pDataDir != 0)
return (PIMAGE_DATA_DIRECTORY)&pDataDir[nIndex];
return 0;
}
//獲得第一個節
PIMAGE_SECTION_HEADER LPEFile::GetFirstSection(void)
{
PIMAGE_NT_HEADERS pNtH = GetNtHeader();
if(pNtH != 0)
return (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(pNtH);
return 0;
}
//判斷是否是PE文件
BOOL LPEFile::GetFileIsPE(void)
{
PIMAGE_DOS_HEADER pDosHeader = GetDosHeader();
if(pDosHeader == 0)
return FALSE;
if(pDosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
PIMAGE_NT_HEADERS pNtH = GetNtHeader();
if(pNtH->Signature == IMAGE_NT_SIGNATURE)
return TRUE;
}
return FALSE;
}
bool LPEFile::GetMachineString(WORD nValue,char* wchBuf)
{
bool bIsSuccess = true;
switch(nValue)
{
case IMAGE_FILE_MACHINE_I386: strcpy_s( wchBuf, 50,"x86"); break;
case IMAGE_FILE_MACHINE_IA64: strcpy_s( wchBuf, 50,"Intel Itanium"); break;
case IMAGE_FILE_MACHINE_AMD64: strcpy_s( wchBuf, 50,"x64"); break;
default: bIsSuccess = false; break;
}
return bIsSuccess;
}
void LPEFile::GetSubSystemString(WORD nValue,char* wchBuf)
{
switch(nValue)
{
case IMAGE_SUBSYSTEM_UNKNOWN: strcpy_s( wchBuf, 50,"未知的子系統"); break;
case IMAGE_SUBSYSTEM_NATIVE: strcpy_s( wchBuf, 50,"不需要子系統"); break;
case IMAGE_SUBSYSTEM_WINDOWS_GUI: strcpy_s( wchBuf, 50,"圖形界面"); break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI: strcpy_s( wchBuf, 50,"控制檯界面"); break;
case IMAGE_SUBSYSTEM_OS2_CUI: strcpy_s( wchBuf, 50,"OS2控制檯界面"); break;
case IMAGE_SUBSYSTEM_POSIX_CUI: strcpy_s( wchBuf, 50,"POSIX控制檯界面"); break;
case IMAGE_SUBSYSTEM_NATIVE_WINDOWS: strcpy_s( wchBuf, 50,"不需要子系統"); break;
case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: strcpy_s( wchBuf, 50,"CE圖形界面"); break;
}
}
//通過節數目獲得相應的信息
PIMAGE_SECTION_HEADER LPEFile::GetSection(int nIndex)
{
int nCount = GetSectionCount();
if( nIndex >= nCount || nIndex < 0)
return 0;
PIMAGE_SECTION_HEADER psh = GetFirstSection();
for(int i=0; i< nCount; i++, psh++)
{
if( nIndex == i)
return psh;
}
return 0;
}
//返回節數目
int LPEFile::GetSectionCount(void)
{
PIMAGE_FILE_HEADER pfh = GetFileHeader();
if(pfh != 0)
return pfh->NumberOfSections;
return 0;
}
LPVOID LPEFile::RvaToPtr(DWORD dwRVA)
{
PIMAGE_NT_HEADERS pNtHead = GetNtHeader();
return ImageRvaToVa( pNtHead, GetImage(), dwRVA, 0);
}
LPVOID LPEFile::GetDataDirectoryEntryToData(USHORT DirectoryEntry)
{
//起始RVA
DWORD dwDataStartRva = GetDataDirectory(DirectoryEntry)->VirtualAddress;
LPVOID pDirData = RvaToPtr( dwDataStartRva);
if(pDirData != NULL)
return pDirData;
return 0;
}
//int LPEFile::StrMtoW(_in char* chBuf,_out wchar_t* wchBuf)
//{
// int nSize = 0;
// if(chBuf == 0)
// return -1;
// nSize = MultiByteToWideChar( CP_ACP, 0, chBuf, -1, 0, 0);
// MultiByteToWideChar(CP_ACP, 0, chBuf, -1 , wchBuf, nSize);
//
// return nSize;
//}
//
//int LPEFile::StrWtoM(_in wchar_t* wchBuf,_out char* chBuf)
//{
// int nSize = 0;
// if(wchBuf == NULL)
// {
// return -1;
// }
//
// nSize = WideCharToMultiByte(CP_ACP, 0, wchBuf, -1, 0, 0, 0, 0);
//
// if(chBuf != NULL)
// {
// WideCharToMultiByte(CP_ACP, 0, wchBuf, -1, chBuf, nSize, 0, 0);
// }
//
// return nSize;
//}
只要編寫一個程序,來調用這些類中函數就可以了。