• 当前位置: 首页 > 等阶教程源码 > 初级教程源码易语言全面解读PE格式PE文件格式一览源码
  • 易语言全面解读PE格式PE文件格式一览源码

    • 软件授权:
      开源软件
    • 软件大小:
      8.65 KB
    • 文件类型:
      .zip
    • 下载次数:
    • 上传用户:
      心脏
    • 发布时间:
      2018-10-04 20:17
    • 软件等阶:
    • 运行环境:
      Winall,Win2003,WinXP,Win7,Win8
    • 软件评级:

    软件介绍             



     

    全面解读PE格式PE文件格式一览


    系统结构:易语言全面解读PE格式PE文件格式一览源码,全面解读PE格式PE文件格式一览


     

    全面解读PE格式PE文件格式一览

     

    PE 的意思就是 Portable Executable(可移植的执行体)。它是 Win32环境自身所带的执行体文件格式。它的一些特性继承自 Unix Coff (common object file format)文件格式。"portable executable"(可移植的执行体)意味着此文件格式是跨win32平台的 : 即使Windows运行在非IntelCPU上,任何win32平台的PE装载器都能识别和使用该文件格式。当然,移植到不同的CPUPE执行体必然得有一些改变。所有 win32执行体 (除了VxD16位的Dll)都使用PE文件格式,包括NT的内核模式驱动程序(kernel mode drivers)。因而研究PE文件格式给了我们洞悉Windows结构的良机。


    本节主要是浏览一下 PE文件格式的概要。

     +-------------------------------+    
         |       DOS MZ header("MZ")     |
         +-------------------------------+    
         |           DOS stub            |
         +-------------------------------+
         |         PE header("PE")       |
         +-------------------------------+  
         |          Section table        |
         +-------------------------------+  
         |           Section 1           |
         +-------------------------------+  
         |           Section 2           |
         +-------------------------------+  
         |           Section ...         |
         +-------------------------------+  
         |           Section n           |
         +-------------------------------+
       

    上图是 PE文件结构的总体层次分布。所有 PE文件(甚至32位的 DLLs) 必须以一个简单的 DOS MZ header 开始。我们通常对此结构没有太大兴趣。有了它,一旦程序在DOS下执行,DOS就能识别出这是有效的执行体,然后运行紧随 MZ header 之后的 DOS stubDOS stub实际上是个有效的 EXE,在不支持 PE文件格式的操作系统中,它将简单显示一个错误提示,类似于字符串 "This program requires Windows" 或者程序员可根据自己的意图实现完整的 DOS代码。通常我们也不对 DOS stub 太感兴趣:

    因为大多数情况下它是由汇编器/编译器自动生成。通常,它简单调用中断21h服务9来显示字符串"This program cannot run in DOS mode"。紧接着 DOS stub 的是 PE header PE header PE相关结构 IMAGE_NT_HEADERS 的简称,其中包含了许多PE装载器用到的重要域。当我们更加深入研究PE文件格式后,将对这些重要域耳目能详。执行体在支持PE文件结构的操作系统中执行时,PE装载器将从 DOS MZ header 中找到 PE header 的起始偏移量。因而跳过了 DOS stub 直接定位到真正的文件头 PE header

    PE文件的真正内容划分成块,称之为sections(节)。每节是一块拥有共同属性的数据,比如代码/数据、读/写等。我们可以把PE文件想象成一逻辑磁盘,PE header 是磁盘的boot扇区,而sections就是各种文件,每种文件自然就有不同属性如只读、系统、隐藏、文档等等。 值得我们注意的是 ---- 节的划分是基于各组数据的共同属性: 而不是逻辑概念。重要的不是数据/代码是如何使用的,如果PE文件中的数据/代码拥有相同属性,它们就能被归入同一节中。不必关心节中类似于"data", "code"或其他的逻辑概念: 如果数据和代码拥有相同属性,它们就可以被归入同一个节中。(译者注:节名称仅仅是个区别不同节的符号而已,类似"data", "code"的命名只为了便于识别,惟有节的属性设置决定了节的特性和功能)如果某块数据想付为只读属性,就可以将该块数据放入置为只读的节中,当PE装载器映射节内容时,它会检查相关节属性并置对应内存块为指定属性。如果我们将PE文件格式视为一逻辑磁盘,PE headerboot扇区而sections是各种文件,但我们仍缺乏足够信息来定位磁盘上的不同文件,譬如,什么是PE文件格式中等价于目录的东东?别急,那就是 PE header 接下来的数组结构 section table(节表)。 每个结构包含对应节的属性、文件偏移量、虚拟偏移量等。如果PE文件里有5个节,那么此结构数组内就有5个成员。因此,我们便可以把节表视为逻辑磁盘中的根目录,每个数组成员等价于根目录中目录项。

    以上就是PE文件格式的物理分布,下面将总结一下装载一PE文件的主要步骤:

    PE文件被执行,PE装载器检查 DOS MZ header 里的 PE header 偏移量。如果找到,则跳转到 PE headerPE装载器检查 PE header 的有效性。如果有效,就跳转到PE header的尾部。紧跟 PE header 的是节表。PE装载器读取其中的节信息,并采用文件映射方法将这些节映射到内存,同时付上节表里指定的节属性。 PE文件映射入内存后,PE装载器将处理PE文件中类似 import table(引入表)逻辑部分。
       
      
    上述步骤是基于本人观察后的简述,显然还有一些不够精确的地方,但基本明晰了执行体被处理的

    过程。你应该下载 LUEVELSMEYER的《PE文件格式》.该文的描述相当详细,可用作案头的参考手册。

     

    <2>检验PE文件的有效性


    本教程中我们将学习如何检测给定文件是一有效PE文件。

    理论:

    如何才能校验指定文件是否为一有效PE文件呢? 这个问题很难回答,完全取决于想要的精准程度。您可以检验PE文件格式里的各个数据结构,或者仅校验一些关键数据结构。大多数情况下,没有必要校验文件里的每一个数据结构,只要一些关键数据结构有效,我们就认为是有效的PE文件了。下面我们就来实现前面的假设。

    我们要验证的重要数据结构就是 PE header。从编程角度看,PE header 实际就是一个 IMAGE_NT_HEADERS 结构。定义如下:

    .数据类型 IMAGE_NT_HEADERS
    .
    成员 Signature, 整数型
    , , , {50h, 45h, 00h, 00h},"PE"
    .
    成员
    FileHeader, IMAGE_FILE_HEADER
    .
    成员 OptionalHeader, IMAGE_OPTIONAL_HEADER32

    <1>Signature 一整数(dword)类型,值为50h, 45h, 00h, 00hPE\0\0)。 本域为PE标记,我们可以
      
       
    此识别给定文件是否为有效PE文件。

    <2>FileHeader 该结构域包含了关于PE文件物理分布的信息,比如节数目、文件执行机器等。

    <3>OptionalHeader 该结构域包含了关于PE文件逻辑分布的信息,虽然域名有"可选"字样,但实际上本
        
    结构总是存在的。我们目的很明确。如果IMAGE_NT_HEADERSsignature域值等于"PE",那么就是有效的PE文件。实际上,为了比较方便,Microsoft已定义了常量IMAGE_NT_SIGNATURE供我们使用。

    IMAGE_DOS_SIGNATURE  5A4Dh
    IMAGE_OS2_SIGNATURE  454Eh
    IMAGE_OS2_SIGNATURE_LE  454Ch
    IMAGE_VXD_SIGNATURE  454Ch
    IMAGE_NT_SIGNATURE  4550h

    接下来的问题是: 如何定位 PE header? 答案很简单: DOS MZ header 已经包含了指向 PE header 的文件偏移量。DOS MZ header 又定义成结构 IMAGE_DOS_HEADER 。查询windows.inc,我们得知IMAGE_DOS_HEADER结构的最后一个整数型成员e_lfanew就是指向 PE header 的文件偏移量。通过计算得知IMAGE_DOS_HEADER结构的大小是40h(十进制是64),那么e_lfanew的地址就是DOS MZ header+60,现在将所有步骤总结如下:

    <1>首先检验文件头部第一个字的值是否等于"MZ" (IMAGE_DOS_SIGNATURE),是则 DOS MZ header 有效。
        <2>
    一旦证明文件的 DOS header 有效后,就可用e_lfanew来定位 PE header 了。

    <3>比较 PE header 的第一个字的值是否等于 "PE"(IMAGE_NT_HEADER)。如果前后两个值都匹配,那我们就认为该文件是一个有效的PE文件。
    ,我们开始用代码来说明:

    先定义几个常量
    ===============================================================
     
    名称                                16进制        10进制

    GENERIC_READ                         80000000h       2147483648 
    FILE_SHARE_READ                      1h              1
    OPEN_EXISTING                        3               3 
    FILE_ATTRIBUTE_NORMAL                80h             128
    SECTION_MAP_READ                     4h              4
    PAGE_READONLY                        2h              2
    FILE_MAP_READ                        4h              4

    ===============================================================


    用到的API:

    ===============================================================

    *CreateFile             打开或创建文件_

    *CreateFileMapping      创建文件映射

    *MapViewOfFile          映射到本进程空间

    *UnmapViewOfFile        解除本进程映射

    *CloseHandle            关闭内核对象

    ==============================================================
     
    接着就是代码:

    ===============================================================================
    .
    程序集窗口程序集1
    .
    程序集变量 文件号, 整数型
    , , "2"
    .
    程序集变量 映射句柄, 整数型
    , , "2"
    .
    程序集变量 空间地址, 整数型, , "2"

    =============================

    .子程序 映射文件到本空间, 逻辑型
    .
    参数 文件名, 文本型
    .
    局部变量 PeRav, 整数型

    '先通过CreateFile打开指定的文件,得到一个文件号


    文件号 [1] = 打开或创建文件_ (文件名, #GENERIC_READ, #FILE_SHARE_READ, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, 0)
    输出调试文本 (“文件号:” + 到文本 (文件号
    [1]))
    .
    如果真 (文件号 [1]
    0)
       
    信息框 (“打开文件失败!”, #错误图标, “错误
    ”)
       
    返回 (
    )
    .
    如果真结束


    '
    然后用得到的文件号创建文件映射,得到一个文件映射句柄


    映射句柄 [1] = 创建文件映射 (文件号 [1], 0, #PAGE_READONLY, 0, 0, 字符 (0))
    输出调试文本 (“映射句柄:” + 到文本 (映射句柄
    [1]))
    .
    如果真 (映射句柄 [1]
    0)
       
    信息框 (“打开文件失败!”, #错误图标, “错误
    ”)
       
    返回 (
    )
    .
    如果真结束

    '根据文件映射句柄用MapViewOfFile把文件映射到本进程空间

    空间地址 [1] = 映射到本进程空间 (映射句柄 [1], #FILE_MAP_READ, 0, 0, 0)
    输出调试文本 (“空间地址:” + 到文本 (空间地址
    [1]))
    .
    如果真 (空间地址 [1]
    0)
       
    信息框 (“打开文件失败!”, #错误图标, “错误
    ”)
       
    返回 (
    )
    .
    如果真结束


    '
    检查文件头部第一个字的值是否等于"MZ"

    .如果 (文本比较 (指针到文本 (空间地址 [1]), “MZ”, ) 0)
        PeRav
    = 取字节集数据 (指针到字节集 (空间地址 [1]
    60, 4), 3, )
     
    '
    比较 PE header 的第一个字的值是否等于
    "PE"
     
      .
    如果真 (指针到文本 (空间地址 [1] PeRav)
    “PE”)
           
    文件号 [2] =文件号
    [1]
           
    映射句柄 [2] =映射句柄
    [1]
           
    空间地址 [2] =空间地址
    [1]
    '
    如果是就认为是有效的PE文件

     
         
    返回 ()
        .
    如果真结束

    .否则

    .如果结束
    信息框 (“不是有效的PE格式文件!”, #错误图标, “错误”)
    关闭对象
    (1)
    返回 ()


     

     

    全面解读PE格式PE文件格式一览

    相关软件

    下载说明

    本站目前主要提供易语言源码、模块、支持库等下载大部分源码均为ZIP打包,
    注:本站源码主要来源于网络收集。如有侵犯您的利益,请联系我们,我们将及时删除!
    部分源码可能含有危险代码,(如关机、格式化磁盘等),请看清代码在运行。
    由此产生的一切后果本站均不负责。源码仅用于学习使用,如需运用到商业场景请咨询原作者。

    使用本站源码开发的产品均与本站无任何关系,请大家遵守国家相关法律。

     

    推荐排行

    • 易语言系统盘符修改器源

      易语言系统盘符修改器源码,遍历卷,DeleteVolumeMountPoint,GetVolumePathNamesForVolumeName,SetVolumeMountPoint,FindFirstVolume,FindNextVolume,FindVolumeClose,MessageBox...

    • 易语言类的使用将多线程

      易语言类的使用将多线程操作封装到类源码,取数子程序100,取数子程序10,取数子程序_10,取数子程序_100,初始组件,创建许可证,删除许可证...

    • 易语言用空格分割文本源

      易语言用空格分割文本源码,子程序_启动线程,子程序_创建进入许可证,子程序_删除进入许可证,子程序_进入许可区,子程序_退出许可区,子程序_等待线程,子程序_挂起线程,子程序_继续执行...

    • 易语言编写QQ邮件发送器

      易语言编写QQ邮件发送器V10e源码,易语言编写QQ邮件发送器V10e...

    • 易语言系统盘符修改器源

      易语言系统盘符修改器源码,遍历卷,DeleteVolumeMountPoint,GetVolumePathNamesForVolumeName,SetVolumeMountPoint,FindFirstVolume,FindNextVolume,FindVolumeClose,MessageBox...

    • 超级列表框排序凌晨孤星

      取随机文本,取随机时间,排序列表,CompareFunc,比较时间,取文本地址,取日期时间地址,lstrcmpA...

    • 易语言叮咚茶文字特效源

      TextEffect,timeGetTime,SetTextCharacterExtra,OffsetRect,SetTextColor,FillRect,CreateSolidBrush,DeleteObject,GetSysColor,TextOut,DrawText,OleTranslateColor,GetDC,lstrlen,ReleaseDC,CreateFont,MulDiv,GetDeviceCaps,SelectObject...

    • 易语言屏幕笼罩源码

      易语言屏幕笼罩源码,屏幕笼罩...

    • 易语言透明桌面软件研究

      易语言透明桌面软件研究源码,透明桌面软件研究,MakeTrans,设主窗透明度,Ansi转Unicode,BitBlt,DeleteObject,SetWindowLong,AlphaBlend,UpdateLayeredWindow,CreateDIBSection,GetDIBits,SetDIBits,CreateCompatibleDC,SelectObject,DeleteDC,CopyMemory,SetWi...