【问题标题】:What's the meaning of HIGHLOW in a disassembled binary file?反汇编的二进制文件中的HIGHLOW是什么意思?
【发布时间】:2014-07-18 09:42:20
【问题描述】:

我刚刚第一次使用 DUMPBIN,我在输出文件中反复看到术语 HIGHLOW:

BASE RELOCATIONS #7
   11000 RVA,       E0 SizeOfBlock
    ...
         3B5  HIGHLOW            2001753D  ___onexitbegin
         3C1  HIGHLOW            2001753D  ___onexitbegin
    ...

我很好奇这个词代表什么。我在 Google 或 Stackoverflow 上没有找到任何关于它的信息。

【问题讨论】:

    标签: c++ windows assembly x86 dumpbin


    【解决方案1】:

    为了应用修正,delta 被计算为 首选基址,以及图像实际所在的基址 已加载。

    基本思想是,在某个地址进行修复时,我们必须知道

    1. 必须更改哪些内存(“偏移”字段)
    2. 重定位需要什么值(“delta”值)
    3. 要使用重定位数据和增量值的哪些部分(“类型”字段)

    以下是“类型”字段的一些可能值

    • HIGH - 将增量的高位字(16 位)添加到“偏移”处的 16 位值
    • LOW - 将 delta 的低位字添加到“偏移”处的值
    • HIGHLOW - 在“偏移”处将完整的增量添加到 32 位值

    换句话说,HIGHLOW 类型告诉程序它正在从这个重定位块*的页面的偏移量“偏移量”上进行修复,并且需要修改一个双字才能拥有正常工作的可执行文件。

    * 所有的重定位条目都被分组到块中,每个块都有一个页面,在该页面上应用其条目

    假设您的代码中有这条指令:

    section .data
    message: "Hello World!", 0
    
    section .code
    ...
    mov eax, message
    ...
    

    您运行汇编程序,然后立即运行反汇编程序。现在您的代码如下所示:

    mov eax, dword [0x702000]
    

    你现在很好奇为什么是0x700000,当你查看文件转储时,你会看到

    ImageBase:      0x00700000
    

    现在您了解了这个数字是从哪里来的,并且您已经准备好运行可执行文件了。 将可执行文件加载到内存并为其创建地址空间的加载程序发现内存0x700000 不可用,它需要将该文件放在其他地方。它决定0xf00000 可以,并将文件内容复制到那里。

    但是,您的程序被链接为仅使用 0x700000 上的数据,并且链接器无法知道其输出将被重新定位。正因为如此,装载机必须发挥它的魔力。它

    1. 计算 delta 值 - 旧地址(图像库)是0x700000,但它需要0xf00000(首选地址)。它从另一个中减去一个并得到0x800000 作为结果。
    2. 进入文件的.reloc 部分
    3. 检查是否还有另一个页面(4KB 的数据)要重新定位。如果不是,它会继续调用文件的入口点。 4.对于当前页面的每次重定位,它
    4. 在重定位偏移处获取数据
    5. 添加增量值(以类型字段状态的方式)
    6. 将新值放在重定位偏移处
    7. 继续第 3 步

    还有更多类型的重定位条目,其中一些是特定于架构的。要查看完整列表,请阅读“Microsoft Portable Executable and Common Object File Format, section 6.6.2. Fixup Types”

    【讨论】:

      【解决方案2】:

      您在此处看到的是 Microsoft Windows 可执行文件中“基本重定位表”的内容。

      在 Windows 中基本重定位表对于 DLL 文件是必需的,它们对于可执行文件是可选的;它们包含有关 EXE/DLL 文件中地址信息位置的信息,当知道 DLL 文件在内存中的实际地址时(将 DLL 加载到内存中时),必须更新这些信息。 Windows 使用存储在此表中的信息来更新地址信息。

      该表支持不同类型的地址,而命名是 Microsoft 特定的:ABSOLUTE (= dummy)、HIGH、LOW、HIGHLOW、HIGHHADJ 和 MIPS_JMPADDR。

      常量的全称是“IMAGE_REL_BASED_HIGHLOW”。

      “ABSOLUTE”类型通常是插入的虚拟条目,以确保表的部分长度为 4(或 8)字节的倍数。

      在 x86 CPU 上仅使用“HIGHLOW”类型:它告诉 Windows 文件中绝对(32 位)地址的位置。

      一些背景信息:

      在您的示例中,“Image Base”可能是 0x20000000,这意味着 EXE/DLL 文件已被编译为加载到地址 0x20000000。在地址 0x200113B5 (0x20000000 + 0x11000 + 0x3B5) 和 0x200113C1 处有绝对地址。

      假设内存位置 0x200113B5 包含值 0x20012345,它是程序中函数或变量的地址。

      也许地址 0x20000000 的内存无法使用,Windows 决定将 DLL 加载到 0x50000000 的内存中。那么 0x20012345 必须替换为 0x50012345。

      Windows 使用基本重定位表中的信息来查找所有必须替换的地址。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-02
        • 1970-01-01
        相关资源
        最近更新 更多