XNU:在 kext 中获取进程启动和清理通知

XNU: getting process startup and cleanup notifications in kext

在内核扩展中启动和退出进程时获得通知的最佳方式是什么?

我知道我可以使用 KAuth 订阅流程创建 (KAUTH_VNODE_EXECUTE)。订阅进程清理怎么样?

KAUTH_VNODE_EXECUTE 对所有进程来说都不够;这不会捕获没有 exec() 的 fork()ed 进程。在 OSX 上相当罕见,但并非闻所未闻。至少有一个 fork 的 MAC 框架策略回调,尽管 MAC (com.apple.kpi.dsep) 被标记为不受 Apple 支持,并且主要 OS X 版本之间的 ABI 更改是常见。

除了定期遍历您自己的进程列表、查找 proc_t 中有问题的 PID 并检查它是否仍然存在之外,我不知道有什么可以关闭的。当然,如果检测到具有回收 PID 的新进程,则也意味着先前具有相同 PID 的进程已经死亡。如果您有关于相关进程的额外信息,您可能能够从其他事件中推断出进程死亡。

还有一种方法可以在退出时监视进程。 您可以使用内核事件通知机制 (kevent),它是 freeBSD 的一部分,受 OS X 支持。

流程从进程启动开始(您可以使用 kauth 或 mac 框架方法捕获)。在回调函数中,您需要注册适当的事件以便稍后监视。这是通过使用 EV_SET 和以下参数设置 kevent 实例来完成的:

kevent.ident = pid
kevent.filter = EVFLT_PROC
kevent.flags = EV_ADD
kevent.fflags = NOTE_EXIT

在代码中应该如下所示:

EV_SET(&ke, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
kevent(kq, &ke, 1, NULL, 0, NULL);  // registration of ke to kqueue represented by kq descriptor. 

最后,您将需要另一个线程来监听这些事件并在时间到了(进程退出)时捕获它们,再次使用 kevent 命令。

err = kevent(kq, NULL, 0, &ke, 1, NULL);
if (err == -1)
   err(1, "error in catching the event");

if (ke.fflags & NOTE_EXIT)
    printf("this is what you need ..."); 

更多详情您可以查看以下内容doc