• PE解析篇2


    基本结构图:

    ms-dos头

    (注:最左边是文件头的偏移量。) 
    IMAGE_DOS_HEADER STRUCT 
    { 
    +0h    WORD    e_magic        //    Magic DOS signature MZ(4Dh 5Ah)     DOS可执行文件标记 
    +2h      WORD     e_cblp       //    Bytes on last page of file               
    +4h    WORD     e_cp        //    Pages in file                     
    +6h    WORD     e_crlc        //    Relocations                     
    +8h    WORD     e_cparhdr   //    Size of header in paragraphs         
    +0ah    WORD     e_minalloc   //    Minimun extra paragraphs needs         
    +0ch    WORD     e_maxalloc  //    Maximun extra paragraphs needs     
    +0eh    WORD     e_ss            //    intial(relative)SS value        DOS代码的初始化堆栈SS 
    +10h    WORD     e_sp         //    intial SP value                       DOS代码的初始化堆栈指针SP 
    +12h    WORD     e_csum         //    Checksum 
    +14h    WORD     e_ip         // intial IP value                       DOS代码的初始化指令入口[指针IP] 
    +16h    WORD     e_cs         //    intial(relative)CS value         DOS代码的初始堆栈入口 
    +18h    WORD     e_lfarlc         //    File Address of relocation table 
    +1ah    WORD     e_ovno         // Overlay number 
    +1ch    WORD     e_res[4]          // Reserved words 
    +24h    WORD     e_oemid          // OEM identifier(for e_oeminfo) 
    +26h    WORD    e_oeminfo   // OEM information;e_oemid specific  
    +29h    WORD     e_res2[10]   // Reserved words 
    +3ch    DWORD   e_lfanew     //  Offset to start of PE header      指向PE文件头 
    } IMAGE_DOS_HEADER ENDS

    NT头

    IMAGE_NT_HEADERS STRUCT 
    {
    +0h       DWORDSignature  
    +4h       IMAGE_FILE_HEADER FileHeader 
    +18h      IMAGE_OPTIONAL_HEADER32OptionalHeader   
    } IMAGE_NT_HEADERS ENDS

    标准头

    IMAGE_FILE_HEADER 结构
    typedef     struct _IMAGE_FILE_HEADER 
    {
    +04h    WORD          Machine;              // 运行平台
    +06h      WORD          NumberOfSections;     // 文件的区块数目
    +08h    DWORD         TimeDateStamp;        // 文件创建日期和时间
    +0Ch      DWORD         PointerToSymbolTable; // 指向符号表(主要用于调试)
    +10h     DWORD         NumberOfSymbols;      // 符号表中符号个数(同上)
    +14h      WORD          SizeOfOptionalHeader; // IMAGE_OPTIONAL_HEADER32 结构大小
    +16h      WORD          Characteristics;      // 文件属性
    } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

    可选NT头

    typedef struct _IMAGE_OPTIONAL_HEADER 
    {
        //
        // Standard fields.  
        //
    +18h    WORD    Magic;                   // 标志字, ROM 映像(0107h),普通可执行文件(010Bh)
    +1Ah    BYTE    MajorLinkerVersion;      // 链接程序的主版本号
    +1Bh    BYTE    MinorLinkerVersion;      // 链接程序的次版本号
    +1Ch    DWORD   SizeOfCode;              // 所有含代码的节的总大小
    +20h    DWORD   SizeOfInitializedData;   // 所有含已初始化数据的节的总大小
    +24h    DWORD   SizeOfUninitializedData; // 所有含未初始化数据的节的大小
    +28h    DWORD   AddressOfEntryPoint;     // 程序执行入口RVA
    +2Ch    DWORD   BaseOfCode;              // 代码的区块的起始RVA
    +30h    DWORD   BaseOfData;              // 数据的区块的起始RVA
        //
        // NT additional fields.    以下是属于NT结构增加的领域。
        //
    +34h    DWORD   ImageBase;               // 程序的首选装载地址
    +38h    DWORD   SectionAlignment;        // 内存中的区块的对齐大小
    +3Ch    DWORD   FileAlignment;           // 文件中的区块的对齐大小
    +40h    WORD    MajorOperatingSystemVersion;  // 要求操作系统最低版本号的主版本号
    +42h    WORD    MinorOperatingSystemVersion;  // 要求操作系统最低版本号的副版本号
    +44h    WORD    MajorImageVersion;       // 可运行于操作系统的主版本号
    +46h    WORD    MinorImageVersion;       // 可运行于操作系统的次版本号
    +48h    WORD    MajorSubsystemVersion;   // 要求最低子系统版本的主版本号
    +4Ah    WORD    MinorSubsystemVersion;   // 要求最低子系统版本的次版本号
    +4Ch    DWORD   Win32VersionValue;       // 莫须有字段,不被病毒利用的话一般为0
    +50h    DWORD   SizeOfImage;             // 映像装入内存后的总尺寸
    +54h    DWORD   SizeOfHeaders;           // 所有头 + 区块表的尺寸大小
    +58h    DWORD   CheckSum;                // 映像的校检和
    +5Ch    WORD    Subsystem;               // 可执行文件期望的子系统
    +5Eh    WORD    DllCharacteristics;      // DllMain()函数何时被调用,默认为 0
    +60h    DWORD   SizeOfStackReserve;      // 初始化时的栈大小
    +64h    DWORD   SizeOfStackCommit;       // 初始化时实际提交的栈大小
    +68h    DWORD   SizeOfHeapReserve;       // 初始化时保留的堆大小
    +6Ch    DWORD   SizeOfHeapCommit;        // 初始化时实际提交的堆大小
    +70h    DWORD   LoaderFlags;             // 与调试有关,默认为 0 
    +74h    DWORD   NumberOfRvaAndSizes;     // 下边数据目录的项数,这个字段自Windows NT 发布以来一直是16
    +78h    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];   
    // 数据目录表
    } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

    16个directory结构表

    IMAGE_DATA_DIRECTORY STRUCT
          VirtualAddress    DWORD       ?   ; 数据的起始RVA
          isize             DWORD       ?   ; 数据块的长度
    IMAGE_DATA_DIRECTORY ENDS

    表头

    typedef struct _IMAGE_SECTION_HEADER 
    {
            BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // 节表名称,如“.text” 
            //IMAGE_SIZEOF_SHORT_NAME=8
            union
             {
                    DWORD PhysicalAddress;      // 物理地址
                    DWORD VirtualSize;          // 真实长度,这两个值是一个联合结构,可以使用其中的任何一个,一般是取后一个
            } Misc;
            DWORD VirtualAddress;               // 节区的 RVA 地址
            DWORD SizeOfRawData;                // 在文件中对齐后的尺寸
            DWORD PointerToRawData;             // 在文件中的偏移量
            DWORD PointerToRelocations;         // 在OBJ文件中使用,重定位的偏移
            DWORD PointerToLinenumbers;         // 行号表的偏移(供调试使用地)
            WORD NumberOfRelocations;           // 在OBJ文件中使用,重定位项数目
            WORD NumberOfLinenumbers;           // 行号表中行号的数目
            DWORD Characteristics;              // 节属性如可读,可写,可执行等
    } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

    导入表

    IMAGE_IMPORT_DESCRIPTOR STRUCT 
        union 
            Characteristics           DWORD   ? 
            OriginalFirstThunk        DWORD   ? 
        ends 
        TimeDateStamp                 DWORD   ? 
        ForwarderChain                DWORD   ? 
        Name                          DWORD   ? 
        FirstThunk                    DWORD   ?
    IMAGE_IMPORT_DESCRIPTOR ENDS

    IMAGE_THUNK_DATA STRUC
        union u1
        ForwarderString      DWORD  ?        ; 指向一个转向者字符串的RVA
        Function             DWORD  ?        ; 被输入的函数的内存地址
        Ordinal              DWORD  ?        ; 被输入的API 的序数值
        AddressOfData        DWORD  ?        ; 指向 IMAGE_IMPORT_BY_NAME
        ends
    IMAGE_THUNK_DATA ENDS
    
    IMAGE_IMPORT_BY_NAME STRUCT
        Hint      WORD      ? 
        Name      BYTE      ?
    IMAGE_IMPORT_BY_NAME ENDS

    导出表
    IMAGE_EXPORT_DIRECTORY STRUCT
        Characteristics        DWORD    ?    ; 未使用,总是定义为0
        TimeDateStamp        DWORD    ?       ; 文件生成时间
        MajorVersion        WORD    ?    ; 未使用,总是定义为0
        MinorVersion        WORD    ?    ; 未使用,总是定义为0
        Name            DWORD    ?    ; 模块的真实名称
        Base                DWORD    ?    ; 基数,加上序数就是函数地址数组的索引值
        NumberOfFunctions    DWORD    ?    ; 导出函数的总数
        NumberOfNames        DWORD    ?    ; 以名称方式导出的函数的总数
        AddressOfFunctions    DWORD    ?    ; 指向输出函数地址的RVA
        AddressOfNames        DWORD    ?    ; 指向输出函数名字的RVA
        AddressOfNameOrdinals    DWORD    ?    ; 指向输出函数序号的RVA
    IMAGE_EXPORT_DIRECTORY ENDS

    重定位表

    IMAGE_BASE_RELOCATION STRUC
     
        VirtualAddress      DWORD        ?  ; 重定位数据开始的RVA 地址
        SizeOfBlock         DWORD        ?  ; 重定位块得长度
        TypeOffset          WORD         ?  ; 重定项位数组
     
    IMAGE_BASE_RELOCATION  ENDS
  • 相关阅读:
    VM启用ISO共享
    部署服务--NLB
    SCVMM问题汇总
    判断文件是否存在(exist)
    函数(Function)作用域 / 远程函数执行
    基于433MHz无线串口,多发一收解决方案
    ZigBee自组网地址分配与路由协议概述
    Zigbee协议栈--Z-Stack的使用
    RT-Thread RTOS
    信息量、互斥信息量和事件标志
  • 原文地址:https://www.cnblogs.com/trevain/p/14616079.html
Copyright © 2020-2023  润新知