判斷某exe字尾的檔案是否為PE格式

2021-05-22 02:00:27 字數 3446 閱讀 5788

如何判斷pe檔案合法,主要就是兩個地方,頭為"mz"簽名,跟著dos頭部的就是"pe"簽名,任何標準的pe檔案都會包含這兩個簽名。如下這段**所示,這是乙個判斷是否為合法pe檔案的api。

通過檔案對映實現pe檔案內容的讀取。

bool isvalidpefile( cstring strpathname )

if ( hmmfile == invalid_handle_value )

lpvoid pvmem = mapviewoffile( hmmfile, file_map_read, 0, 0, 0 );

if ( ! pvmem )

if ( *( ushort* ) pvmem != image_dos_signature )

if ( *( ( dword* ) ( ( pbyte ) pvmem + ( ( pimage_dos_header ) pvmem )->e_lfanew ) ) != image_nt_signature )

unmapviewoffile( pvmem );

closehandle( hmmfile );

closehandle( hfile );

return true;

}

這段**實現了對pe檔案合法性的判斷。

但是,我還希望對應用程式的型別作乙個更加徹底的判斷,如何知道應用程式是基於視窗形式的還是基於命令列形式的程式呢?

其實pe檔案中早已經包含了這種程式型別的標誌!這個標誌包含在pe檔案的頭部image_nt_header的結構中的 image_optional_header的sybsystem記錄! 看看"winnt.h"中對sybsystem的巨集定義。

#define image_subsystem_unknown 0 // unknown subsystem.

#define image_subsystem_native 1 // image doesn't require a subsystem.

#define image_subsystem_windows_gui 2 // image runs in the windows gui subsystem.

#define image_subsystem_windows_cui 3 // image runs in the windows character system

#define image_subsystem_os2_cui 5 // image runs in the os/2 character subsystem.

#define image_subsystem_posix_cui 7 // image runs in the posix character subsystem.

#define image_subsystem_native_windows 8 // image is a native win9x driver.

#define image_subsystem_windows_ce_gui 9 // image runs in the windows ce subsystem.

通過這些定議則可以輕易的判斷應用程式是何種形式的,當subsystem的值為image_subsystem_windows_gui的時候,則可以確定這個程式是基於圖形介面的,當它的值為image_subsystem_windows_cui的時候可以確定它為命令列的程式了。 核心的**如下:
// 根據 pe 簽名判斷當前檔案是否合法的 pe 檔案

handle hfile = createfile( strpathname, generic_read, file_share_read, null, open_existing, file_attribute_normal, null );

if ( hfile == invalid_handle_value )

lpvoid pvmem = mapviewoffile( hmmfile, file_map_read, 0, 0, 0 );

if ( ! pvmem )

// 是否包含有 dos 簽名

if ( *( ushort* ) pvmem != image_dos_signature )

// 是否包含有 nt 簽名

if ( *( ( dword* ) ( ( pbyte ) pvmem + ( ( pimage_dos_header ) pvmem )->e_lfanew ) ) != image_nt_signature )

lpvoid pvoptionalheader =  ( pbyte ) pvmem + ( ( pimage_dos_header ) pvmem )->e_lfanew + sizeof( dword ) + sizeof( image_file_header );
image_optional_header ioh;

copymemory( & ioh, pvoptionalheader, sizeof( image_optional_header ) );

if ( ioh.subsystem == image_subsystem_windows_gui )
return false;

}

// 根據 pe 簽名判斷當前檔案是否合法的 pe 檔案

handle hfile = createfile( strpathname, generic_read, file_share_read, null, open_existing, file_attribute_normal, null );

if ( hfile == invalid_handle_value )

lpvoid pvmem = mapviewoffile( hmmfile, file_map_read, 0, 0, 0 );

if ( ! pvmem )

// 是否包含有 dos 簽名

if ( *( ushort* ) pvmem != image_dos_signature )

// 是否包含有 nt 簽名

if ( *( ( dword* ) ( ( pbyte ) pvmem + ( ( pimage_dos_header ) pvmem )->e_lfanew ) ) != image_nt_signature )

lpvoid pvoptionalheader =  ( pbyte ) pvmem + ( ( pimage_dos_header ) pvmem )->e_lfanew + sizeof( dword ) + sizeof( image_file_header );
image_optional_header ioh;

copymemory( & ioh, pvoptionalheader, sizeof( image_optional_header ) );

if ( ioh.subsystem == image_subsystem_windows_cui )
return false;

}

判斷某整數是否為兩數平方之和

題 給定乙個整數 n,寫乙個程式判斷是否存在 2 個整數 a b a b 使得 a 2 b 2 n 如 輸入 n 5,輸出 true 輸入 n 7,輸出 false 思路 我們可以把整數n當成是乙個圓心在原點的園的半徑的平方。即圓的方程為 a 2 b 2 n。這樣,我們就可以使得a從1開始到根號n,...

C 判斷檔案是否為空

在 頭部引入 system.io 命名空間 第一種方法 using filestream fs new filestream c a.txt filemode.open 第二種方法 fileinfo fi new fileinfo c a.txt if fi.length 0 相比之下,第二種方法更...

shell判斷檔案是否為空

if s filename 如果檔案存在且為空,s代表存在不為空,將他取反 then okfi s 表示檔案是否存在並且是否為非空 判斷檔案的引數如下 e 檔案存在 f file 是乙個 regular 檔案 不是目錄或者裝置檔案 s 檔案長度不為 0 d 檔案是個目錄 b 檔案是個塊裝置 軟盤,c...