7

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

#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并设置errnoEACCES,据我所知,这是因为缺乏权利/代码签名。我找到了我需要设置的权利,但我不知道如何去做,也不知道如何实际签署它..

如果我运行codesign -d --entitlements :- <path_to_app>,它会失败code object is not signed at all,即使我已经尝试在 Xcode 中配置登录一段时间(我有证书等等)。那么我该怎么做呢?实际上用 Xcode 签名并不明显,所以我相当无能。

4

1 回答 1

6

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

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

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

这意味着mprotect不能使驻留在其中的任何区域__TEXT可写。

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

最重要的是,由于 macOS 拒绝执行具有可写属性的文件,init_prot因此无法设置为任一。rwx__TEXT(init_prot)

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

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

由于该代码片段依赖于__TEXT(max_prot)硬编码为 的偏移量0xA0,因此作为替代方案,我创建了一个插入式替换/包装器,它ld尊重max_prot.segprot

于 2020-05-20T23:03:29.450 回答