使用mprotect使文本段在macOS上可写 [英] Using mprotect to make text segment writable on 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中配置登录一段时间(我有证书等),它也会因code object is not signed at all
失败.那么我应该怎么做呢?实际上,使用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).
最重要的是,由于macOS拒绝执行具有可写__TEXT(init_prot)
属性的文件,因此init_prot
不能设置为rwx
.
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
由于该代码段依赖于将__TEXT(max_prot)
偏移量硬编码为0xA0
,因此,作为替代方案,我创建了 ld
的直接替换/包装,它遵守segprot
的max_prot
参数.
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屋!