【问题标题】:ld64 segprot on MacOS Catalina not working?MacOS Catalina 上的 ld64 segprot 不工作?
【发布时间】: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 行为?
  • 查看thisthis 确实看起来保护设置正确......但它们不是......
  • 这是由于 macOS Catalina 中引入的更改。您正在查看 ld64 的过时版本。你可以看到max_prot在这里设置了init_protgithub.com/apple-opensource/ld64/blob/…
  • 天哪,你是对的——我误读了这段代码。如果这种改变是故意的,你有什么见解吗?这可能是无意的,因为手册页仍然明确指出 ld 可以接受 maxprot 和 initprot。
  • 如果您有兴趣,我已经编写了一个 Python 脚本,可以直接替换 ld。它包装ld 并在链接后从任何segprot 参数应用max_protgist.github.com/darfink/a756b88e999631d75cbbeefd3eee7e2d

标签: 64-bit ld macos-catalina darwin


【解决方案1】:

是的,3 月 18 日确实发生了一些事情:

Apple committed a change 使 ld 始终为非 i386 架构设置 maxprot = initprot,因此包括 x64,即 Catalina。目前还不清楚这是否是故意的,这与 ld 手册页不一致。

一种解决方法当然是在 initprot 中为整个段设置所需的保护级别。如果想要进行更精细的控制,可以将所需的数据/代码移动到单独的段中。

另一种解决方法,感谢Darfink 的评论:也可以在 ld 运行后更改链接器或修改所需的 maxprot。 Darfink 指出了他的ld64 wrapper, a python script,以自动执行此操作。

【讨论】:

    猜你喜欢
    • 2020-02-04
    • 2020-02-17
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    相关资源
    最近更新 更多