在Linux中移动堆栈并保留一半可寻址空间

时间:2014-05-06 12:29:57

标签: c linux assembly linker crt

对于内存监控库的实现,我想移动受监控程序的堆栈,并保留虚拟内存的上半部分,以便在监控库中使用,跟随" half' n' -model描述由TaintTraceLIFTHobbes等工具使用。但是,我似乎并不清楚如何实际做到这一点。只是mmaping所需的内存失败(无法分配内存)。我需要修改crt吗?链接器?

1 个答案:

答案 0 :(得分:0)

我不太确定如何分配受污染和无污染的内存,并在类似Unix的操作系统中进行优化。

Unix系统中的内存分配是使用brk()和sbrk()完成的。没有比这更多的了。对于其他内存空间,您需要使用共享内存分配(您可以仅通过您的进程对它们进行读/写,因此它就是#34;共享"就在您之间。)

您遇到的问题是不断增长的内存分配。我不太确定,但从我记得使用共享内存时,您无法轻松扩展分配的缓冲区。但是较新的界面可能对您有用。

---更新:

阅读malloc()文档,我发现了以下内容:

  

通常,malloc()从堆中分配内存,并调整   使用sbrk(2)根据需要填充堆的大小。分配块时   内存大于MMAP_THRESHOLD字节,glibc malloc()   实现将内存分配为私有匿名映射   使用mmap(2)。 MMAP_THRESHOLD默认为128 kB,但可以调整   使用mallopt(3)。使用mmap(2)执行的分配是   不受RLIMIT_DATA资源限制的影响(参见getrlimit(2))。

这意味着操作系统已经默认使用mmap()来分配大于128Kb的缓冲区。此外,标准的malloc()受到RLIMIT_DATA的getrlimit()的限制:

  

流程数据段的最大大小(初始化数据,   未初始化的数据和堆)。此限制会影响对brk(2)和   sbrk(2),在遇到软件时失败并出现错误ENOMEM   这个资源的限制。

但是,正如malloc()所说,如果你分配大缓冲区(128Kb +),那么你不会受到该限制的影响。

话虽这么说,很多内存都分配给内核本身,程序,映射到地址的I / O(DMA),中断表,内存表(MMU管理)和共享内存缓冲区等内容。 (即使用SHARED的mmap()将分配所有进程必须具有访问权限的内存地址,即使您还没有使用它们,如果您要访问它们,它们也会被保留。)

使用共享内存的那些东西就是共享库。 (二进制文件加载在共享内存中,因此对于针对所述共享库运行的所有进程一次。)