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

 

posted @ 2021-04-04 13:48  包子TT  阅读(60)  评论(0编辑  收藏  举报