简体   繁体   English

10.13 High Sierra OSX-使用ENOMEM授予执行权限时,Python mprotect总是失败

[英]10.13 High Sierra OSX - Python mprotect always fails when granting exec permission, with ENOMEM

Background: 背景:

Writing a proof of concept that involves executing machine code within a python program. 编写涉及在python程序中执行机器代码的概念证明。 To do this on osx so I had to utilize ctypes and libc.dylib and the following function calls: 要在osx上执行此操作,因此必须使用ctypes和libc.dylib以及以下函数调用:

(With SIP disabled) (禁用SIP)

  1. valloc to allocate aligned memory valloc分配对齐的内存
  2. mprotect to grant wrx permission on allocated memory mprotect在分配的内存上授予wrx权限
  3. memmove to copy executable code to allocated memory; 记忆将可执行代码复制到分配的内存中; cast; 投; and execute... 然后执行...

Problem : 问题

The issue arises at the mprotect function call, where it always return -1 for fail. 该问题出现在mprotect函数调用中,该调用总是失败时返回-1。

Script: (logic almost identical to a linux system as they both are posix family) 脚本:(逻辑几乎与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)

The mmove will now fail with a segfault error message (b/c writing the memory space that probably only had read privilege), and program comes to a hault... mmove现在将失败,并出现segfault错误消息(b / c写入可能仅具有读取特权的内存空间),并且程序出现故障……

The problem is with mprotect, this method works very well in linux, I am now seeing that the results are very different for mac osx 问题是与mprotect有关,此方法在linux中效果很好,我现在看到的结果对于mac osx来说是非常不同的

Question: 题:

Does Mac OSX have extra security features (even with SIP disabled) that restricts the mprotect type of operation? Mac OSX是否具有限制mprotect操作类型的额外安全功能(即使禁用了SIP)? And if so, how can one bypass it? 如果是这样,一个人怎么能绕过它呢?

UPDATE: 更新:

As per @DietrichEpp suggested in the comments, using use_errno=True on ctypes.CDLL call generated the errno. 根据注释中建议的@DietrichEpp,在ctypes.CDLL调用中使用use_errno = True会生成errno。 It evaluated to errno: 12, Cannot allocate memory. 评估为errno:12,无法分配内存。 This errno is the value for ENOMEM on the mprotect man page. 该errno是mprotect手册页上ENOMEM的值。

Although there were a few ENOMEM on the man page, I suspect it is the last scenario: (b/c there were no error with the valloc call) 尽管手册页上有一些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.) 

I suspect that osx have special restrictions, and have set the maximum mappings for each process, hence adding more permissions a new mapping of the same process will exceed such maximum limit (of how many mappings with exec/write privileges per process). 我怀疑osx具有特殊的限制,并为每个进程设置了最大映射,因此增加更多权限,同一进程的新映射将超过此最大限制(每个进程有多少个具有exec / write特权的映射)。 If my assumptions were true, how can we work around that? 如果我的假设是正确的,我们如何解决呢?

Apple's man pages are no longer online, but refer to the POSIX man page for mprotect : Apple的手册页不再在线,但请参考POSIX手册页以获取mprotect

The behavior of this function is unspecified if the mapping was not established by a call to mmap(). 如果未通过调用mmap()建立映射,则该函数的行为不确定。

It appears that Linux is more forgiving in this regard, and allows you to call mprotect() on whatever memory you want, more or less. 在这方面,Linux似乎更为宽容,它允许您或多或少在所需的任何内存上调用mprotect()。 Darwin is more strict, and requires you to use memory from mmap() if you want to call mprotect(). Darwin更为严格,如果要调用mprotect(),则要求您使用mmap()中的内存。 This is one of the reasons why it pays off to read the whole man page from start to finish. 这就是为什么从头到尾阅读整个手册页都值得的原因之一。

If you think about it, this is a reasonable requirement. 如果您考虑一下,这是一个合理的要求。 Memory given by valloc() is managed by the allocator and must be later returned to the allocator with free(), and mprotect() in a sense goes around the allocator's back and changes the way that the memory works. valloc()给定的内存由分配器管理,以后必须通过free()返回给分配器,并且mprotect()在某种意义上绕过了分配器的背面,并改变了内存的工作方式。 This is not the case for mmap() and munmap(), which are in the same family of system calls as mprotect(). mmap()和munmap()并非如此,它们与mprotect()在同一系列的系统调用中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在OSX High Sierra中正确设置网状包的Python路径? - How to properly set the Python path for the reticulate package in OSX High Sierra? 无法让Selenium Geckodriver在Python上运行-Mac OSX High Sierra - Unable to get Selenium Geckodriver to work on Python - Mac OSX High Sierra 在Mac OS 10.13(High Sierra)上导入pygame模块时遇到问题! - Having trouble importing pygame module on Mac OS 10.13(High Sierra)! 适用于 Python3 的 OSX HIDAPI 安装(pip3 故障排除):High-Sierra - OSX HIDAPI install for Python3 (pip3 troubleshooting): High-Sierra Python3:ModuleNotFoundError:在Mac OSX High Sierra v 10.13.3上没有名为“ coinbase”的模块 - Python3: ModuleNotFoundError: No module named 'coinbase' on Mac OSX High Sierra v 10.13.3 Python Selenium webdriver chromedriver“可能有错误的权限”(OSX 10.13) - Python Selenium webdriver chromedriver 'may have wrong permissions' (OSX 10.13) OSX High Sierra的工作目录中的空格字符问题 - Problems with a space character in my working directory in OSX High Sierra 命令'cc'在OSX High Sierra上以退出状态1失败 - command 'cc' failed with exit status 1 on OSX High Sierra python 导入文件时,php exec 失败 - php exec fails when python imports a file 在Mac OSX Sierra中安装python-igraph - Install python-igraph in Mac OSX Sierra
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM