Using mprotect to make text segment writable on macOS

后端 未结 1 1892
心在旅途
心在旅途 2020-12-11 06:45

This is essentially what I\'m trying to do,

#include 

int zero() {
    return 0;
}

int main(int argc, const char *argv[]) {
    return mp         


        
相关标签:
1条回答
  • 2020-12-11 07:14

    This is not a definitive answer, but it's a workaround.

    Your problem is caused by changes of the linker (ld64) in macOS Catalina. The default value of the max_prot attribute of the __TEXT segment in the Mach-O header has been changed.

    Previously max_prot default value was 0x7 (PROT_READ | PROT_WRITE | PROT_EXEC).
    The default value has now been changed to 0x5 (PROT_READ | PROT_EXEC).

    This means that mprotect cannot make any region that resides within __TEXT writable.

    In theory, this should be resolved by providing the linker flag -segprot __TEXT rwx rx, but this is not the case. Since Catalina, the max_prot field is ignored. Instead, max_prot is set to the value of init_prot (see here).

    To top it all off, init_prot cannot be set to rwx either due to macOS refusing to execute a file which has a writable __TEXT(init_prot) attribute.

    A brute workaround is to manually modify and set __TEXT(max_prot) to 0x7 after linking.

    printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc
    

    Since that code snippet relies on the __TEXT(max_prot) offset being hardcoded to 0xA0, as an alternative, I've created a drop-in replacement/wrapper for ld which respects the max_prot parameter of segprot.

    0 讨论(0)
提交回复
热议问题