C++ 什么';HIGHLOW在反汇编二进制文件中的含义是什么?

C++ 什么';HIGHLOW在反汇编二进制文件中的含义是什么?,c++,windows,assembly,x86,dumpbin,C++,Windows,Assembly,X86,Dumpbin,我第一次使用DUMPBIN,我在输出文件中反复看到术语HIGHLOW: BASE RELOCATIONS #7 11000 RVA, E0 SizeOfBlock ... 3B5 HIGHLOW 2001753D ___onexitbegin 3C1 HIGHLOW 2001753D ___onexitbegin ... 我很好奇这个词代表什么。我没有在谷歌或Stackov

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

BASE RELOCATIONS #7
   11000 RVA,       E0 SizeOfBlock
    ...
         3B5  HIGHLOW            2001753D  ___onexitbegin
         3C1  HIGHLOW            2001753D  ___onexitbegin
    ...
我很好奇这个词代表什么。我没有在谷歌或Stackoverflow上找到任何关于它的信息

若要应用修正,将计算增量,作为 首选基址,以及映像实际所在的基址 上膛了

基本的想法是,当我们在某个地址做一个固定时,我们必须知道

  • 必须更改的内存(“偏移”字段)
  • 重新定位需要什么值(“增量”值)
  • 要使用重新定位的数据和增量值的哪些部分(“类型”字段)
  • 以下是“类型”字段的一些可能值

    • HIGH
      -在“偏移量”处的16位值上添加更高的增量字(16位)
    • LOW
      -在“偏移”处的值中添加较低的增量字
    • HIGHLOW
      -在“offset”处的32位值上添加完整的增量
    换句话说,
    HIGHLOW
    type告诉程序,它正在对此重定位块*页面的偏移量“offset”进行修复,并且需要修改一个双字,以使可执行文件正常工作

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

    假设您的代码中有以下说明:

    section .data
    message: "Hello World!", 0
    
    section .code
    ...
    mov eax, message
    ...
    
    运行汇编程序,然后立即运行反汇编程序。现在,您的代码如下所示:

    mov eax, dword [0x702000]
    
    您现在很好奇为什么它是
    0x700000
    ,当您查看文件转储时,您会看到

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

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

  • 计算增量值-旧地址(图像基)为
    0x700000
    ,但它需要
    0xf00000
    (首选地址)。它将一个从另一个中减去,得到
    0x800000
  • 获取文件的
    .reloc
    部分
  • 检查是否还有另一个页面(4KB的数据)需要重新定位。若否,则继续调用文件的入口点。 4.对于当前页面的每次重新定位,它
  • 获取重定位偏移量处的数据
  • 添加增量值(以类型字段状态的方式)
  • 将新值放置在重新定位偏移处
  • 继续执行步骤3

  • 还有更多类型的重新定位入口,其中一些是特定于体系结构的。要查看完整列表,请阅读“Microsoft可移植可执行文件和通用对象文件格式,第6.6.2节。修复类型”。

    此处显示的是Microsoft Windows可执行文件中“基本重新定位表”的内容

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

    该表支持不同类型的地址,而命名是特定于Microsoft的:绝对(=虚拟)、高、低、高、低、高和MIPS_JMPADDR

    常量的全称为“IMAGE\u REL\u BASED\u HIGHLOW”

    “绝对”类型通常是一个插入的伪条目,以确保表的各个部分是4(或8)字节长的倍数

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

    一些背景信息:

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

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

    可能无法使用地址为0x20000000的内存,Windows决定将DLL加载到地址为0x50000000的内存中。然后必须将0x20012345替换为0x50012345

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