简体   繁体   English

在 Mac OS X 中获取进程创建通知

[英]Get process creation notification in Mac OS X

I am trying to write kext for Mac OS X which will get notified when any process is started.我正在尝试为 Mac OS X 编写 kext,它会在任何进程启动时收到通知。

In Windows you can do this by calling PsSetLoadImageNotifyRoutine(...) and specify callback which will be called when the process is starting.在 Windows 中,您可以通过调用 PsSetLoadImageNotifyRoutine(...) 并指定将在进程启动时调用的回调来完成此操作。 This is documented way and it works in all Windows starting from Win 2k.这是记录的方式,它适用于从 Win 2k 开始的所有 Windows。

Is there anything similar for Mac? Mac 上有类似的吗? It seems like this is possible to achieve using kauth process listeners, but process scope has never been implemented in OS X.使用 kauth 进程侦听器似乎可以实现这一点,但是 OS X 中从未实现过进程范围。

Another alternative is to hook SYS_execve and friends, but this is undocumented and unsupported way.另一种选择是挂钩 SYS_execve 和朋友,但这是未记录且不受支持的方式。 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.我不需要任何取消 - 只想在进程启动时收到通知,并获取它的 pid 和路径。

Well, your question is a bit ambiguous.嗯,你的问题有点模棱两可。

Being "notified when any process is started" IMHO means the fork syscall, not execve .被“在任何进程启动时通知”恕我直言意味着fork系统调用,而不是execve However I have no idea if you can be notified on fork by any official API.但是,我不知道您是否可以通过任何官方 API 在fork上收到通知。

If the execve is what you are interested in, take a look at the kernel authorization (kauth) API .如果您对execve感兴趣,请查看内核授权 (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);您可以在KAUTH_SCOPE_VNODE中注册并跟踪在 execve 执行之前通知KAUTH_VNODE_EXECUTE (并且可能通过回调的返回值拒绝它成功); or register in KAUTH_SCOPE_FILEOP and track for KAUTH_FILEOP_EXEC to be notified after the execve() is performed.或在KAUTH_SCOPE_FILEOP注册并跟踪在执行execve()后要通知的KAUTH_FILEOP_EXEC

Old question - but - The answer stating SYS_execve hooking is the only way to be notified is incorrect and dangerous.老问题 - 但是 - 说明 SYS_execve hooking 是唯一得到通知的方法的答案是不正确和危险的。 For one, the sysent table is not exported (though arguably it can be found fairly easily).一方面,sysent 表没有导出(尽管可以说它很容易找到)。 For two, you have to patch the memory and ensure it's rw.对于两个,您必须修补内存并确保它是 rw。

A MUCH better way, in a kext, is to use the MAC framework (that would be Mandatory Access Control).在 kext 中,更好的方法是使用 MAC 框架(即强制访问控制)。 That's in the XNU sources, in the /security branch.这是在 XNU 源代码中的 /security 分支中。 The MAC Framework was designed for exactly this kind of operations - ie notifications/hooking without actual function or address overwrite, but with callouts. MAC 框架正是为这种操作而设计的——即没有实际功能或地址覆盖的通知/挂钩,但带有标注。 This is also detailed in a book titled "Mac OS X and iOS Internals", Chapter 14.这也在一本名为“Mac OS X and iOS Internals”的书的第 14 章中有详细介绍。

For anyone finding this question after 2019:对于 2019 年后发现此问题的任何人:

Apple has a relatively new (macOS 10.15+) C framework called Endpoint Security which provides process lifecycle events (among other things) and can be consumed either by a user mode daemon or a new "System Extension" (successor to the "Kernel Extension") provided the proper code signing entitlements are secured from Apple. Apple 有一个相对较新的 (macOS 10.15+) C框架,称为Endpoint Security ,它提供进程生命周期事件(除其他外)并且可以由用户模式守护程序或新的“系统扩展”(“内核扩展”的后继者)使用) 前提是从 Apple 获得了适当的代码签名权利。 Some notable features are:一些显着的特点是:

  • Efficient / Event-driven model ( es_new_client() )高效/事件驱动模型( es_new_client()
  • Granular event type subscription model (eg ES_EVENT_TYPE_NOTIFY_EXEC , ES_EVENT_TYPE_NOTIFY_FORK , ES_EVENT_TYPE_NOTIFY_EXIT via es_subscribe() )粒度事件类型订阅模型(例如ES_EVENT_TYPE_NOTIFY_EXECES_EVENT_TYPE_NOTIFY_FORKES_EVENT_TYPE_NOTIFY_EXIT通过es_subscribe()
  • rich event context including pid , uid , and much more (eg An event message for process creation ( es_event_exec_t ) includes an es_process_t field with process details including executable path)丰富的事件上下文,包括piduid等等(例如,进程创建的事件消息( es_event_exec_t )包括一个es_process_t字段,其中包含进程详细信息,包括可执行路径)
  • Events can be 'muted' (masked) based on source (parent) process (eg es_mute_process() ) to help with signal v. noise and performance impact.可以根据源(父)进程(例如es_mute_process() )“静音”(屏蔽)事件,以帮助处理信号与噪声和性能影响。

Apple has been pushing developers to adopt this new framework for a while now in favor of previous monitoring APIs (like KAUTH , MAC and OpenBSM ( /dev/auditpipe )) so it's the only solution I can recommend investing in going forward.一段时间以来,Apple 一直在推动开发人员采用这种新框架,以支持以前的监控 API(如KAUTHMACOpenBSM ( /dev/auditpipe )),因此这是我可以推荐投资的唯一解决方案。

There are some WWDC sessions and example projects available on the subject: https://developer.apple.com/documentation/endpointsecurity/monitoring_system_events_with_endpoint_security有一些关于该主题的 WWDC 会议和示例项目: https : //developer.apple.com/documentation/endpointsecurity/monitoring_system_events_with_endpoint_security

SYS_execve hooking is only way to be notified when any process is started. SYS_execve 挂钩是在任何进程启动时收到通知的唯一方式。 Also, you could try to use DTrace and libdtrace for receiving process started notification;此外,您可以尝试使用 DTrace 和 libdtrace 来接收进程启动通知; I've been trying that way but without success.我一直在尝试这种方式,但没有成功。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM