Здавствуйте. Мне задали такую задачку для курсовой - блокирование нежелательных процессов. Вобщем обдумав ее, я решил попробывать написать драйвер (заодно прокачаться в этой области, все-же интересно ) Да и из user mode такую штуку только если с помощью WMI сделать удастся, что имхо ненадежно. Все бы ничего (почитал документацию, полазил здесь по форуму, поэкспериментировал - вроде бы получается), но тут возникла ситуация с защитой управления драйвером и "черным списком". Т.е. по сути нужно "запаролить" все эти действия. Ничего умного в голову не пришло кроме как зашифровать код в драйвере отвечающий за снятие колбэка (PsRemoveLoadImageNotifyRoutine) и т.п. действий, а при посылке сообщения драйверу от управляющй программы, слать заодно пароль. В драйвере из пароля вычислять хеш и сравнивать его с оригинальным. В случае совпадения - кусок кода дешифруется этим паролем и выполняется. Раньше я такое проделывал из user mode, а с ядерным режимом сразу же возникли вопросы: 1) как снять дамп участка кода ? (возможно тупо просканить кусок памяти и вывести DbgPrint) 2) есть-ли и какой аналог функции VirtualProtect ? Ну вообще конечно можно было бы и не геммороится с этим шифрованием, просто интересно - получится-ли такое.
Platon как вариант создать подобие проактивки. Не позволять запускать непроверенные драйвера, не давать доступа к объекту физикалмемори, не давать открывать легальные дровы и ехеки имеющие отношение к режиму ядра для записи в них. Больше я хз чего тут предложить. Но остаются ещё и сплойты. Тут уже сам думай. А война на уровне ядра бессмыслена.
Clerk Дело не в этом, это нужно чтобы снятие легальным способом (посылкой управляющего кода) было авторизировано. А ручное удаление это да, тут надо думать. Хотя снять из юзермода вроде нельзя, а из ядра - запуск-то не санкционированых процессов запрещен, инструменты не запустишь, соответственно и снять не получится, наверное Хотя из этого следует что и возится с шифрованием не стоит, достаточно просто сравнивать хеш пароля - опять таки снять проверку не получится из-за невозможности юзать нужные инструменты. k3internal Спасибо, попробую. ЗЫ Тему думаю стоит закрыть, действительно война на уровне ядра бессмыслена
Platon Можно снять из юзермода нотификатор. Ядерная память открыта для модификации из контекста csrss. Достаточно исполнить в его контексте юзермодный код.
Clerk Возьму на заметку, пасиба. Freeman Каких хендлов? Думаю что это можно переложить на плечи антивиря. Если понадобится без него работать, попробую порешать, можт чего получится.
Решил пойти другим путем и не юзать колбэк. Попробывал перехватывать ZwCreateProcessEx и там из секции дергать полное имя образа. Все получилось кроме того что после выдергивания пути (конкретнее - после копирования буквы винта функцией RtlCopyUnicodeString) оригинальная ZwCreateProcessEx стала возвращать STATUS_INVALID_PARAMETERS, что очень странно. Если букву не копировать то нормально все, чудеса какие-то Код (Text): NTSTATUS NtCreateProcessExHook(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, HANDLE ParentProcess, ULONG Flags, HANDLE SectionHandle, HANDLE DebugPort, HANDLE ExceptionPort, BOOLEAN InJob) { PSECTION Section; PSEGMENT Segment; PCONTROL_AREA ControlArea; PFILE_OBJECT FileObject; UNICODE_STRING DeviceLetter; __try { if (ObReferenceObjectByHandle(SectionHandle, SECTION_QUERY, *MmSectionObjectType, UserMode, &Section, NULL) == STATUS_SUCCESS) { Segment = Section->Segment; if (MmIsAddressValid(Segment)) { ControlArea = Segment->ControlArea; if (MmIsAddressValid(ControlArea)) { if (ControlArea->Segment == Segment) { FileObject = ControlArea->FilePointer; if (MmIsAddressValid(FileObject)) { if (IoVolumeDeviceToDosName(FileObject->DeviceObject, &DeviceLetter) == STATUS_SUCCESS) { RtlCopyUnicodeString(&SectionSource, &DeviceLetter); // Из-за этого облом :( ExFreePool(DeviceLetter.Buffer); } SectionSource.Length = 0; RtlAppendUnicodeStringToString(&SectionSource, &FileObject->FileName); DbgPrint("NtCreateProcessExHook: %S", SectionSource.Buffer); } } } } ObDereferenceObject(Section); } } __except(EXCEPTION_EXECUTE_HANDLER) { DbgPrint("NtCreateProcessExHook: raise exception!"); } return NtCreateProcessExTrue(ProcessHandle, DesiredAccess, ObjectAttributes, ParentProcess, Flags, SectionHandle, DebugPort, ExceptionPort, InJob); } Где я накосячил?
на Код (Text): SectionSource.Length = 0; не обращайте внимания, забыл убрать когда постил, это нужно было после комментирования RtlCopyUnicodeString
Что странно, замена RtlCopyUnicodeString на копирование с помощью RtlMoveMemory работает Код (Text): RtlMoveMemory(SectionSource.Buffer, DeviceLetter.Buffer, DeviceLetter.Length); SectionSource.Length = DeviceLetter.Length; ЗЫ А как здесь свои сообщения отредактировать? В упор нужной кнопочки не вижу