I am trying to write kext for Mac OS X which will get notified when any process is started.
In Windows you can do this by calling PsSetLoadImageNotifyRoutine(...) and specify callback which will be called when the process is starting. This is documented way and it works in all Windows starting from Win 2k.
Is there anything similar for Mac? It seems like this is possible to achieve using kauth process listeners, but process scope has never been implemented in OS X.
Another alternative is to hook SYS_execve and friends, but this is undocumented and unsupported way. I really don't want to go this way.
I don't need any cancelling - just want to be notified when process is started, and get it's pid & path.
Well, your question is a bit ambiguous.
Being "notified when any process is started" IMHO means the fork
syscall, not execve
. However I have no idea if you can be notified on fork
by any official API.
If the execve
is what you are interested in, take a look at the kernel authorization (kauth) API.
You can register in KAUTH_SCOPE_VNODE
and track for KAUTH_VNODE_EXECUTE
to be notified before the execve performs (and possibly deny it to succeed by return value from your callback); or register in KAUTH_SCOPE_FILEOP
and track for KAUTH_FILEOP_EXEC
to be notified after the execve()
is performed.
Old question - but - The answer stating SYS_execve hooking is the only way to be notified is incorrect and dangerous. For one, the sysent table is not exported (though arguably it can be found fairly easily). For two, you have to patch the memory and ensure it's rw.
A MUCH better way, in a kext, is to use the MAC framework (that would be Mandatory Access Control). That's in the XNU sources, in the /security branch. The MAC Framework was designed for exactly this kind of operations - i.e. notifications/hooking without actual function or address overwrite, but with callouts. This is also detailed in a book titled "Mac OS X and iOS Internals", Chapter 14.
SYS_execve hooking is only way to be notified when any process is started.
Also, you could try to use DTrace and libdtrace for receiving process started notification; I've been trying that way but without success.
Here's an example using the MAC and KAUTH.
https://www.synack.com/2015/11/17/monitoring-process-creation-via-the-kernel-part-i/