可能很多的人都没有注意到一些事情,就是你的程序是不是合法的可运行的应用程序,例如一个文件只是把后缀改成 .exe 的形式就显示为应用程序的图标了! 你不想写一个根据后缀名就确定应用程序类型的程序吧!这样太哪个了吧!解决方法就是根据PE文件格式来解释。关于PE文件格式的资料现在网上汗牛充栋,这里我就不再解释,有兴趣的朋友可以上网查阅PE文件格式资料。我就简单的用代码去演示如何判断PE文件合法,主要就是两个地方,头为"MZ"签名,跟着DOS头部的就是"PE"签名,任何标准的PE文件都会包含这两个签名。如下这段代码所示,这是一个判断是否为合法PE文件的API。
1 BOOL IsValidPEFile( CString strPathName ) 2 { 3 if ( ! PathFileExists( strPathName ) ) 4 return FALSE; 5 6 // 根据 PE 签名判断当前文件是否合法的 PE 文件 7 HANDLE hFile = CreateFile( strPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 8 if ( hFile == INVALID_HANDLE_VALUE ) { 9 TRACE1( "Failed To Open File %s !\n", strPathName ); 10 return FALSE; 11 } 12 13 HANDLE hMMFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL ); 14 if ( hMMFile == INVALID_HANDLE_VALUE ) { 15 CloseHandle( hFile ); 16 return FALSE; 17 } 18 19 LPVOID pvMem = MapViewOfFile( hMMFile, FILE_MAP_READ, 0, 0, 0 ); 20 if ( ! pvMem ) { 21 CloseHandle( hMMFile ); 22 CloseHandle( hFile ); 23 return FALSE; 24 } 25 26 // 是否包含有 DOS 签名 27 if ( *( USHORT* ) pvMem != IMAGE_DOS_SIGNATURE ) { 28 UnmapViewOfFile( pvMem ); 29 CloseHandle( hMMFile ); 30 CloseHandle( hFile ); 31 return FALSE; 32 } 33 34 // 是否包含有 NT 签名 35 if ( *( ( DWORD* ) ( ( PBYTE ) pvMem + ( ( PIMAGE_DOS_HEADER ) pvMem )->e_lfanew ) ) != IMAGE_NT_SIGNATURE ) { 36 UnmapViewOfFile( pvMem ); 37 CloseHandle( hMMFile ); 38 CloseHandle( hFile ); 39 return FALSE; 40 } 41 42 UnmapViewOfFile( pvMem ); 43 CloseHandle( hMMFile ); 44 CloseHandle( hFile ); 45 46 return TRUE; 47 }
判断是否是窗口程序
1 BOOL IsWindowsApp( CString strPathName ) 2 { 3 if ( ! PathFileExists( strPathName ) ) 4 return FALSE; 5 6 // 根据 PE 签名判断当前文件是否合法的 PE 文件 7 HANDLE hFile = CreateFile( strPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 8 if ( hFile == INVALID_HANDLE_VALUE ) { 9 TRACE1( "Failed To Open File %s !\n", strPathName ); 10 return FALSE; 11 } 12 13 HANDLE hMMFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL ); 14 if ( hMMFile == INVALID_HANDLE_VALUE ) { 15 CloseHandle( hFile ); 16 return FALSE; 17 } 18 19 LPVOID pvMem = MapViewOfFile( hMMFile, FILE_MAP_READ, 0, 0, 0 ); 20 if ( ! pvMem ) { 21 CloseHandle( hMMFile ); 22 CloseHandle( hFile ); 23 return FALSE; 24 } 25 26 // 是否包含有 DOS 签名 27 if ( *( USHORT* ) pvMem != IMAGE_DOS_SIGNATURE ) { 28 UnmapViewOfFile( pvMem ); 29 CloseHandle( hMMFile ); 30 CloseHandle( hFile ); 31 return FALSE; 32 } 33 34 // 是否包含有 NT 签名 35 if ( *( ( DWORD* ) ( ( PBYTE ) pvMem + ( ( PIMAGE_DOS_HEADER ) pvMem )->e_lfanew ) ) != IMAGE_NT_SIGNATURE ) { 36 UnmapViewOfFile( pvMem ); 37 CloseHandle( hMMFile ); 38 CloseHandle( hFile ); 39 return FALSE; 40 } 41 42 LPVOID pvOptionalHeader = ( PBYTE ) pvMem + ( ( PIMAGE_DOS_HEADER ) pvMem )->e_lfanew + sizeof( DWORD ) + sizeof( IMAGE_FILE_HEADER ); 43 44 IMAGE_OPTIONAL_HEADER ioh; 45 CopyMemory( & ioh, pvOptionalHeader, sizeof( IMAGE_OPTIONAL_HEADER ) ); 46 47 if ( ioh.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI ) { 48 UnmapViewOfFile( pvMem ); 49 CloseHandle( hMMFile ); 50 CloseHandle( hFile ); 51 52 return TRUE; 53 } 54 55 return FALSE; 56 }
判断文件是否是控制台程序
1 BOOL IsCosoleApp( CString strPathName ) 2 { 3 if ( ! PathFileExists( strPathName ) ) 4 return FALSE; 5 6 // 根据 PE 签名判断当前文件是否合法的 PE 文件 7 HANDLE hFile = CreateFile( strPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 8 if ( hFile == INVALID_HANDLE_VALUE ) { 9 TRACE1( "Failed To Open File %s !\n", strPathName ); 10 return FALSE; 11 } 12 13 HANDLE hMMFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL ); 14 if ( hMMFile == INVALID_HANDLE_VALUE ) { 15 CloseHandle( hFile ); 16 return FALSE; 17 } 18 19 LPVOID pvMem = MapViewOfFile( hMMFile, FILE_MAP_READ, 0, 0, 0 ); 20 if ( ! pvMem ) { 21 CloseHandle( hMMFile ); 22 CloseHandle( hFile ); 23 return FALSE; 24 } 25 26 // 是否包含有 DOS 签名 27 if ( *( USHORT* ) pvMem != IMAGE_DOS_SIGNATURE ) { 28 UnmapViewOfFile( pvMem ); 29 CloseHandle( hMMFile ); 30 CloseHandle( hFile ); 31 return FALSE; 32 } 33 34 // 是否包含有 NT 签名 35 if ( *( ( DWORD* ) ( ( PBYTE ) pvMem + ( ( PIMAGE_DOS_HEADER ) pvMem )->e_lfanew ) ) != IMAGE_NT_SIGNATURE ) { 36 UnmapViewOfFile( pvMem ); 37 CloseHandle( hMMFile ); 38 CloseHandle( hFile ); 39 return FALSE; 40 } 41 42 LPVOID pvOptionalHeader = ( PBYTE ) pvMem + ( ( PIMAGE_DOS_HEADER ) pvMem )->e_lfanew + sizeof( DWORD ) + sizeof( IMAGE_FILE_HEADER ); 43 44 IMAGE_OPTIONAL_HEADER ioh; 45 CopyMemory( & ioh, pvOptionalHeader, sizeof( IMAGE_OPTIONAL_HEADER ) ); 46 47 if ( ioh.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI ) { 48 UnmapViewOfFile( pvMem ); 49 CloseHandle( hMMFile ); 50 CloseHandle( hFile ); 51 52 return TRUE; 53 } 54 55 return FALSE; 56 }