重新映射共享库
回答
肯定不是在进程运行时,如果它没有准备好这样做。请记住,共享库代码是一回事,共享库内的数据结构是另一回事。指向库中静态定义的数据结构的指针可能只存在于您的进程中的任何位置,而您无法更改它们。
现在,如果你想写一个新的程序,应该允许这个,它不应该太难。对共享库没有静态依赖关系,使用dlopen()
将其打开,并使用dlsym()
获取函数。让你的进程捕捉到SIGUSR1这样的信号,并在信号处理程序中(更好:在主循环中的某个安全点检测到信号处理程序调用时设置的标志)丢弃旧库,加载新库并调整相应的符号。
我想要做以下操作,让父母取消映射并重新映射库,然后再分叉孩子,孩子将要使用重新映射的库,我如何解决所有符号,以便孩子能够正确运行?我应该为每个符号调用dlsym吗? –
如果您知道共享库没有被执行(即不在调用堆栈中),那么执行该操作相当容易。只需dlclose()该库,然后再次dlopen()。如果你需要一个图书馆的处理,你可以自己dlopen(),然后关闭它两次。我相信这会起作用,因为引用计数将达到零,并且库将被取消映射(除非最初加载的库以某种方式特殊装入)。如果你可以避免共享库的链接时依赖(只需在ELF构造函数中调用dlopen),这肯定会起作用。
如果您正在手动加载新库(如果您希望能够选择其加载地址),则可以简单地自行覆盖PLT条目。我写了一个工具,它做了一些非常相似的工作,如https://github.com/dwks/asyncsafe。如果您覆盖每个PLT条目以指向解析函数,则懒惰符号加载将自动再次发生;或者,你可以自己解决它们。
我确定你知道Blind ROP学术攻击(http://www.scs.stanford.edu/~abelay/pdf/bittau:brop.pdf)。这种攻击有几种防御措施可以满足你的要求,试着搜索文献。
- 1. 错误而映射共享库
- 2. JPA共享实体映射
- 3. 升压共享内存映射重新连接
- 4. 学说Yaml映射共享列
- 5. Ç共享存储器指针映射
- 6. 休眠 - 共享映射xml文件
- 7. 带有boost :: interprocess的共享映射
- 8. 保存哈希映射共享偏好
- 9. 共享Windows映射驱动器
- 10. 共享内存中的C++ STL映射
- 11. 无法映射共享内存
- 12. TFS 2010映射到共享文件夹
- 13. 共享模型的休眠映射
- 14. 为Linux重新编译共享Android库
- 15. 在Visual Studio版本之间共享git存储库映射
- 16. 使用ctypes映射来自共享库的全局变量
- 17. 映射共享库部分时出错:libhmmm.so:成功
- 18. mach_vm_region_recurse,在osx上映射内存和共享库
- 19. Linux中共享库内存映射的访问权限
- 20. 共享点重新注册
- 21. 重新映射Emacs命令
- 22. IP地址重新映射
- 23. 重新映射?在NERDTree
- 24. 重新映射按键
- 25. ARM内存重新映射
- 26. 重新映射线路键
- 27. 阵列重新映射
- 28. Vim重新映射奇怪
- 29. 重新映射arbitary曲线
- 30. vim重新映射hjkl
如果给mmap()提供了正确的选项,你也许可以映射这个库的一个新副本,但它只是文件的映射,而不是解释和分割成文本/数据等等。像加载器或'dlopen()'这样的节会给。 'dlopen()'可能会让你回到现有的副本。取消映射现有的副本很可能是不可能的,因为如果允许的话,它可能会对进程造成致命的影响...... – twalberg