• PE文件结构详解


    (注:最左边是文件头的偏移量。) 
    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

    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;

    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;

    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






















     
     
     
     
     
  • 相关阅读:
    长篇专访科比:成功没秘诀 只有不断努力
    生活哲理
    8个让程序员追悔莫及的职业建议
    优秀程序员必备十大习惯
    回顾马云屌丝岁月的惨状:多次被拒失声痛哭
    程序员,究竟该怎么赚钱?
    洛杉矶凌晨4点-------启航
    iOS越狱开发
    iOS越狱开发中遇到的坑
    macOS上搭建RabbitMQ+MQTT服务器
  • 原文地址:https://www.cnblogs.com/milantgh/p/3949866.html
Copyright © 2020-2023  润新知