пишу драйвер на С для защиты процесса, сделал перехват функции ZwOpenProcess, определяю в своей проге (чистый Win32API) PID защищаемого процесса, передаю драйверу PID, и уже соответственно драйвер осуществляет защиту процесса у меня соответственно вопрос - этого достаточно для защиты памяти процесса от записи или это вообще не в этой стороне? смотрю сейчас уже в сторону дополнительной обработки функций ZwWriteVirtualMemory и ZwProtectVirtualMemory, подскажите пожалуйста, как они работают, что делают, ничего толкового и подробного не нашел по этим функциям, одни ссылки только что эти функции используют руткиты и антивири желательно с примерами на С и комментами, буду очень благодарен, если направите на путь истинный (асм не предлагать, я в нем почти ни бум бум)))
мыслите в правильном направлении, без хэндла процесса ничего не получится в юзермоде. Но из csrss можно скопировать нужные хэндлы (он имеет хэндлы всех процессов), так что придется хукать ещё и NtDuplicateObject, чтобы предотвратить копирование. Хуки на ZwWriteVirtualMemory и ZwProtectVirtualMemory излишни (а вот описание почитайте в книжке Неббета, которая в английском варианте валяется везде (Недокументированные возможности Windows 2000).
можно подробнее - почему излишни? не потому что, чтобы их вызвать сначала идет обращение к ZwOpenProcess? прошу прощения за наглость, но, пожалуйста, аргументируйте свои ответы, не голословно же мне всему верить возможно, не совсем меня правильно поняли - драйвер работает в ring0, ring3 оставим для приложений, меня интересует только защита процесса в нулевом кольце, прога - только для определения PID защищаемого процесса (процесс не свой, а "чужой" - в принципе какого угодно приложения) и передача этого PID в драйвер
RUStx88 Какже вы драйвера тогда пишите, если вам понятие системных сервисов не известно ? Если нет описателя, то к обьекту документированными способами не добраться.
я имею ввиду их синтаксис и использование, на примерах пишу свой первый "драйв")), так что особо сильно не придирайтесь, а лучше поделитесь ссылками или своими знаниями, чтобы я устранил пробел в своих т.е. достаточно, я так понимаю? перекрываем эту функцию (ZwOpenProcess) обращения к процессу и большинство прог\юзеров обломается?
RUStx88 Да. Ещё открытие системных процессов нужно запретить. Нужно начинать с более простых вещей. Качественная реализация будет для вас не доступной. Будет масса уязвимостей, начиная с простейших типа race condition и более грубыми.
- Естественно обламается вы же используете ring0, а юзермордные программы выполняются в контексте ring3. - Так ето уже руткит получается. 2 RUStx88: вы пишете что то вроде руткит-драйвера Conficker'a?) Так знайте и его обломать не сложно ЗЫ.: Пропалится АВ при первом же запуске.
пишу защитника для своего процесса, ну использует для этого технологию руткитов))) про Conficker не слышал))) я сделал так: перехват функции ZwOpenProcess и при обращении к защищаемому процессу STATUS_ACCESS_DENIED + скрытие процесса (думаю еще над подменой его PID) думаю, это самое легко реализуемое + не самое легкое для обхода этой защиты
Я думаю никто вам не сможет сказать какой защиты достаточно а какой нет. Вот мне сразу в голову не идёт способ как "влезть в процесс" из userland если нет хендла. И это незначит что этого способа нет. Т.е. если я сейчас скажу "Да я точно знаю что тебе хватит просто перехватить ZwOpenProcess и твой процесс неуязвим!" тебе это както поможет? ))) Вобщем если хочешь защитится от всего и всех, то пиши "мегакрутой руткит". Если надо создать относительно надёжную защиту можешь делать так. Пишешь утилиту которая "влезает в процесс", потом в драйвере блокирует те методы. Потом придумываешь новые методы "влезания" и всё заново. Если с последним совсем проблема, тогда вначале читаешь литературу по устройству виндоус.... Ну и гдето после этого уже появляются новые идеи )
100 пудов! нет ни одного руткита который нельзя было бы обломать И процесс вы точно на 100% никогда не сможете защитить ничем. Так что одна из методик обхода и защиты процесса - сокрытие потоков процесса через всем известные приемы с ядром и ntdll
еще вот такая проблема объявилась, хук для ZwOpenProcess работает прекрасно, решил потренироваться, использовать детект (типа: был факт - делаем оповещение) на то, кто пытается влезть в процесс переписываю код хука ZwOpenProcess на функцию ZwWriteVirtualMemory, и... что такое - НЕ компилится!!! компилятор выдает мне главное, код абсолютно такой же, только функции поменялись, но все равно не работает тысячу раз проверял синтаксис функции ZwWriteVirtualMemory - все правильно написано, объявлено подскажите, пожалуйста, как перехватить эту функцию, я уже не знаю что делать, не пойму, что за трабла весь гугл излазил уже, все китайские сайты вот код перехвата Код (Text): typedef struct ServiceDescriptorEntry { unsigned int *ServiceTableBase; unsigned int *ServiceCounterTableBase; unsigned int NumberOfServices; unsigned char *ParamTableBase; } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; #define SYSTEMSERVICE(function) \ KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)function + 1)] #define SYSCALL_INDEX(function) \ *(PULONG)((PUCHAR)function + 1) #define HOOK(function, NewFunction, OldFunction) \ OldFunction = (PVOID)InterlockedExchange((PLONG)&MappedSystemCallTable[SYSCALL_INDEX(function)], (LONG)NewFunction) #define UNHOOK(function, OldFunction) \ InterlockedExchange((PLONG)&MappedSystemCallTable[SYSCALL_INDEX(function)], (LONG)OldFunction) NTSYSAPI NTSTATUS NTAPI ZwWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG BufferLength, OUT PULONG ReturnLength OPTIONAL); typedef NTSTATUS (*ZWWRITEVIRTUALMEMORY)(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG BufferLength, OUT PULONG ReturnLength OPTIONAL); PVOID OldZwWriteVirtualMemory; NTSTATUS NewZwWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG BufferLength, OUT PULONG ReturnLength OPTIONAL) { ... } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath) { ... g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices * 4); if (!g_pmdlSystemCall) return STATUS_UNSUCCESSFUL; MmBuildMdlForNonPagedPool(g_pmdlSystemCall); g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; MappedSystemCallTable = (PVOID*)MmMapLockedPages(g_pmdlSystemCall, KernelMode); OldZwWriteVirtualMemory = (PVOID)(SYSTEMSERVICE(ZwWriteVirtualMemory)); //!!!!!!!!!!!!!!!!!!!!!!!! HOOK(ZwWriteVirtualMemory, NewZwWriteVirtualMemory, OldZwWriteVirtualMemory); //!!!!!!!!!!!!!!!! ... } VOID UnLoadDriver(IN PDRIVER_OBJECT DriverObject) { UNHOOK(ZwWriteVirtualMemory, OldZwWriteVirtualMemory); //!!!!!!!!!!!!!!!!!!! ... } где восклицательные знаки - на них ругается компилятор при использовании ZwWriteVirtualMemory, при ZwOpenProcess все нормально заменяю ZwWriteVirtualMemory на ZwOpenProcess - и ву-а-ля всё работает в чем трабла????
Не сочтите за снобизм, но не компилятор, а линкер функция ZwWriteVirtualMemory(...) не экспортируется из ядра. Если уж используете SSDT, то из нее можно получать адрес оригинальной функции по заданному индексу (индекс зависит от номера билда ядра ОС). UPD: Еще, в вашем случае, если до вас был установлен сплайс-перехват (jmp-переход в начале функции на адрес хука), то вы еще в BSOD свалитесь. Вставьте хотя бы код проверки на выход за пределы SSDT или читайте тело функции с диска, а не из памяти.
тааааак, поиск по форуму решил больше, чем гугл))))) нашел много тем про проблему вытаскивания адреса функции ZwWriteVirtualMemory http://wasm.ru/forum/viewtopic.php?id=24179 да, извиняюсь, протупил, линкер, конечно )))
RUStx88 Тогда уже просто при вызове ZwWriteVirtualMemory проверяй какой процесс описывает хэндл непосредственно в ядре. На производительности это не особо отразится. Зато не нужно будет следить за кучей хэндлов сразу и перехватывать никому ненужные ZwOpenProcess и кто там с ним ещё.
закинуть код в контекст другого процесса можно и без ZwWriteVirtualMemory... другое дело что, перехватывая ZwOpenProcess, мы решаем больше проблем... не только вопросы по работе с ап защищаемого процесса, но и создания потоков в нем или изменение контекста одного из потоков...