![](/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.