Прятки в linux



     проститутки из ростова-на-Дону воплотят все ваши смелые фантазии. | Решил первым запустить электромобиль на ионно- литиевых батареях. |     

Исключение процесса из списка задач


Перечень всех процессоров хранится внутри ядра в виде двунаправленного списка task_struct, определение которого можно найти в файле linux/sched.h. next_task

указывает на следующий процесс в списке, prev_task – на предыдущий. Физически task_struct

содержится внутри PCB-блоков (Process Control Block), адрес которых известен каждому процессу. Переключение контекста осуществляется планировщиком (scheduler), который определяет какой процесс будет выполняется следующим (см. рис 3). Если мы исключим наш процесс из списка, он автоматически исчезнет из списка процессов /proc, но больше никогда не получит управление, что в наши планы вообще-то не входит.

Рисунок 3 организация процессов в Линухе

Просматривая список процессов, легко обнаружить, что в нем отсутствует процесс, PID которого равен нулю. А ведь такой процесс (точнее — псевдопроцесс) есть! Он создается операционной системой для подсчета загрузки ЦП и прочих служебных целей.

Допустим, нам необходимо скрыть процесс с идентификатором 1901. Исключаем его из двунаправленного списка, склеивая между собой поля next_task/prev_task

двух соседних процессов. Подцепляем наш процесс к процессу с нулевым PID'ом, оформляя себя как материнский процесс (за это отвечает поле p_pptr) и… модифицируем код планировщика так, чтобы родитель процесса с нулевым PID'ом хотя бы эпизодически получал управление (см. рис 4). Если необходимо скрыть более одного процесса, их можно объединить в цепочку, используя поле p_pptr или любое другое реально незадействованное поле.

Рисунок 4 удаление процесса из двунаправленного списка процессов

Исходный код планировщика содержится в файле /usr/src/linux/kernel/sched.c. Нужный нам фрагмент легко найти по ключевому слову "goodness" (имя функции, определяющей "значимость" процесса в глазах планировщика). В различных ядрах он выглядит по разному. Например, моя версия реализована так:

c

= -1000;                        // начальное значение "веса"




Содержание  Назад  Вперед