c语言怎么判断文件类型,判断你的文件是否为合法的PE文件和应用类型

作者:赖锋

源代码下载

可能很多的人都没有注意到一些事情,就是你的程序是不是合法的可运行的应用程序,例如一个文件只是把后缀改成 .exe 的形式就显示为应用程序的图标了! 你不想写一个根据后缀名就确定应用程序类型的程序吧!这样太哪个了吧!解决方法就是根据PE文件格式来解释。关于PE文件格式的资料现在网上汗牛充栋,这里我就不再解释,有兴趣的朋友可以上网查阅PE文件格式资料。我就简单的用代码去演示如何判断PE文件合法,主要就是两个地方,头为”MZ”签名,跟着DOS头部的就是”PE”签名,任何标准的PE文件都会包含这两个签名。如下这段代码所示,这是一个判断是否为合法PE文件的API。

通过文件映射实现PE文件内容的读取。BOOL IsValidPEFile( CString strPathName )

{

if ( ! PathFileExists( strPathName ) )

return FALSE;

HANDLE hFile = CreateFile( strPathName,

GENERIC_READ,

FILE_SHARE_READ,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL );

if ( hFile == INVALID_HANDLE_VALUE ) {

TRACE1( “Failed To Open File %s !\n”, strPathName );

return FALSE;

}

HANDLE hMMFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL );

if ( hMMFile == INVALID_HANDLE_VALUE ) {

CloseHandle( hFile );

return FALSE;

}

LPVOID pvMem = MapViewOfFile( hMMFile, FILE_MAP_READ, 0, 0, 0 );

if ( ! pvMem ) {

CloseHandle( hMMFile );

CloseHandle( hFile );

return FALSE;

}

if ( *( USHORT* ) pvMem != IMAGE_DOS_SIGNATURE ) {

UnmapViewOfFile( pvMem );

CloseHandle( hMMFile );

CloseHandle( hFile );

return FALSE;

}

if ( *( ( DWORD* ) ( ( PBYTE ) pvMem + ( ( PIMAGE_DOS_HEADER ) pvMem )->e_lfanew ) ) != IMAGE_NT_SIGNATURE ) {

UnmapViewOfFile( pvMem );

CloseHandle( hMMFile );

CloseHandle( hFile );

return FALSE;

}

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的时候可以确定它为命令行的程序了。 核心的代码如下: 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 ) {

UnmapViewOfFile( pvMem );

CloseHandle( hMMFile );

CloseHandle( hFile );

return TRUE;

}  这个详细解释我就略过了,只要得到 IMAGE_OPTIONAL_HEADER 这个结构,再根据 subsytem这个位再判断类型。呵,这篇文章就到 这结束了,当然,为了证实以上代码结果,我当然会附一上份Demo!

来源:http://www.vckbase.com/document/viewdoc/?id=1893coolker2010-01-26 00:27:09

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值