首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单的进程加载器内存映射

简单的进程加载器内存映射
EN

Stack Overflow用户
提问于 2012-07-30 22:40:19
回答 1查看 550关注 0票数 3

我正在为Linux编写一个非常简单的进程加载器。我正在加载的可执行文件已经编译,并且我知道每个可执行文件在内存中的什么位置。我尝试的第一种方法是使用mmap()手动将每个代码或数据部分放在正确的位置,例如

代码语言:javascript
复制
mmap(addr, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)

除非我删除MAP_FIXED标志,否则它会出现段错误,因为似乎一个块的地址与内存中已有的东西冲突,甚至可能与加载器本身冲突;地址0x401000似乎是有问题的。

我甚至不确定从哪里开始做这件事。我的一个朋友建议虚拟化内存访问操作;我不确定这样做会对性能造成什么样的影响,我也不知道它是如何做到的,但这可能是一个选择。我真正喜欢做的是创建一个“空的”进程,就它而言,它会占用全部内存,所以在我想要加载到用户空间之前,不会加载任何东西。整个“空”过程的概念可能没有意义,但这是描述我想要的最好的方式。我非常需要一些可能对我有帮助的参考资料或例子。

EN

回答 1

Stack Overflow用户

发布于 2012-08-19 07:08:07

当您的进程正在运行时(可能在“sleep(1000);”中打瞌睡),查看它的/proc/pid/map。这将告诉您0x401000的用途。

代码语言:javascript
复制
~$ 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/sleep没有使用这个块,我的小一行程序也没有。

你可能正在链接一些想要登陆的库?

因此,一种方法是尽早分配所需的块(在main()运行之前很久--在其他地方查找该信息)。

另一种方法是将您的代码链接到某个您“知道”不会被占用的地址(假设您自己生成x86操作码,或者“链接”,因此这不应该是一种延伸)。

另一个更好的选择是使您的代码可重定位。您不想替换整个进程的地址空间(这正是exec所做的),这一事实或多或少表明您的代码应该就是这样。

因此,找到一个可用的地址,在那里加载位,并根据需要执行重新定位(因此,如果磁盘上的文件格式不是ELF,则需要包含reloc信息)。这是最重要的,也是你下一步想要从你的装载器中得到的东西。

当然,这很大程度上意味着要自己重新实现dlopen()。我猜想你只是想了解它是如何工作的--如果不是这样的话,伙计dlopen。斯蒂芬的零规则:它已经在那里了;-)

不要忘了支持从你的代码链接其他库(不重复),dlclose(),初始化器,各种RTLD_*模式,遵守MYCUSTOMLD_LIBRARY_PATH,GCC的__thread说明符等;-)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11723758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档