zoukankan      html  css  js  c++  java
  • PE 学习之路 —— 区块表

    1. 前述

    在 NT 头结束后,紧接着就是区块表,区块表包含每个块在映象中的信息,分别指向不同的区块实体。

    2. 区块表

    区块表是一个 IMAGE_SECTION_HEADER 结构数组,这个结构包含区块的信息,比如位置、长度、属性等,区块的数目是由 NT 头中的文件头里的 NumberOfSections 给出。以下为 `IMAGE_SECTION_HEADER` 结构:

    在上述图中,有两个字段比较重要,分别为 `VirtualAddress`、`PointerToRawData`,这两个字段用于将相对虚拟地址或虚拟地址转换为文件偏移地址,以下为 RVA 转 FOA 函数:

    DWORD RVAtoFOA(DWORD dwRva)
    {
        // 获取区段表的数量
        DWORD dwCounts = g_NtHeader->FileHeader.NumberOfSections;
    
        // 获取区段表数组的首元素
        auto Sections = IMAGE_FIRST_SECTION(g_NtHeader);
    
        // 遍历所有的区段表找到符合要求的区段
        for (DWORD i = 0; i < dwCounts; ++i)
        {
            // 要求:RVA >= 区段的首地址 并且 RVA < 区段的结尾的地址
            if (dwRva >= Sections[i].VirtualAddress &&
                (Sections[i].VirtualAddress + Sections[i].SizeOfRawData))
            {
                // FOA = VA - ImageBase - (所在区段的 RVA - 所在区段的 FOA)
                // FOA = RVA - 所在区段的 RVA + 所在区段的 FOA
                return dwRva - Sections[i].VirtualAddress + Sections[i].PointerToRawData;
            }
        }
    
        // 如果找不到就返回 -1
        return -1;
    }

    计算公式为:`FOA = VA - ImageBase - (所在区段的 RVA - 所在区段的 FOA)` 或 `FOA = RVA - 所在区段的 RVA + 所在区段的 FOA`。在上述代码中,有一个为 `IMAGE_FIRST_SECTION`,我们来看下它的定义,如下:

    其实 `IMAGE_FIRST_SECTION` 为一个宏,它主要由三部分相加组成,作用是获取到第一个区段的首地址,参数为 NT 头。你可以把这个首地址理解成数组名,数组的首地址。在获取到了地址后,下面的 for 循环遍历所有的区段表找到符合要求的区段。这三部分内容具体如下:

    • IMAGE_NT_HEADERS 的起始地址
    • IMAGE_OPTIONAL_HEADER32 (PE 扩展头)在 IMAGE_NT_HEADERS 中的偏移
    • IMAGE_OPTIONAL_HEADER32 的大小

     其中后两个加起来的大小恰好就是 IMAGE_NT_HEADERS 的大小,再跟第一个相加就得到区段表的地址了。看到这你可以会问,为什么不直接加上 `IMAGE_NT_HEADERS` 的大小呢?因为 `IMAGE_OPTIONAL_HEADER32` 大小不固定,32 位下该值为 0x00E0H,64 位下该值为 0x00F0H,并且用户还可以自定义其大小。

     3. 额外说明

    扩展头大小是由文件头中 `SizeOfOptionalHeader` 字段给出,`FIELD_OFFSET` 这个是给出 `OptionalHeader` 在 `IMAGE_NT_HEADERS` 结构中的偏移,如下:

    (本小节完)

  • 相关阅读:
    Java如何编写自动售票机程序
    install windows service
    redis SERVER INSTALL WINDOWS SERVICE
    上传文件
    This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.
    解决Uploadify上传控件加载导致的GET 404 Not Found问题
    OracleServiceORCL服务不见了怎么办
    Access to the temp directory is denied. Identity 'NT AUTHORITYNETWORK SERVICE' under which XmlSerializer is running does not have sufficient permiss
    MSSQL Server 2008 数据库安装失败
    数据库数据导出成XML文件
  • 原文地址:https://www.cnblogs.com/importthis/p/10192523.html
Copyright © 2011-2022 走看看