【问题标题】:Get process creation notification in Mac OS X在 Mac OS X 中获取进程创建通知
【发布时间】:2011-11-23 22:27:32
【问题描述】:

我正在尝试为 Mac OS X 编写 kext,它会在任何进程启动时得到通知。

在 Windows 中,您可以通过调用 PsSetLoadImageNotifyRoutine(...) 来执行此操作,并指定将在进程启动时调用的回调。这是记录在案的方式,它适用于从 Win 2k 开始的所有 Windows。

Mac 有类似的东西吗?使用 kauth 进程侦听器似乎可以实现这一点,但进程范围从未在 OS X 中实现。

另一种选择是挂钩 SYS_execve 和朋友,但这是未记录且不受支持的方式。我真的不想走这条路。

我不需要任何取消 - 只想在进程启动时收到通知,并获取它的 pid 和路径。

【问题讨论】:

    标签: macos hook kernel-extension


    【解决方案1】:

    嗯,你的问题有点模棱两可。

    “在任何进程启动时收到通知”恕我直言,这意味着 fork 系统调用,而不是 execve。但是我不知道您是否可以通过任何官方 API 在fork 上收到通知。

    如果您对execve 感兴趣,请查看kernel authorization (kauth) API

    您可以在KAUTH_SCOPE_VNODE 中注册并跟踪KAUTH_VNODE_EXECUTE,以便在 execve 执行之前得到通知(并可能通过回调的返回值拒绝它成功);或在KAUTH_SCOPE_FILEOP注册并跟踪KAUTH_FILEOP_EXEC,以便在execve()执行后得到通知。

    【讨论】:

    • 这是一个很好的信息!我刚试过,它有效。但是,这仅适用于进程启动事件。如何获取进程退出事件?
    • 这种方式不能正常工作。正如我之前所说,最好为任务设置挂钩。
    【解决方案2】:

    老问题 - 但是 - 说明 SYS_execve 挂钩是唯一得到通知的方法的答案是不正确且危险的。一方面,没有导出 sysent 表(尽管可以说它很容易找到)。对于两个,您必须修补内存并确保它是 rw。

    在 kext 中,更好的方法是使用 MAC 框架(即强制访问控制)。那是在 XNU 源代码中的 /security 分支中。 MAC 框架专为此类操作而设计 - 即没有实际功能或地址覆盖但带有标注的通知/挂钩。这在名为“Mac OS X 和 iOS 内部原理”的书第 14 章中也有详细说明。

    【讨论】:

      【解决方案3】:

      对于 2019 年之后发现此问题的任何人:

      Apple 有一个相对较新的 (macOS 10.15+) C 框架,称为 Endpoint Security,它提供进程生命周期事件(除其他外),可以由用户模式守护进程或新的“系统扩展”(继任者)使用到“内核扩展”),前提是从 Apple 获得适当的代码签名权利。一些显着的特点是:

      • 高效/事件驱动模型 (es_new_client())
      • 精细事件类型订阅模型(例如ES_EVENT_TYPE_NOTIFY_EXECES_EVENT_TYPE_NOTIFY_FORKES_EVENT_TYPE_NOTIFY_EXIT 通过es_subscribe()
      • 丰富的事件上下文,包括 piduid 等(例如,用于创建流程的事件消息 (es_event_exec_t) 包含一个 es_process_t 字段,其中包含流程详细信息,包括可执行路径)
      • 可以根据源(父)进程(例如es_mute_process())对事件进行“静音”(屏蔽),以帮助解决信号对噪声和性能的影响。

      Apple 一段时间以来一直在推动开发人员采用这个新框架,以支持以前的监控 API(如 KAUTHMACOpenBSM (/dev/auditpipe)),所以这是我可以推荐的唯一解决方案投资于未来。

      有一些关于该主题的 WWDC 会议和示例项目:https://developer.apple.com/documentation/endpointsecurity/monitoring_system_events_with_endpoint_security

      【讨论】:

        【解决方案4】:

        SYS_execve 挂钩是在任何进程启动时得到通知的唯一方法。 此外,您可以尝试使用 DTrace 和 libdtrace 来接收进程启动通知;我一直在尝试这种方式,但没有成功。

        【讨论】:

        • 你好Александр。谢谢回复。我不认为挂钩 SYS_execve 是一个正确的选择,因为我的 kext 将被大多数防病毒软件标记为 rootkit。这种方法似乎很不稳定,因为定位 sysent 表可能很棘手。此外,使用 libdtrace 似乎不是一个好主意,主要是因为接口可能会改变,所以我将不得不重新编译我的代码。我想知道,我可以在用户模式应用程序中获得有关进程开始/结束的通知吗?我想知道,大多数防病毒软件如何在 Mac OS 中发挥作用?挂钩系统调用?
        • 您无法在用户模式应用程序中获得有关进程开始/结束的通知。防病毒软件正在挂钩系统调用。如果时间延迟对您来说不重要,您可以使用this information
        【解决方案5】:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-02-02
          • 2012-07-17
          • 1970-01-01
          • 2014-10-11
          • 2012-04-25
          • 2011-02-04
          • 1970-01-01
          • 2018-12-15
          相关资源
          最近更新 更多