判斷一個檔案是否為有效的PE檔案,判斷2個字段:
DOS頭的e_magic字段是否為0x5A4D;
NT頭的Signature字段是否為0x00004550;
若都是的話則是一個有效的PE檔案;
VC6,單文檔工程;
void CIspeView::OnDraw(CDC* pDC)
{
CIspeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
//HANDLE hFile = CreateFile(TEXT("test.png"), GENERIC_ALL, NULL, NULL,OPEN_EXISTING,NULL,NULL);
HANDLE hFile = CreateFile(TEXT("notepad.exe"), GENERIC_ALL, NULL, NULL,OPEN_EXISTING,NULL,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
//std::cout << "打開檔案失敗!" << std::endl;
pDC->TextOut(20,20,"打開檔案失敗!");
CloseHandle(hFile);
exit(EXIT_SUCCESS);
}
// 擷取檔案的大小
DWORD dwFileSize = GetFileSize(hFile, NULL);
// 申請記憶體空間,用于存放檔案資料
BYTE * FileBuffer = new BYTE[dwFileSize];
// 讀取檔案内容
DWORD dwReadFile = 0;
ReadFile(hFile, FileBuffer, dwFileSize, &dwReadFile, NULL);
//檢查DOS頭中的MZ标記,判斷e_magic字段是否為0x5A4D,或者是IMAGE_DOS_SIGNATURE
DWORD dwFileAddr = (DWORD)FileBuffer;
//auto DosHeader = (PIMAGE_DOS_HEADER)dwFileAddr;
PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)dwFileAddr;
if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
// 如果不是則提示使用者,并立即結束
::MessageBox(NULL, TEXT("這不是一個有效PE檔案"), TEXT("提示"), MB_OK);
delete FileBuffer;
CloseHandle(hFile);
exit(EXIT_SUCCESS);
}
// 若都通過的話再擷取NT頭所在的位置,并判斷Signature字段是否為0x00004550,或者是IMAGE_NT_SIGNATURE
//auto NtHeader = (PIMAGE_NT_HEADERS)(dwFileAddr + DosHeader->e_lfanew);
PIMAGE_NT_HEADERS NtHeader = (PIMAGE_NT_HEADERS)(dwFileAddr + DosHeader->e_lfanew);
if (NtHeader->Signature != IMAGE_NT_SIGNATURE)
{
// 如果不是則提示使用者,并立即結束
::MessageBox(NULL, TEXT("這不是一個有效PE檔案"), TEXT("提示"), MB_OK);
delete FileBuffer;
CloseHandle(hFile);
exit(EXIT_SUCCESS);
}
// 若上述都通過,則為一個有效的PE檔案
//MessageBox(NULL, TEXT("這是一個有效PE檔案"), TEXT("提示"), MB_OK);
pDC->TextOut(20,60,"這是一個有效PE檔案");
delete FileBuffer;
CloseHandle(hFile);
}
拷貝一個test.png,notepad.exe到工程目錄;
當測試test.png時如下,

測試 notepad.exe 如下,
目前程式可用;
這一句如果寫為,
auto DosHeader = (PIMAGE_DOS_HEADER)dwFileAddr;
則報錯,
cannot convert from 'struct _IMAGE_DOS_HEADER *' to 'int'
改為,
PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)dwFileAddr;
如果是控制台版本則需要包含 #include <windows.h>;