工艺简单加载内存映射(Simple process loader memory mapping)

2019-09-20 11:11发布

我正在写一个Linux非常简单的过程装载机。 我装的可执行文件已经进行了编译,我知道每个人期望在内存中找到。 我试图第一种方法是使用mmap()手动放置在正确的位置上的每个代码或数据段,如

mmap(addr, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)

它出现segfaults除非我删除了MAP_FIXED标志,因为它似乎有一些已经在内存中,甚至可能装载机本身就是块冲突的地址; 地址0x401000似乎是有问题的。

我真的不甚至知道在这一个开始。 一个朋友建议虚拟存储器存取操作; 我不知道我会采取什么样的性能命中是什么,以及我不知道它是如何做,但它可能是一种选择。 我真的很想做的就是创建一个“空”的过程,这将有,就有人担心,存储器的完整运行,所以什么都不会被加载到用户空间,直到我希望它是。 “空”过程的整个概念可能是毫无意义的,但它是描述我想要的东西的最佳方式。 我对一些引用或例子,可以帮助我很失望。

Answer 1:

有了您的进程中运行(在打盹,也许 “休眠(1000);”),看看它的/ proc / PID /地图。 这会告诉你什么0x401000的用途。

~$ sleep 1h &
[3] 2033
~$ cat /proc/2033/maps
00110000-002af000 r-xp 00000000 08:01 1313056    /lib/i386-linux-gnu/libc-2.15.so
...

这对我的盒子,/ bin中/睡眠不使用该块,而且也没有我小的单行程序。

你可能在想在那里降落一些库链接?

因此,一个办法是分配你需要的方式早块(很久以前的main()中运行 - 别处寻找这些信息)。

另一种方法是你的代码链接到你“知道”是不是采取了一些地址(“链接”想必,你正在生成的操作码的x86自己,或以其他方式,所以这不应该是一个延伸)。

另外,更好的,方法是使你的代码重定位。 你不想更换整个进程的地址空间的事实(正是高管一样)或多或少地说,你的代码应该是公正的。

所以,找到一个可用的地址,载入位在那里,并根据需要进行重新定位(所以你的磁盘上的文件格式,如果它不是ELF,将需要包括RELOC信息)。 这是高端路线,和明显的事情,你会想从你的下一个装载机。

当然,相当多的手段重新实现dlopen()的自己。 我以为你只是想了解它是如何工作的 - 如果不是,男人dlopen的。 斯特凡法则零:它已经存在;-)

不要忘记,以支持从您的代码链接的其他库(不重复),dlclose(),初始化,各种RTLD_ *模式,荣誉MYCUSTOMLD_LIBRARY_PATH,GCC的__thread说明符等;-)



文章来源: Simple process loader memory mapping