重新映射共享庫
回答
肯定不是在進程運行時,如果它沒有準備好這樣做。請記住,共享庫代碼是一回事,共享庫內的數據結構是另一回事。指向庫中靜態定義的數據結構的指針可能只存在於您的進程中的任何位置,而您無法更改它們。
現在,如果你想寫一個新的程序,應該允許這個,它不應該太難。對共享庫沒有靜態依賴關係,使用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