使用 mprotect 使文本段在 macOS 上可写 [英] Using mprotect to make text segment writable on macOS

查看:17
本文介绍了使用 mprotect 使文本段在 macOS 上可写的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这基本上就是我想要做的,

This is essentially what I'm trying to do,

#include <sys/mman.h>

int zero() {
    return 0;
}

int main(int argc, const char *argv[]) {
    return mprotect((void *) &zero, 4096, PROT_READ | PROT_WRITE);
}

所以我试图使代码可写,本质上.这在当前的 macOS (Catalina 10.15.2) 上不起作用,它只返回 -1 并将 errno 设置为 EACCES,即据我所知是因为缺乏权利/代码签名.我找到了我需要设置的权利,但我不知道如何去做,也不知道如何实际签署..

so I'm trying to make code writable, essentially. This doesn't work on the current macOS (Catalina 10.15.2), it just returns -1 and sets errno to EACCES, which as far as I know is because of lack of entitlement/code signing. I've found the entitlement I need to set, but I have no idea how to go about that, nor how to actually sign it..

如果我运行 codesign -d --entitlements :- <path_to_app>,它会失败,代码对象根本没有签名,即使我已经尝试过配置在 Xcode 中签名一段时间(我有一个证书等等).那么我应该怎么做呢?实际上,使用 Xcode 签署它并不明显,所以我相当无能为力.

If I run codesign -d --entitlements :- <path_to_app>, it fails with code object is not signed at all, even though I've tried configuring signing in Xcode for a while (I have a certificate and so on). So how should I go about this? Actually signing it isn't obvious with Xcode, so I'm fairly clueless.

推荐答案

这不是一个确定的答案,但它是一种解决方法.

This is not a definitive answer, but it's a workaround.

您的问题是由 macOS Catalina 中链接器 (ld64) 的更改引起的.Mach-O 标头中 __TEXT 段的 max_prot 属性的默认值已更改.

Your problem is caused by changes of the linker (ld64) in macOS Catalina. The default value of the max_prot attribute of the __TEXT segment in the Mach-O header has been changed.

以前 max_prot 默认值为 0x7 (PROT_READ | PROT_WRITE | PROT_EXEC).
默认值现已更改为 0x5 (PROT_READ | PROT_EXEC).

Previously max_prot default value was 0x7 (PROT_READ | PROT_WRITE | PROT_EXEC).
The default value has now been changed to 0x5 (PROT_READ | PROT_EXEC).

这意味着 mprotect 不能使位于 __TEXT 内的任何区域可写.

This means that mprotect cannot make any region that resides within __TEXT writable.

理论上,这应该通过提供链接器标志-segprot __TEXT rwx rx 来解决,但事实并非如此.从 Catalina 开始,max_prot 字段被忽略.相反,max_prot 设置为 init_prot 的值(参见 此处).

In theory, this should be resolved by providing the linker flag -segprot __TEXT rwx rx, but this is not the case. Since Catalina, the max_prot field is ignored. Instead, max_prot is set to the value of init_prot (see here).

最重要的是,init_prot 不能设置为 rwx 要么是因为 macOS 拒绝执行具有可写 __TEXT(init_prot) 属性.

To top it all off, init_prot cannot be set to rwx either due to macOS refusing to execute a file which has a writable __TEXT(init_prot) attribute.

一个粗暴的解决方法是在链接后手动修改并将__TEXT(max_prot)设置为0x7.

A brute workaround is to manually modify and set __TEXT(max_prot) to 0x7 after linking.

printf 'x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc

由于该代码片段依赖于硬编码到 0xA0__TEXT(max_prot) 偏移量,作为替代,我创建了一个 插入式替换/包装器 用于 ld 尊重 max_prot 参数segprot.

Since that code snippet relies on the __TEXT(max_prot) offset being hardcoded to 0xA0, as an alternative, I've created a drop-in replacement/wrapper for ld which respects the max_prot parameter of segprot.

这篇关于使用 mprotect 使文本段在 macOS 上可写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆