zoukankan      html  css  js  c++  java
  • 第13章:PE文件格式(1)

    一年前看过一次,但没有实实在在的理解,这次争取结合实际的PE文件再看看.

     

    一般来说,很多文件为了提高使用率,都会使用一个"最小基本单位"的概念.PE文件中各节区的起始位置在某个最小单位的倍数上.

    若不够,则空白区域用NULL填充.

    相对虚拟地址(RVA):从某个基准地址开始的相对地址.

    虚拟地址(VA):进程虚拟内存的绝对地址.

    两个都指的是在装载入内存之后的地址.

    随着所处位置的不同,其最小基本单位也会发生变化,导致NULL填充区变大.

    PE 头

    DOS头

    首先前40H是一个IMAGE_DOS_HEADER的结构体--DOS头:

     结构体包含如下几个字段:

     注意:WORD占两字节,DWORD占四字节

     e_magic是DOS签名,该结构体的最后一个字段e_lfanew是NT头的偏移,此处偏移值是e0.

    紧跟着的是DOS存根(stub),是一个可选项.由代码和数据混合而成,大小不确定.此处40-4D处是代码,int 21执行时由

    eax寄存器中的值来决定执行哪个中断.此处debug模式下,将数据(This ...)识别为了代码.故40-7F为DOS存根段.

     

     若使用得当,可以在DOS存根处写入代码,使得在DOS模式下运行16位程序,在Windows下运行32/64位程序.

    对DOS头,DOS存根做一个总结:

    1.DOS存根是可选的,大小变化的,可以在里面写入汇编程序以运行在16位DOS模式下.

    2.DOS头是固定的40H字节.

    3.DOS头第一个是DOS签名--MZ,最后一个是e_lfanew,是NT头的偏移(从地址0开始),因为DOS存根大小不确定.

    NT头

    即IMAGE_NT_HEADERS.有三个成员:PE,文件头(File Header)可选头(Optional Header).总大小为F8字节.

     识别出来并不困难,找到PE即可.

    接下来是文件头结构体(黑色划线部分),重要的有如下几个

    首先是机器码(Machine),此处位014C,表明是intel 386的CPU

    第二个是节区数(NumberOfSections),此处为3.

    第三个是可选头大小(SizeOfOptionalHeader),用来指出IMAGE_OPTIONAL_HEADER32/64的长度,此处是e0

    第四个是Characteristics,用来标识文件属性此处是10f,即包含了重定向信息删除,可执行文件,行数移除,本地符号表移除以及系统文件等属性

     可选头(Image_Optional_Header)PE结构体最大的.

     

    1#.Magic 

    可选头是32结构体时位,该值为10B;可选头是64位结构体时,该值为20B.

    2#.AddressOfEntryPoint

    标识处EP的RVA值,指出程序最先执行的代码起始地址.动态反汇编软件会从其中读取出值.

    3#.ImageBase

    指出PE文件优先装入的地址.EXE,DLL被装载到0~FFFFFFFF(32位系统),SYS文件被装载到80000000~FFFFFFFF.一般来说,EXE的基址是00400000,DLL的基址位10000000.执行PE文件时,PE转载器先创建进程,再将文件载入内存,最后EIP=ImageBase+AddressOfEntryPoint.

    4#.SectionAlignment,FileAlignment

    SectionAlignment指定了节区在磁盘文件中的最小单位,FileAlignment指定了节区在内存中的最小单位.

    5#.SizeOfImage

    PE文件在虚拟内存中所占空间的大小.

    6#.SizeOfHeaders

    指出PE头的大小.

    7#.Subsystem

    区分系统文件与普通的可执行文件.

    8#.NumberOfRvaAndSizes

    指定最后一个成员DataDirectory数组的个数,以这个为准,而不是IMAGE_NUMBEROF_Directory_Entries(16)

    9#.DataDirectory

     非常重要的是Export / Import  / Resource Directory,TLS Direction.

    对NT头做一个总结:

    1.NT头包含三个元素:PE,File Header,Optional Header.

    2.文件头中的第一个元素是机器码,I386的CPU是0x014C,倒数第二个是可选头大小,32/64位系统的可选头大小不同,最后一个是文件属性,0x2是exe,0x20000是DLL

    3.从PE开始,数18H字节就到了可选头的第一个元素.

    4.DataDirectory[n]结构体中的每一个都有两个属性:一个是相对虚拟地址,一个是大小.其中每个结构体的大小为8字节

    5.从Magic(10B/20B)开始,加60H即到DataDirectory的第一个结构体,每个结构有两个占4字节的元素--VirtualAddress,Size.

    6.从Magic开始,加20H即到SectionAlignment和FileAlignment,每个占4字节

    节区头

     即IMAGE_SECTION_HEADER结构体.它定义了每个节区的相关信息.每个节区头的大小固定为40字节.

    重要的元素有下面几个:

    1#.VirtualSize

    指示内存中节区所占的实际大小,通常这个值会被对齐到某个整数.

    2#.VirtualAddress

    内存中节区的起始地址.其实是相对虚拟地址,程序运行时会加上一个ImageBase值.通常第一个节区的值会被置为1000H.会按照SectionAlignmnet的值对齐.

    3#SizeOfRawData

    磁盘文件中节区所占的大小.这个值通常是对VirtualSize依照FileAlignment的值进行对齐后所得到的.

    4#.PointerToRawData

    指示该节区在文件中的起始位置.已按照FileAlignment对齐.

    5#.Characteristics

    文件属性.由bits组合而成.

    节区头name字段8个字节.

  • 相关阅读:
    [tip]build x86+x64 parrelly for your VS solution
    float double的内存表示及比较大小的方法
    [Problem 13]欧拉
    Interface Project
    [复习]内存对齐
    [tip]VS online Gallery in Extention Manager
    [Problem 14]欧拉
    “火柴棍式”程序员面试题打破惯性思维
    [复习]时间复杂度及计算
    ModuleCatalog配置文件
  • 原文地址:https://www.cnblogs.com/Rev-omi/p/13170124.html
Copyright © 2011-2022 走看看