macos - Darwin 10.15 上的自修改代码导致 "malformed mach-o image"?

标签 macos dyld mach-o malformed self-modifying

我有一个生成自修改代码的程序(如果您感兴趣,请参阅 https://tigress.wtf/selfModify.html)。它在 x86 Darwin 和 Linux 上运行。在达尔文,我编译

gcc -g -segprot __TEXT rwx rwx self_modifying.c -o self_modifying.exe

最近,这似乎不起作用,我明白了
dyld: malformed mach-o image: __TEXT segment maps start of file but is writable

当我运行程序时。

我在 MacOS 10.15.3 上运行 clang 6.0.1 版。任何帮助,将不胜感激。

最佳答案

@AlexDenisov 非常接近,但该限制不仅适用于在 Catalina 上运行的最低 macOS 10.15.0 及更高版本的可执行文件。

Mach-O 加载命令有 2 种格式,指示可执行文件本身可以使用的最小 MacOS:
- LC_BUILD_VERSION (如果我没记错的话,新版本是在 10.14 左右引入的)
- LC_VERSION_MIN_MACOSX (遗产之一)

即使使用 LC_VERSION_MIN_MACOSX 回退到较旧的 MacOS 版本:

gcc -segprot __TEXT rwx rwx -mmacosx-version-min=10.6 self_modifying.c 

我们遇到了同样的问题。

绕过检查 我发现可行的一种解决方案是完全摆脱 min macos 版本。我不知道有任何 gccld可以实现这一目标的标志。幸运的是,我们可以在 Jonathan Levin 的 jtool2 的帮助下链接可执行文件后进行处理。

所以命令链变成:
gcc -segprot __TEXT rwx rwx self_modifying.c 
jtool2 -l a.out                             
    LC 00: LC_SEGMENT_64             Mem: 0x000000000-0x100000000   __PAGEZERO
    LC 01: LC_SEGMENT_64             Mem: 0x100000000-0x100001000   __TEXT
        Mem: 0x100000f60-0x100000f83        __TEXT.__text   (Normal)
        Mem: 0x100000f84-0x100000f8a        __TEXT.__stubs  (Symbol Stubs)
        Mem: 0x100000f8c-0x100000fa6        __TEXT.__stub_helper    (Normal)
        Mem: 0x100000fa6-0x100000fb2        __TEXT.__cstring    (C-String Literals)
        Mem: 0x100000fb4-0x100000ffc        __TEXT.__unwind_info    
    LC 02: LC_SEGMENT_64             Mem: 0x100001000-0x100002000   __DATA_CONST
        Mem: 0x100001000-0x100001008        __DATA_CONST.__got  (Non-Lazy Symbol Ptrs)
    LC 03: LC_SEGMENT_64             Mem: 0x100002000-0x100003000   __DATA
        Mem: 0x100002000-0x100002008        __DATA.__la_symbol_ptr  (Lazy Symbol Ptrs)
        Mem: 0x100002008-0x100002010        __DATA.__data   
    LC 04: LC_SEGMENT_64             Mem: 0x100003000-0x100004000   __LINKEDIT
    LC 05: LC_DYLD_INFO             
           Rebase info: 8     bytes at offset 12288 (0x3000-0x3008)
           Bind info:   24    bytes at offset 12296 (0x3008-0x3020)
        No Weak info
           Lazy info:   16    bytes at offset 12320 (0x3020-0x3030)
           Export info: 48    bytes at offset 12336 (0x3030-0x3060)
    LC 06: LC_SYMTAB                
    LC 07: LC_DYSYMTAB              
            1 local symbols at index     0
            2 external symbols at index  1
            2 undefined symbols at index 3
           No TOC
           No modtab
            3 Indirect symbols at offset 0x30b8
    LC 08: LC_LOAD_DYLINKER         /usr/lib/dyld
    LC 09: LC_UUID                  UUID: 6AE91487-DB61-3FA8-8DBE-686FEC1DA8FC
    LC 10: LC_BUILD_VERSION         Build Version:           Platform: MacOS 10.15.0 SDK: 10
    LC 11: LC_SOURCE_VERSION        Source Version:          0.0.0.0.0
    LC 12: LC_MAIN                  Entry Point:             0xf60 (Mem: 0x100000f60)
    LC 13: LC_LOAD_DYLIB            /usr/lib/libSystem.B.dylib
    LC 14: LC_FUNCTION_STARTS       Offset:     12384, Size:      8 (0x3060-0x3068)
    LC 15: LC_DATA_IN_CODE          Offset:     12392, Size:      0 (0x3068-0x3068)
jtool2 -rc 10 --inplace a.out

现在您的 a.out应该正确启动:-)

关于macos - Darwin 10.15 上的自修改代码导致 "malformed mach-o image"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60497896/

相关文章:

ios - iPhone 上的 Go 语言

python - OSX brew python "Could not find a version that satisfies the requirement pyopencv"

ruby - RVM 和 Ruby 2.1.1 的全新安装 - dyld 库/路径错误

c++ - 在 Mac OS X 上检索系统信息

macos - @loader_path解析到什么路径?

ios - LC_LOAD_DYLINKER 和 IOS 上的自定义链接器

objective-c - Apple Mach-O 链接器 (id) 错误 - 困惑?

c# - 无法启动服务挂载被拒绝 '/usr/local/share/dotnet/sdk/NuGetFallbackFolder\r\n' 不是来自 macos X 的共享并且 docker 不知道

objective-c - 如何在插入/拔出耳机时收到通知?苹果