这基本上就是我要做的,
#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
,据我所知,这是因为缺乏授权/代码签名。我已经找到了我需要设定的权利,但我不知道如何进行,也不知道如何真正签署。
如果我运行codesign -d --entitlements :- <path_to_app>
,它会以code object is not signed at all
失败,尽管我已经尝试在Xcode中配置签名一段时间了(我有证书等等(。那么我该怎么做呢?事实上,用Xcode签名并不明显,所以我相当无知。
这不是一个明确的答案,但它是一个变通方法。
您的问题是由macOS Catalina中的链接器(ld64(更改引起的。Mach-O头中__TEXT
段的max_prot
属性的默认值已更改。
以前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拒绝执行具有可写__TEXT(init_prot)
属性的文件,init_prot
也不能设置为rwx
。
一种暴力解决方法是在链接后手动修改__TEXT(max_prot)
并将其设置为0x7
。
printf 'x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc
由于该代码片段依赖于将__TEXT(max_prot)
偏移量硬编码为0xA0
,因此,作为一种替代方案,我为ld
创建了一个包含segprot
的max_prot
参数的插入式替换/包装器。