I used to be able to use mach_override to hook any exported function on Mac OS including Catalina. However, now the target app crashed every time and I check the Console and find the following error:
CODE SIGNING: 30911[app] vm_map_protect can't have both write and exec at the same time
What's going on and is that possible I can bypass it without touching the target app's signature?
The hardened runtime is designed specifically to prevent that sort of hooking. The target app's entitlements would have to opt-in to allowing it. If you find a way around it, Apple would consider that a security hole bug and patch it in a future OS release.
It should work if you disable System Integrity Protection, but I don't know if that suits your purpose.
Related
I'm writing a macOS launch daemon (in C++). It works for the most part, except that I am noticing some random crashes via SIGABRT (in the log.)
I've asked earlier about the use of the Core Graphics framework, which it turns out was not allowed in a launch daemon. I removed it, but I still get very rare crashes.
Thus I'm wondering which of the following frameworks am I allowed to use from a launch daemon?
There's no technical restriction on specific frameworks you're allowed or not allowed to link. Merely linking a library will not cause crashes. Some APIs need to be called from specific contexts, such as much of Core Graphics only making sense if a process is part of a windowing session, as you've found out. But even there, some of the off-screen drawing APIs which don't interface with the windowing system directly ought to work from a Launch Daemon context.
If you're seeing crashes calling specific APIs, you'll need to investigate those one by one. If you're seeing "random" crashes, I suspect you have a bug (memory overwrite? multithreading error?) in your code. Note that Apple's toolchain provides a bunch of different diagnostic options which you can use even when not running in the debugger, such as ASan, UBSan, and Thread Sanitizer. These may help you track down issues.
As you've specifically tagged this question with the IOKit tag and it's shown in your screenshot, I'll add that using IOKit from a launch daemon is very common. It's even possible to use IOKit matching events as a launch trigger for the daemon using XPC events/xpc_set_event_stream_handler - this way, your daemon can be started on-demand when a specific (type of) device is connected, for example. (As opposed to starting up at every system boot and consuming system resources even if it's not needed or doing anything.)
I have a small project which implements function hooking in MAC using mach_override() by Jonathan 'Wolf' Rentzsch:https://github.com/rentzsch/mach_override
I have hooked one of the functions of kextstat process from mac.
So when I am executing
$kextstat
OSX is killing this process saying below error:
CODE SIGNING: process 2211[kextstat]: rejecting invalid page at
address 0x7fff5132d000 from offset 0xca53000 in file
"/private/var/db/dyld/dyld_shared_cache_x86_64h"
(cs_mtime:1531207073.366350606 == mtime:1531207073.366350606)
(signed:0 validated:0 tainted:0 nx:0 wpmapped:1 dirty:1 depth:2)
my dynamic library is code-signed.
In my initial observation, i could conclude that mach_override() function in failing in following code:
atomic_mov64((uint64_t *)originalFunctionPtr,
jumpRelativeInstruction);
above code could be found : mach_override.c:342
https://github.com/rentzsch/mach_override
Firstly, you should note that public discussion of Apple's Developer Beta software is a breach of Apple's terms and conditions. Such questions should be posted to Apple's forums, which has a specific section for Beta releases.
That being said, the technology and problem you're seeing is SIP, which includes denial of code injection, as well as protecting system files from being overwritten. The detail that follows is nothing new and exists in pre 10.14 macOS builds, though disabled (by default) in those versions.
When an application is signed, it creates a hash of each file page in the binary, and a super hash of all those hashes. During execution of a binary, when a page fault occurs, or a file (e.g. dylib) is mmap'd into the executing process, amfid (Apple Mobile File Integrity daemon) verifies that the new code is signed and that its signature matches that of the executing binary. If the signature or hashes do not match, then the code is denied loading, or in some cases, the process is killed.
In this case, kextstat contains an Apple certificate that does not match the certificate of your code that you're attempting to inject into kextstat. In addition, the certificate of kexstat includes the platform binary flag, which Developer certificates do not have.
Without a zero-day vulnerability, you're not going to be able to hook kextstat in a commercial environment. If it's just research you want to do, then you can either disable SIP, or remove the signature from the kextstat binary, causing amfid to ignore the certificate verification.
I've written a plugin for finder on Mac(mountain lion) and it works perfectly, but I have to run the bundle with sudo. Then I make a package(Packagemaker) to run this bundle and it failed(install correctly and if I run it by clicking desktop icon it failed, if run though commandline with sudo, it works).
Does anybody know how to fix this issue just like installing dropbox (and then sync icon shows)
The problem you're facing is that, internally, mach_inject calls the function task_for_pid.
This function returns the kernel task id for the given process pid and due to security reasons, Apple now requires that use of this function can only take place from users that are members of either the root or procmod groups. This explains why running sudo works for you.
If you're just developing this for just your own use, the simplest method is to add yourself to the procmod group. However, if you want to distribute the application, you'll need to ensure that any installer installs the program to run as a member of the root or procmod groups.
One possibility is to separate your application into two parts, where the second is registered to run with elevated privileges using SMJobBless. If you don't program in Objective-C, don't worry as the actually parts of SMJobBless that are required are just C function calls; look for AuthorizationCopyRights and SMJobBless in the given example code.
Alternatively, if the application is code-signed, that should work too, though it's not something I've tried myself. You can read about that here.
As of OS X 10.11 (El Capitan), task_for_pid is an entitled function call, only available to software with a specific entitlement in its certificate and no longer available to 3rd party developers.
This breaks mach_inject, making it harder to retrieve another process's mach task, whilst SIP (System Integrity Projection) is enabled.
I'd like save a kext setting between OS restarts. As I need the settings after kext been loaded immediately, I can not wait for managing daemon start up. Is it a way for reading/writing kext plist file from kext or some other ways to do that?
Basically, no - you're supposed to store settings in userspace and use a launchd service to set them in the kext. Until your kext receives the settings, it should just use some sane defaults.
One way to truly include settings on kext startup is to add custom attributes to the IOKitPersonality in your kext's info.plist. Obviously, this means that changing settings requires changing the kext itself, but I have heard reports of people actually doing this on Apple's public darwin mailing lists (although Apple employees pitched in to criticise it). Note that the kext cache will not like this: If your userspace program changes settings in the info.plist, it will probably need to increase the bundle version number in order for the kext cache to pick up the change, otherwise the cached/prelinked kext won't see the change. You need to do this within the constraints of the rules for kext bundle versions or it won't be detected as a version increase, or worse, the kext cache will reject the kext outright. Also, don't forget to touch /System/Library/Extensions/ after updating kexts.
Update: modifying a kext's info.plist will no longer work in 10.9 and 10.10 due to the kext signing requirement.
In the specific case where your kext is a storage filter scheme, you can store your settings in a special "super block" of the provider partition. AppleRAID (which is open source) does this, for example. This isn't practical for any other kind of kext, though.
I am writing a MailStatistics app that need to go to the file ~/Library/Mail/Envelop Index to get the mail information. My app does not write anything into the file system but when I submitted it to the Apple Store, the app gets rejected because: "Apps that do not comply with the Mac OS X File System documentation will be rejected"
Does anyone know all possible reasons that can lead to this specific rejection
I think I know the problem, it may be because I set the mode to become READWRITE instead of READONLY. I changed it back and hope that Apple will accept it this time