天天看點

使用程式判斷一個檔案是否是有效的PE檔案

判斷一個檔案是否為有效的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時如下,

使用程式判斷一個檔案是否是有效的PE檔案

測試 notepad.exe 如下,

使用程式判斷一個檔案是否是有效的PE檔案

目前程式可用;

這一句如果寫為,

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>;