新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → 判断你的文件是否为合法的PE文件和应用类型 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 4839 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 判断你的文件是否为合法的PE文件和应用类型 举报  打印  推荐  IE收藏夹 
       本主题类别: Description Logics    
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/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!

    [URL=http://www.vckbase.com/code/downcode.asp?id=3220]源代码下载[/URL]


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2010/7/27 14:16:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/22 15:19:19

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    46.875ms