使用mprotect使文本段在macOS上可写



这基本上就是我要做的,

#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创建了一个包含segprotmax_prot参数的插入式替换/包装器。

相关内容

  • 没有找到相关文章

最新更新