且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

从OSX 10.10/10.11内核检索进程路径

更新时间:2023-01-20 09:27:21

应该返回进程的主要可执行文件vnodeproc_getexecutablevnode()的函数在私有KPI中,该函数仅可用于Apple发布的kexts

The function that is supposed to return a process's main executable's vnode, proc_getexecutablevnode() is in the private KPI, which is only available to kexts published by Apple.

它所依赖的信息应该存储在struct procp_textvp字段中,该字段再次不是公共ABI的一部分-Apple可以选择更改其布局,因此即使将其定义导入到您的代码,您的代码在OS X的较早版本或更早版本中可能不正确.但是,

The information it relies on is supposedly stored in the p_textvp field of struct proc, which once again is not part of the public ABI - Apple can choose to change its layout, so even if you do import its definition into your code, your code might be incorrect in future or older versions of OS X. However, it turns out this field is NULL anyway.

也许可以通过sysctl机制获得该信息,但是我看不到一种明显的方法.您应该能够通过proc_info()系统调用在用户空间中获取信息.它没有被Apple记录下来,但是您可以阅读源代码.这由存储在进程地址空间中的信息支持,因此,该进程实际上可以伪造它.

You may be able to get at the information via the sysctl mechanism, but I can't see an obvious way to do it. You should be able to obtain the information in userspace via the proc_info() system call. It's not documented by Apple, but you can read the source. This is backed by information stored in the process's address space, and as such, the process can actually fake it.

最后,如果在启动时加载了kext,则可以通过在KAUTH_SCOPE_FILEOP中注册KAUTH侦听器来自己跟踪进程的可执行文件.事件KAUTH_FILEOP_EXEC会告诉您任何时候一个进程(成功)调用exec()函数之一,包括所讨论的vnode.在OS X/macOS上,posix_spawn()更为常见,因为fork/exec被明确禁止用于多线程进程,并且macOS上的大多数进程都具有多个线程.这一点很相关,因为由posix_spawn()触发的KAUTH_FILEOP_EXEC事件处理程序实际上是在 parent 进程的上下文中运行的.因此,您需要做一些额外的调整,以将可执行vnode信息与子进程PID关联起来.

Finally, if your kext is loaded at boot time, you can keep track of the process's executable file yourself by registering a KAUTH listener in the KAUTH_SCOPE_FILEOP. The event KAUTH_FILEOP_EXEC will tell you whenever a process (successfully) calls one of the exec() functions, including the vnode in question. On OS X/macOS, posix_spawn() is much more common, as fork/exec are explicitly disallowed for multithreaded processes, and most processes on macOS have more than one thread. This is relevant here because the KAUTH_FILEOP_EXEC event handler as triggered by posix_spawn() actually runs in the parent process's context. So you need to do some additional wrangling to correlate the executable vnode information with the child process PID.

另一个注意事项:请注意,可执行文件的路径不一定定义明确.与在Windows上不同,可以移动或删除正在执行的文件,因此路径可以更改或完全消失.此外,可以对文件进行硬链接,在这种情况下,它们具有多个路径. vnode_t是标识文件的内核类型,而不管其名称/路径/等如何. -常规用户进程将始终具有可执行文件vnode,但是vnode可能没有有效路径.确保您的代码不期望它.

One more note: be aware that the path to the executable file isn't necessarily well-defined. Unlike on Windows, files being executed can be moved or deleted, so the path can change, or go away entirely. Moreover, files can be hardlinked, in which case they have multiple paths. The vnode_t is the kernel type that identifies a file, regardless of its name/path/etc. - a regular user process will always have an executable vnode, but that vnode might not have a valid path. Make sure your code doesn't expect it to.