【发布时间】:2020-05-28 01:30:20
【问题描述】:
我想在 MacOS Catalina(64 位)上创建一个二进制文件,其中包含一个可执行的数据段(有关详细信息,请参阅 here),但从一开始就无法执行。
我用
制作我的二进制文件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
.
.
.
我有什么遗漏吗?达尔文文档here 说:
-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。
任何指针都会很棒,在此先感谢。
【问题讨论】:
-
注意我尝试使用 gcc 编译并显式调用 apple clang 链接器 (ld),结果相同。 x64 链接器是否可能改变了 segprot 行为?
-
这是由于 macOS Catalina 中引入的更改。您正在查看 ld64 的过时版本。你可以看到
max_prot在这里设置了init_prot:github.com/apple-opensource/ld64/blob/… -
天哪,你是对的——我误读了这段代码。如果这种改变是故意的,你有什么见解吗?这可能是无意的,因为手册页仍然明确指出 ld 可以接受 maxprot 和 initprot。
-
如果您有兴趣,我已经编写了一个 Python 脚本,可以直接替换
ld。它包装ld并在链接后从任何segprot参数应用max_prot:gist.github.com/darfink/a756b88e999631d75cbbeefd3eee7e2d
标签: 64-bit ld macos-catalina darwin