• WinPE基础知识之头部


    1、DOS头

    // DOS MZ头,大小为64个字节
    typedef struct _IMAGE_DOS_HEADER {     
        WORD   e_magic;                     // EXE标志,“MZ”(有用,解析时作为是否是PE文件的第一个标志)
        WORD   e_cblp;                      // Bytes on last page of file
        WORD   e_cp;                        // Pages in file
        WORD   e_crlc;                      // Relocations
        WORD   e_cparhdr;                   // Size of header in paragraphs
        WORD   e_minalloc;                  // Minimum extra paragraphs needed
        WORD   e_maxalloc;                  // Maximum extra paragraphs needed
        WORD   e_ss;                        // Initial (relative) SS value
        WORD   e_sp;                        // Initial SP value
        WORD   e_csum;                      // Checksum
        WORD   e_ip;                        // Initial IP value
        WORD   e_cs;                        // Initial (relative) CS value
        WORD   e_lfarlc;                    // File address of relocation table
        WORD   e_ovno;                      // Overlay number
        WORD   e_res[4];                    // Reserved words
        WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
        WORD   e_oeminfo;                   // OEM information; e_oemid specific
        WORD   e_res2[10];                  // Reserved words
        LONG   e_lfanew;                    // 非常重要,操作系统通过它找到NT头,NT头相对于文件的偏移地址
      } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

    DOS MZ头下面是DOS Stub,整个Dos Stub是一个字节快,其内容随着链接时使用的链接器不同而不同,而且长度不固定

    2、NT头

    // NT 头
    typedef struct _IMAGE_NT_HEADERS {
        DWORD Signature;
        IMAGE_FILE_HEADER FileHeader;
        IMAGE_OPTIONAL_HEADER32 OptionalHeader;
    } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
    (1)紧跟在DOS Stub后面的是PE头标识(DWORD) Signature, 占四个字节,内容固定为“PE“。
    (2)标准PE头、文件头、COFF头,占20个字节
    3、文件头
    typedef struct _IMAGE_FILE_HEADER {
        WORD    Machine;            // 运行平台
        WORD    NumberOfSections;   // PE中节的数量
        DWORD   TimeDateStamp;      // 文件创建日期和时间
        DWORD   PointerToSymbolTable;    // 指向符号表(用于调试)
        DWORD   NumberOfSymbols;         // 符号表中的符号数量(用于调试)
        WORD    SizeOfOptionalHeader;    // 扩展头结构的长度
        WORD    Characteristics;         // PE文件属性
    } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

    4、扩展PE头

    // 32位程序当中扩展头的大小为224个字节
    typedef struct _IMAGE_OPTIONAL_HEADER {
        WORD    Magic;                  // (有用)魔术字 107h = ROM Image, 10Bh = exe Image
        BYTE    MajorLinkerVersion;     // 链接器版本号
        BYTE    MinorLinkerVersion;
        DWORD   SizeOfCode;             // (有用)所有含代码的节的总大小
        DWORD   SizeOfInitializedData;  // (有用)所有含已初始化数据的节的总大小
        DWORD   SizeOfUninitializedData;// (有用)所有含未初始化数据的节的大小
        DWORD   AddressOfEntryPoint;    // (重要)程序执行入口RVA
        DWORD   BaseOfCode;             // (有用)代码的节的起始RVA
        DWORD   BaseOfData;             // (有用)数据的节的起始RVA
        DWORD   ImageBase;              // (重要)程序的建议装载基址(如果没有加载到这个地址,会发生重定位)
        DWORD   SectionAlignment;       // (重要)内存中的节的对齐粒度,一般是0x1000
        DWORD   FileAlignment;          // (重要)文件中的节的对齐粒度,一般是0x200
        WORD    MajorOperatingSystemVersion;  // 操作系统版本号
        WORD    MinorOperatingSystemVersion;
        WORD    MajorImageVersion;            // 该PE的版本号
        WORD    MinorImageVersion;
        WORD    MajorSubsystemVersion;        // 所需子系统版本号
        WORD    MinorSubsystemVersion;
        DWORD   Win32VersionValue;            // 未用
        DWORD   SizeOfImage;                  // (重要)把文件加载进内存,所需要的内存大小,注意是进行了块对齐之后
        DWORD   SizeOfHeaders;                // (重要)所有头 + 节表的大小
        DWORD   CheckSum;                     // 校验和
        WORD    Subsystem;                    // (有用)文件的子系统
        WORD    DllCharacteristics;           // (有用)指示DLL特征的标志
        DWORD   SizeOfStackReserve;           // (有用)初始化时的栈大小
        DWORD   SizeOfStackCommit;            // (有用)初始化时实际提交的栈大小
        DWORD   SizeOfHeapReserve             // (有用)初始化时保留的堆大小
        DWORD   SizeOfHeapCommit;             // (有用)初始化时实际提交的堆大小
        DWORD   LoaderFlags;                  // 与调试有关
        DWORD   NumberOfRvaAndSizes;          // (有用)下面的数据目录结构的项目数量
        IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];   // (非常重要)数据目录表
    } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

    5、数据目录表

    // 数据目录项
    typedef struct _IMAGE_DATA_DIRECTORY {
        DWORD   VirtualAddress;   // 数据的起始RVA
        DWORD   Size;             // 数据块的长度
    } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
    struct IMAGE_DATA_DIRECTORY_ARRAY DataDirArray            
    [0]struct IMAGE_DATA_DIRECTORY Export        // 导出表
    [1]struct IMAGE_DATA_DIRECTORY Import        // 导入表
    [2]struct IMAGE_DATA_DIRECTORY Resource        // 资源表
    [3]struct IMAGE_DATA_DIRECTORY Exception    // 异常表
    [4]struct IMAGE_DATA_DIRECTORY Security        // 安全表
    [5]struct IMAGE_DATA_DIRECTORY BaseRelocationTable    // 重定位表    
    [6]struct IMAGE_DATA_DIRECTORY DebugDirectory        // 调试信息
    [7]struct IMAGE_DATA_DIRECTORY CopyrightOrArchitectureSpecificData  // 版权信息        
    [8]struct IMAGE_DATA_DIRECTORY GlobalPtr    // 全局PTR
    [9]struct IMAGE_DATA_DIRECTORY TLSDirectory // 线程本地存储
    [10]struct IMAGE_DATA_DIRECTORY LoadConfigurationDirectory  // 配置加载表        
    [11]struct IMAGE_DATA_DIRECTORY BoundImportDirectory        // 绑定导入表
    [12]struct IMAGE_DATA_DIRECTORY ImportAddressTable            // 导入函数地址表
    [13]struct IMAGE_DATA_DIRECTORY DelayLoadImportDescriptors  // 延迟加载表
    [14]struct IMAGE_DATA_DIRECTORY COMRuntimedescriptor        // CLR头
    [15]struct IMAGE_DATA_DIRECTORY Reserved     // 预留

    6、区段头表

    // 节表项
    typedef struct _IMAGE_SECTION_HEADER {
        BYTE    Name[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;

    7、RVA 转 FOA

     1 // RVA 转 FOA
     2 DWORD rva2foa(IMAGE_NT_HEADERS* pNt, DWORD dwRva)
     3 {
     4     IMAGE_SECTION_HEADER* pScnHdr = (IMAGE_SECTION_HEADER*)
     5         IMAGE_FIRST_SECTION(pNt);
     6     for (DWORD i = 0; i < pNt->FileHeader.NumberOfSections; i++)
     7     {
     8         if (dwRva >= pScnHdr[i].VirtualAddress &&
     9             dwRva <= pScnHdr[i].VirtualAddress + pScnHdr[i].SizeOfRawData)
    10         {
    11             return dwRva - pScnHdr[i].VirtualAddress + pScnHdr[i].PointerToRawData;
    12         }
    13     }
    14     return -1;
    15 }
  • 相关阅读:
    Begin Example with Override Encoded SOAP XML Serialization
    State Machine Terminology
    How to: Specify an Alternate Element Name for an XML Stream
    How to: Publish Metadata for a WCF Service.(What is the Metadata Exchange Endpoint purpose.)
    Beginning Guide With Controlling XML Serialization Using Attributes(XmlSerializaiton of Array)
    Workflow 4.0 Hosting Extensions
    What can we do in the CacheMetaData Method of Activity
    How and Why to use the System.servicemodel.MessageParameterAttribute in WCF
    How to: Begin Sample with Serialization and Deserialization an Object
    A Test WCF Service without anything of config.
  • 原文地址:https://www.cnblogs.com/duxie/p/10847832.html
Copyright © 2020-2023  润新知