zoukankan      html  css  js  c++  java
  • PE文件格式

      以下内容摘录自《加密与解密》:

      为了在PE文件中避免有确定的内存地址,出现了相对虚拟地址(RVA)的概念。RVA只是内存中的一个简单的相对于PE文件装入地址的偏移位置。它是一个“相对”地址,或称为“偏移量”。

      例如,假设一个EXE文件从地址400000h处装入,并且它的代码区块开始于401000h,代码区块的RVA将是401000h-400000h=RVA1000h。

      PE装载器将从IMAGE_DOS_HEADER结构中的e_lfanew字段里找到PE Header的起始偏移量,加上基址得到PE头的指针。

      PE相关结构NT映像头(IMAGE_NT_HEADER)由三个字段字组成:

    typedef struct _IMAGE_NT_HEADERS {
      DWORD                 Signature;
      IMAGE_FILE_HEADER     FileHeader;
      IMAGE_OPTIONAL_HEADER OptionalHeader;
    } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;

    其中,IMAGE_OPTIONAL_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;

    最后的数据目录表的结构有很多,比较重要的有输入表、输出表、资源等。

    区块映射到内存后,其偏移位置就发生变化了。文件偏移地址与虚拟地址关系如下:

    File Offset = RVA - △k

    在同一区块中,各地址的偏移量是相等的,但不同区块在磁盘和内存中的差值不一样。

    我们一路奋战,不是为了改变世界,而是不让世界改变我们 ——《熔炉》
  • 相关阅读:
    Android开发系列之ListView用法
    自省
    fake feeling ?
    我心中的天使
    2020.6.16
    python面试题
    tcp
    Short + skip + limit
    01_pyttsx3_将文本文字转为语音播放
    mongo_Linux下不进入数据库查数据
  • 原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5089988.html
Copyright © 2011-2022 走看看