Now we want to use the system call of `
mprotect
` to access and execute any function in dynamic way. It is really usage in hot patching running process. Normaly, we use `
mprotect
` with flags like `PROT_WRITE` or `PROT_READ` and it should work in Linux and MacOS(before Catalina).
Recently we found that `
mprotect
` with `PROT_WRITE` will fail and return zero even throught we have grant the priviledges to the process. It may be the security issue so we disable the csrutil and codesign with almost all the entitlements before testing but it still fail.
Here are the related discussion: https://github.com/flutter/flutter/issues/36714https://github.com/agiledragon/gomonkey/issues/10https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos
https://github.com/flutter/flutter/issues/36714
Right, so you’re modifying
__TEXT
sections.
I have concerns about the long-term sustainability of this approach. macOS is evolving so that all code on the system must be signed, and changing code in memory will break its code signature. There are limited circumstances under which doing this is fine, for example, the debugger does this whenever it needs to set a breakpoint. However, I must emphasise the limited circumstances. Doing this in a debugger or development tool is fine. I’d be much more concerned if you planned to ship a system based on this technology to users.
Speaking of debuggers, the way that LLDB does this without monkeying with your segment protections is by way of
VM_PROT_COPY
. The header has this to say about its behaviour:
When a caller finds that it cannot obtain write permission on a mapped entry, the following flag can be used. The entry will be made “needs copy” effectively copying the object (using COW), and write permission will be added to the maximum protections for the associated entry.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"