XNU: получение уведомлений о запуске и очистке процесса в kext

Каков наилучший способ получать уведомления о запуске и завершении процесса в расширении ядра?

Я знаю, что могу использовать KAuth для подписки на создание процесса (KAUTH_VNODE_EXECUTE). Как насчет подписки на очистку процесса?


person antonone    schedule 15.09.2015    source источник


Ответы (2)


KAUTH_VNODE_EXECUTE недостаточно для всех процессов; это не будет перехватывать процессы, которые fork()ed без exec(). Довольно редко встречается в OSX, но не является чем-то неслыханным. По крайней мере, для разветвления существует обратный вызов политики структуры MAC, хотя MAC (com.apple.kpi.dsep) помечен Apple как неподдерживаемый, а изменения ABI между основными версиями OS X распространены.

Я ничего не знаю о завершении работы, кроме периодического просмотра вашего собственного списка процессов, поиска proc_t для рассматриваемого PID и проверки, работает ли он. Конечно, если обнаруживается новый процесс с переработанным PID, это также означает, что предыдущий процесс с таким же PID умер. Вы можете сделать вывод о смерти процесса из других событий, если у вас есть дополнительная информация о рассматриваемом процессе.

person pmdj    schedule 16.09.2015
comment
основываясь на вашем ответе, я также опубликовал способ получения событий при завершении процесса. - person Zohar81; 17.05.2016

Также есть способ отслеживать процессы при выходе. вы можете использовать механизм уведомления о событиях ядра (kevent), который является частью freeBSD и поддерживается OS X.

поток начинается при запуске процесса (который вы можете поймать, используя подходы kauth или mac framework). в функции обратного вызова вам необходимо зарегистрировать соответствующее событие для последующего мониторинга. Это делается путем установки экземпляра kevent с использованием EV_SET со следующими аргументами:

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 ..."); 

для получения более подробной информации вы можете проверить следующее документ

person Zohar81    schedule 17.05.2016
comment
Я думаю, что это возможно в пользовательском режиме, но не в ядре... потому что определение kqueue() отсутствует в режиме ядра. - person hkb_dev; 27.06.2018