我想在MacOS Catalina(64位)上创建一个二进制文件,其中的数据段可以被执行(见 此处 了解详情),但从一开始就无法执行。
我将我的二进制文件用
gcc -nostdlib -segprot __DATA rwx rw- ....
我还用gcc创建了一个对象文件,然后直接调用ld。ld的版本是
$ ld -v
@(#)PROGRAM:ld PROJECT:ld64-530
BUILD 18:57:17 Dec 13 2019
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 11.0.0, (clang-1100.0.33.17) (static support for 23, runtime is 23)
TAPI support using: Apple TAPI version 11.0.0 (tapi-1100.0.11)
那 应 使数据段的初始权限为RW,但允许我使用mprotect将该段的权限扩展到RWX。
然而,我注意到 __DATA 段的初始和最大权限都是 RW。
$ otool -l jonesforth
.
.
.
Load command 2
cmd LC_SEGMENT_64
cmdsize 312
segname __DATA
vmaddr 0x0000000100001000
vmsize 0x0000000000024000
fileoff 4096
filesize 4096
maxprot 0x00000003
initprot 0x00000003
nsects 3
flags 0x0
Section
.
.
.
我是不是漏掉了什么?在darwin文档中 此处 说。
-segprot name max init (32-bit only)
Specifies the maximum and initial virtual memory protection of
the named segment, name, to be max and init ,respectively. The
values for max and init are any combination of the characters
`r' (for read), `w' (for write), `x' (for execute) and '-' (no
access). The default is `rwx' for the maximum protection for
all segments for PowerPC architecures and `rw` for the all Intel
architecures. The default for the initial protection for all
segments is `rw' unless the segment contains a section which
contains some machine instructions, in which case the default
for the initial protection is `rwx' (and for Intel architecures
it also sets the maximum protection to `rwx' in this case). The
default for the initial protection for the ``__TEXT'' segment is
`rx' (not writable).
当然,这是darwin(仅32位)的文档,但这是我唯一找到的东西. 我怀疑要么是gcc不 "正确 "支持darwin保护语法,要么是它坏了,要么是darwin的东西从x86改成x64了。
如果有任何提示就更好了,先谢谢了。
是的,3月18日确实发生了一些事情。
苹果公司 承诺 这使得 ld 总是为非 i386 架构设置 maxprot = initprot,所以包括 x64,即 Catalina。目前还不清楚这是否是有意为之,它与 ld 的手册不一致。
当然,一个变通的办法是在initprot中为整个段设置所需的保护级别。如果想有更精细的控制,也许可以将所需的数据代码移到一个单独的段中。
另一个变通方法是,感谢来自 Darfink: 人们也可以在ld运行后改变链接器或修改所需的maxprot。Darfink指出,他的 ld64包装器,一个python脚本。,以实现自动化。