- •Лабораторная работа №5. Перехват системных сервисов Цель работы
- •Драйвер-фильтр вызовов системных сервисов.
- •Модификация диалоговой прикладной программы управления драйверами для тестирования драйвера перехвата системных сервисов
- •Пояснения
- •1. Работа с таблицей системных сервисов
- •2. Получение имени текущего процесса
- •Лабораторная работа №6. Получение копии адресного пространства указанного процесса
- •Драйвер-фильтр получения копии адресного пространства на уровне vaDи на уровне каталога-таблиц страниц.
- •Модификация диалоговой прикладной программы управления драйверами для тестирования драйвера получения копии адресного пространства
- •Пояснения
- •1. Получение списка процессов:
- •2, 3. Получение адреса структуры peBпоPid, переключение адресного пространства на нужный процесс по егоPiDс помощью недокументированных функцийKeAttachProcess()/KeDetachProcess()
- •4. Работа с деревом виртуальных адресных дескрипторов процесса (vad): получение снимка адресного пространства на уровнеVad
- •5. Работа с каталогом страниц (см. Также п.11.3 в документации “PentiumProcessor.Pdf”):
- •6. Работа с файлами на уровне драйвера
Лабораторная работа №5. Перехват системных сервисов Цель работы
Реализация драйвера-перехватчика системных сервисов и управляющей программы.
Навыки, получаемые при реализации данной работы:
Работа с таблицей системных сервисов
Получение имени текущего процесса в контексте случайного процесса
Дополнительная информация: PentiumProcessor.pdf
Задание
Имеется программа skype. Данная программа отказывается работать при наличии на компьютере отладчикаSoftIce, даже если отладчик неактивен.
Требуется: с помощью имеющихся утилит наблюдения за программой (regmon,filemon,diskmon,softice) выяснить причину отказа работать, устранить ее при помощи драйвера перехвата определенных системных сервисов.
Создание драйвера будет заключаться в модификации драйвера №3 (simple3) из л/р №1 и драйвера №5 (devioctl) из л/р №3.
Создание прикладной программы будет заключаться в модификации диалоговой прикладной программы управления драйверами из л/р №2.
Драйвер-фильтр вызовов системных сервисов.
Принцип реализации:
При загрузке драйвер должен создать эксклюзивное устройство GuiDevice, которое будет обрабатывать 2 кода управления – подключение фильтра к сервису, и отключение фильтра от сервиса.
Необходимо выяснить смещение до поля с именем процесса, зная, что функция DriverEntry работает в системном контексте (имя процесса = “System”)
Необходимо получить адрес таблицы системных сервисов
По команде из управляющей прикладной программы для указанного номера сервиса запоминаем адрес обработчика, вместо него записываем адрес нашего обработчика.
В нашем обработчике: получаем имя процесса, производим проверку входных параметров, вызываем старый обработчик, производим проверку выходных параметров, выходим из обработчика.
По команде из управляющей прикладной программы восстанавливаем в таблице системных сервисов адреса прежних обработчиков.
Модификация диалоговой прикладной программы управления драйверами для тестирования драйвера перехвата системных сервисов
Реализовать отправку команд подключения и отключения функций-перехватчиков системных сервисов.
Пояснения
1. Работа с таблицей системных сервисов
typedef NTSTATUS (NTAPI *NTPROC)();
typedef NTPROC *PNTPROC;
typedef struct _SYSTEM_SERVICE_TABLE
{
/*00*/ PNTPROC ServiceTable; //массив точек входа
/*04*/ PULONG CounterTable; //массив счетчиков использования
/*08*/ ULONG ServiceLimit; //число элементов
/*0c*/ PUCHAR ArgumentTable; //массив размеров параметров в байтах
}SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
/*00*/ SYSTEM_SERVICE_TABLE ntoskrnl;
/*10*/ SYSTEM_SERVICE_TABLE win32k;
/*20*/ SYSTEM_SERVICE_TABLE Table3; //not used
/*30*/ SYSTEM_SERVICE_TABLE Table4; //not used
}SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
PMDL KeServiceTableMdl;
VOID UnmapServiceTable(PVOID KeServiceTablePointers)
{
if(KeServiceTableMdl==NULL)
return;
MmUnmapLockedPages(KeServiceTablePointers, KeServiceTableMdl);
ExFreePool(KeServiceTableMdl);
}
PVOID *MapServiceTable(BOOLEAN **ServiceIsHooked)
{
PVOID new_tbl;
PMDL new_mdl;
DbgPrint("SvcLimit=%lx\n", KeServiceDescriptorTable->ntoskrnl.ServiceLimit);
//выделяем память для копии таблицы сервисов и обнуляем ее
new_tbl = ExAllocatePoolWithTag(0, KeServiceDescriptorTable->ntoskrnl.ServiceLimit, 0x206B6444);
*ServiceIsHooked = new_tbl;
if(new_tbl==NULL)
return NULL;
memset(new_tbl, 0, KeServiceDescriptorTable->ntoskrnl.ServiceLimit);
//создаем MDL для таблицы сервисов и получаем по ней адрес
new_mdl = MmCreateMdl(0, KeServiceDescriptorTable->ntoskrnl.ServiceTable,
KeServiceDescriptorTable->ntoskrnl.ServiceLimit*4);
if(new_mdl==NULL)
return NULL;
KeServiceTableMdl = new_mdl;
MmBuildMdlForNonPagedPool(new_mdl);
return MmMapLockedPages(KeServiceTableMdl, 0);
}
Получение номера системного сервиса:
В NTлюбая функция-обработчик вызова системного сервиса (функция с префиксомZw) начинается с команды сохранения номера системного сервиса в стеке (pushnumber). Соответственно, зная начало такой функции, можно получить номер системного сервиса (первый байт функции – код командыpush, следующие 4 байта – номер сервиса).
Например, следующая команда вернет номер системного сервиса для функции ZwDeviceIoControl():
ULONG number = *(PULONG)((PUCHAR)ZwDeviceIoControl +1)