使用程序判断一个文件是否是有效的PE文件
程序员文章站
2022-07-05 10:18:48
...
判断一个文件是否为有效的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>;
推荐阅读