动态重定位代码段

时间:2010-02-22 18:16:44

标签: c linux assembly relocation self-modifying

出于好奇,我想知道是否可以重新定位一段代码 程序的执行。例如,我有一个函数,这个函数应该 每次执行后都要在内存中更换。我们想到了一个想法 是使用自修改代码来做到这一点。根据一些在线资源,自我修改 代码可以在Linux上执行,但我仍然不确定是否可以进行这样的动态重定位。有没有人经历过这个?

3 个答案:

答案 0 :(得分:8)

是动态搬迁肯定是可能的。但是,您必须确保代码完全自包含,或者通过绝对引用访问全局/外部函数。如果你的代码可以完全独立于位置,意味着它所做的唯一引用是相对于它自己的,那么你就可以了。否则,您需要在加载时自行进行修正。

使用GCC,您可以使用-fpic生成与位置无关的代码。将-q--emit-relocs传递给链接器将使其发出重定位信息。 ELF specification(PDF链接)包含有关如何使用该重定位信息的信息;如果您不使用ELF,则必须找到适合您格式的文档。

答案 1 :(得分:3)

正如卡尔所说,它可以做到,但你正在打开一堆蠕虫。在实践中,唯一煞费苦心的人是学者或恶意软件作者(现在穿上我的防火斗篷)。

您可以将一些代码复制到malloc的堆区域,然后通过函数指针调用它,但根据操作系统,您可能必须在该段中启用执行。您可以尝试将一些代码复制到代码段中(注意不要覆盖以下函数),但操作系统可能会将此段设置为只读。您可能希望查看Linux内核并了解它如何加载其模块。

答案 2 :(得分:0)

如果在编译时存在所有这些不同的函数,那么您可以简单地使用函数指针来跟踪下一个要调用的函数。如果您必须在运行时修改该函数并且无法在适当的位置进行修改,那么您还可以使用在创建/加载时使用新函数的地址更新的函数指针。然后系统的其余部分将通过函数指针调用自修改函数,因此不必知道或关心自修改代码,您只需要在一个地方进行修复。