【问题标题】:What is there before ImageBase address in Virtual Address?虚拟地址中的 ImageBase 地址之前有什么?
【发布时间】:2021-10-26 21:31:10
【问题描述】:

我从Microsoft documentation 知道,对于 64 位图像,图像基址设置为 0x140000000,它是可执行文件首次加载到内存中的基址。

所以我的问题如下

  1. 0x140000000 地址和虚拟地址第一页的开始 (0x0000000) 之前的内容
  2. 首先加载可执行文件是什么意思?是程序的入口点(当然不是main函数)还是别的什么

【问题讨论】:

    标签: windows portable-executable


    【解决方案1】:

    0x140000000 地址和虚拟地址第一页的开始 (0x0000000) 之前的内容

    在那里分配的任何内容,例如 DLL、文件映射、堆内存,或者此内存都可以是空闲的。第一页始终无法访问。

    可执行文件首先加载是什么意思?是程序的入口点(当然不是main函数)还是别的什么

    加载意味着映射到内存中。映射到内存后,解析导入,静态链接的DLL映射到内存,执行它们的入口点,然后才到达可执行入口点。如果可执行文件具有 TLS 回调,则可执行文件入口点并不是真正从可执行文件执行的第一个函数。

    【讨论】:

    • 对于像堆这样的映射来说,0x00 - 0x13fffffff 的范围是不是太小了。如果我继续使用 malloc 会不会导致堆溢出?
    • 如果继续使用malloc,确实会导致堆溢出。在分配较低地址之前,您可能会用完物理内存/交换。您可以通过使用VirtualAlloc 来保留可执行映射上方的整个范围进行实验,然后您将看到malloc 返回低地址。或者您可以通过/LARGEADDRESSAWARE:NO 看到它。
    • 嗯,我认为你的回答很有道理va representation
    【解决方案2】:

    我不知道 64 位默认值如此之高的技术原因,也许只是为了确保您的应用程序没有模块中的数据/代码的 32 位指针截断错误?而且需要注意的是,这个默认值来自微软的编译器,Windows 本身会接受一个较低的值。 32 位应用程序的默认值为 0x00400000,还有actual hardware and technical reasons for that

    在大多数操作系统中,从 0 开始的第一页是禁区,以防止取消引用 NULL 指针时出现问题。前几兆字节可能映射了 BIOS/固件或其他遗留的东西。

    第一次加载意味着加载器会将文件映射到从该地址开始的内存中。首先是 MZ 部分(DOS 标头和存根代码)和PE header。之后是 PE 标头中列出的各个部分。

    如今大多数应用程序都在使用 ASLR,因此基地址将是随机的,而不是 PE 中列出的首选地址。 ntdll 和 kernel32 在 exe 之前映射,因此如果您选择它们​​的基地址,您也将被重新定位。

    【讨论】:

      猜你喜欢
      • 2016-10-05
      • 2021-11-27
      • 1970-01-01
      • 2011-08-20
      • 2011-01-11
      • 1970-01-01
      • 2015-05-04
      • 2013-05-05
      • 1970-01-01
      相关资源
      最近更新 更多