zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    jQuery
    jQuery
    jQuery Callback 函数
    怎样提高团队管理能力4
    poj 3461 Oulipo(KMP模板题)
    每日一小练——按字典顺序列出全部排列
    Java数据结构与算法之排序
    China Vis 2015 会议小结
    网络基础知识小小说
    NS3网络仿真(7): Wifi节点
  • 原文地址:https://www.cnblogs.com/duxie/p/10847832.html
Copyright © 2011-2022 走看看