在32位系统中,每个进程实际上具有2 ^ 32个字节的CONTIGUOUS地址空间。那么为什么链接器生成的最终可执行代码需要可重定位。要求是什么,因为生成的所有地址都是进程自己的地址空间中的虚拟地址,而其他进程不能使用相同的地址空间。 因此,该过程可以放在它想要的任何地方。为什么要重新定位?
答案 0 :(得分:2)
某些操作系统使可执行代码可重定位(这对所有操作系统来说绝对不是通用的)以允许address space layout randomization。这有助于缓解某些攻击。
过去,当堆栈可执行时,可以通过直接在溢出的堆栈或堆上写入可执行代码来利用缓冲区溢出。随着操作系统变得更加智能并开始阻止堆栈和堆的执行,攻击变得更加复杂,并且通过执行return oriented programming开始在内存中使用已知代码序列。这类攻击的缓解首先是通过随机化共享库的内存布局(因为那些更容易利用)然后当攻击者切换到攻击主可执行文件时,通过随机化可执行文件的内存位置来完成的。为了使主要可执行文件成为可能,需要重新定位。
答案 1 :(得分:1)
可执行代码并不总是包含相对地址。例如,在Windows上,寻址通常是绝对的(例如,对于全局数据)。
考虑两个不同的动态库。两者都编译为固定基址0x00100000。您的程序尝试加载它们。装载器放置第二个DLL的位置在哪里?其首选基地址已被其他DLL使用。
在这种情况下,可重定位代码有助于将第二个DLL放在不同的地址,并将其内部指针修补到新位置。使用固定的基址,加载第二个DLL就会失败。
答案 2 :(得分:-1)
它需要可重定位,因为为了执行您的进程需要将其放入就绪队列中的实际主内存中。现在主存储器中的位置不固定(它放置在有足够空间的地方),因此指令的实际地址与其虚拟地址不同。
因此,需要相应地更新函数,返回等的语句,指向这些函数的实际地址