达尔文10.15上的自修改代码会导致“格式错误的mach-o图像"? [英] Self-modifying code on Darwin 10.15 resulting in "malformed mach-o image"?

查看:178
本文介绍了达尔文10.15上的自修改代码会导致“格式错误的mach-o图像"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序可以生成自我修改的代码(请参见 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上运行6.0.1版的clang.任何帮助将不胜感激.

解决方案

@AlexDenisov非常接近,但该限制并不只适用于运行Mac OS 10.15.0及更高版本的Catalina上的可执行文件.

Mach-O load命令有两种格式,它们指示可执行文件本身可以使用的最小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 

我们遇到了同样的问题.

绕过支票,我发现可以使用的一种解决方案是完全放弃最低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应该可以正确启动:-)

I have a program that generates self-modifying code (see https://tigress.wtf/selfModify.html in case you're interested). It runs on x86 Darwin and Linux. On Darwin, I compile with

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

Recently, this seems not to work, I get

dyld: malformed mach-o image: __TEXT segment maps start of file but is writable

when I run the program.

I'm running clang version 6.0.1 on MacOS 10.15.3. Any help would be appreciated.

解决方案

@AlexDenisov is pretty close, but the restriction does not apply only to executables running on Catalina with min macOS 10.15.0 and higher.

There are 2 formats of Mach-O load command that indicate the min MacOS the executable itself can use:
- LC_BUILD_VERSION(the new one introduced around 10.14 if I recall correctly)
- LC_VERSION_MIN_MACOSX (the legacy one)

Even with fallbacking to older MacOS version using LC_VERSION_MIN_MACOSX:

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

we run into the same problem.

To bypass the check one solution I found to work is to get rid of min macos version altogether. I'm not aware though of any gcc or ld flag that can achieve this. Fortunately we can do the processing after linking the executable with the help of Jonathan Levin's jtool2

So the chain of commands become:

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

Now your a.out should launch correctly :-)

这篇关于达尔文10.15上的自修改代码会导致“格式错误的mach-o图像"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆