将ELF共享库和自定义binfmt可执行文件加载到相同的Linux地址空间
我正在做一个项目,在Linux平台上加载并运行一个自定义二进制格式的可执行文件(在我的例子中是PE)。到目前为止,我已经非常成功地完成了这项工作,首先加载可执行文件,然后加载一个小的ELF共享库,该库调用可执行文件的开始地址,然后安全退出 不过,出于几个原因,我真的不想自己装精灵。首先,我使用的共享库是在汇编中编写的(我不能使用其他任何东西,因为我没有链接到将ELF共享库和自定义binfmt可执行文件加载到相同的Linux地址空间,linux,memory-management,process,shared-libraries,elf,Linux,Memory Management,Process,Shared Libraries,Elf,我正在做一个项目,在Linux平台上加载并运行一个自定义二进制格式的可执行文件(在我的例子中是PE)。到目前为止,我已经非常成功地完成了这项工作,首先加载可执行文件,然后加载一个小的ELF共享库,该库调用可执行文件的开始地址,然后安全退出 不过,出于几个原因,我真的不想自己装精灵。首先,我使用的共享库是在汇编中编写的(我不能使用其他任何东西,因为我没有链接到libc,等等),这将是非常特定于平台的,我想离开它,使用C,这样我就可以为任何平台编译。此外,使用Linux的本机ELF加载程序而不是我自
libc
,等等),这将是非常特定于平台的,我想离开它,使用C,这样我就可以为任何平台编译。此外,使用Linux的本机ELF加载程序而不是我自己的简化版本将更容易、更安全
我想知道是否有一种方法可以使用我的binfmt处理程序(一个已安装的内核模块)来加载我的可执行文件,然后让Linux将我的共享库(及其依赖项)加载到相同的地址空间,而不覆盖我的可执行代码。我最初认为uselib
syscall可能有用,但手册页上的描述不清楚这是否符合我的目的:
从libc4.4.4开始,仅加载库“/lib/ld.so”,以便
此动态库可以加载所需的其余库(再次
使用此呼叫)。这也是libc5的现状
glibc2不使用此调用
我也从未见过它的使用示例,而且我总是对使用我不理解的系统调用保持警惕
有没有一个好的方法来实现我所描述的?我可以使用Linux的现有功能将共享库(用C编写)加载到已经包含可执行代码的地址空间中吗?如果可以,我如何使用该库而不知道它加载到了哪里?已经有一个类似这样的项目,名为binfmt_pe(由我!),它是一个内核模块,并且将有自己的链接器(类似于/lib/ld) 至于你关于制作模块和加载程序/链接器的问题,下面有一些链接。我还包括了关于ELF和PE可执行文件信息的链接 我希望这有帮助。:) 制作Linux内核模块的有用信息
mmap
,那么整个过程都会崩溃,因为我正在重写内存中执行的代码。当用户空间看起来不再是一个选项时,我转而使用内核模块进行加载;它基本上是ELF加载程序的模拟,我想要运行的ELF代码(来自共享库)是ELF解释器的模拟。现在,这里有一个想法:仍然加载elf二进制文件,但告诉GCC创建位置无关的代码。然后,必须有某种头告诉Linux在哪个地址加载elf代码,让PE地址保持空闲。@Linuxios这就是我现在要做的,只是它是一个共享库,而不是PIC(基本上对我来说是一样的)。问题是如何让linux首先加载ELF代码。从内核模块调用execve
肯定会加载它,但会加载到它自己的地址空间中;我想把它写进体育课。我想继续接受你的答案(非常彻底),但我还有几个问题。我已经在这个项目上工作了大约一年了,现在完全被卡住了。加载PE不是问题;我可以将它放入内存并执行它,只要它不引用任何外部库。您计划如何在实施中处理这一问题?