我有一些二进制文件,我使用mmap()将其写入内存。然后我尝试从分配的内存中执行它,但直到现在它没有结果。有人可以帮忙吗?例子表示赞赏) 我在Ubuntu, 任何二进制文件(c hello world),其大小为file_size,其描述符为fd,然后是:
addr = mmap(NULL, file_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, pa_offset);
if (addr == MAP_FAILED)
handle_error("mmap");
所以我不知道如何执行它
答案 0 :(得分:3)
虽然你的问题即使在编辑之后仍然令人困惑,但我认为你已经足够说明你做错了什么。
任何二进制文件(c hello world)
您无法以与操作系统执行相同的方式执行mmap
二进制文件。你在Linux上运行,所以你的hello世界很可能是ELF格式的二进制文件。 Linux知道如何读取和执行ELF二进制文件,而您的程序则不知道。 ELF starts with a header以及您的内存映射数据也以标头开头。哪个不是可执行代码。标头以0x7F
开头,对应于x86上的jg
指令,因此尝试'执行'ELF标头作为可执行代码可能(取决于标志的状态)立即跳转到垃圾地址由标题的下一个字节构成。
如果你想运行这样的代码,你需要解析ELF文件,找到它的入口点(或者,可能首先是.init
部分)并从那里开始执行代码。出于学习目的,你当然可以自由地做这个练习,但这不是从你自己执行另一个程序的正常方式。一种典型的方法是使用fork
和exec
调用。这让Linux可以处理启动程序的技术问题。
答案 1 :(得分:1)
几乎不可能执行任意内存映像。 ELF文件必须在进程地址空间中以特定方式进行mmaped,几乎从不作为底层文件的连续映像。
我能想到的最接近的可行方法是将图像保存到(可能是无名的)文件中,并通过execveat(fd, "", ...)
执行该文件。检查execveat(2)在他们谈论空路径名的位置,并在O_TMPFILE上打开(2)。
命名的临时文件和常规的execve(2)也可以正常工作,只要在文件可以更改时close / munmap和execve之间的差距不是问题。
另一个想法是在用户空间完全加载ELF,为新进程设置正确的地址空间,调用LD等。绝对不容易。不需要任何execve(2)调用,只需从那里分叉和工作。因为不会使用execve(2),所以某些事情如O_CLOEXEC处理和解压缩额外内存将需要非常简单的解决方法。