![](/img/trans.png)
[英]How to properly set the Python path for the reticulate package in OSX High Sierra?
[英]10.13 High Sierra OSX - Python mprotect always fails when granting exec permission, with ENOMEM
背景:
編寫涉及在python程序中執行機器代碼的概念證明。 要在osx上執行此操作,因此必須使用ctypes和libc.dylib以及以下函數調用:
(禁用SIP)
問題 :
該問題出現在mprotect函數調用中,該調用總是失敗時返回-1。
腳本:(邏輯幾乎與linux系統相同,因為它們都是posix系列)
import ctypes
buf = "machine code..."
libc = cytpes.CDLL('libc.dylib')
size = len(buf)
buf_ptr = ctypes.c_char_p(buf)
# allocate aligned memory space
alloc_space = ctypes.c_void_p(ctypes.valloc(size))
# this always evaluates true, and mprotect fails every attempt
if 0 != libc.mprotect(alloc_space, size, 1 |2 |4):
print "mprotect failed"
ctypes.mmove(alloc_space, buf_ptr, size)
mmove現在將失敗,並出現segfault錯誤消息(b / c寫入可能僅具有讀取特權的內存空間),並且程序出現故障……
問題是與mprotect有關,此方法在linux中效果很好,我現在看到的結果對於mac osx來說是非常不同的
題:
Mac OSX是否具有限制mprotect操作類型的額外安全功能(即使禁用了SIP)? 如果是這樣,一個人怎么能繞過它呢?
更新:
根據注釋中建議的@DietrichEpp,在ctypes.CDLL調用中使用use_errno = True會生成errno。 評估為errno:12,無法分配內存。 該errno是mprotect手冊頁上ENOMEM的值。
盡管手冊頁上有一些ENOMEM,但我懷疑這是最后一種情況:(b / c valloc調用沒有錯誤)
ENOMEM Changing the protection of a memory region would result in the total number of mappings with distinct attributes (eg, read versus read/write protection) exceeding the allowed maximum. (For example, making the protection of a range PROT_READ in the middle of a region currently protected as PROT_READ|PROT_WRITE would result in three mappings: two read/write mappings at each end and a read-only mapping in the middle.)
我懷疑osx具有特殊的限制,並為每個進程設置了最大映射,因此增加更多權限,同一進程的新映射將超過此最大限制(每個進程有多少個具有exec / write特權的映射)。 如果我的假設是正確的,我們如何解決呢?
Apple的手冊頁不再在線,但請參考POSIX手冊頁以獲取mprotect :
如果未通過調用mmap()建立映射,則該函數的行為不確定。
在這方面,Linux似乎更為寬容,它允許您或多或少在所需的任何內存上調用mprotect()。 Darwin更為嚴格,如果要調用mprotect(),則要求您使用mmap()中的內存。 這就是為什么從頭到尾閱讀整個手冊頁都值得的原因之一。
如果您考慮一下,這是一個合理的要求。 valloc()給定的內存由分配器管理,以后必須通過free()返回給分配器,並且mprotect()在某種意義上繞過了分配器的背面,並改變了內存的工作方式。 mmap()和munmap()並非如此,它們與mprotect()在同一系列的系統調用中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.