Я считываю таймер с помощью команды RDTSC на протяжении 24 часов, и это работает замечательно. Но проблема в том, что драйвер загружается, и таймер начинает отсчет сразу, хотя драйвер загружается мгновенно. Интересно, не упустил ли я что-то здесь. Код (Text): #define TIMER_QUERY_STATE 0x0001 #define TIMER_MODIFY_STATE 0x0002 #define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|TIMER_QUERY_STATE|TIMER_MODIFY_STATE) #define SECONDS_IN_24_HOURS 24 * 60 * 60 Код (Text): NTSTATUS DriverEntry(PDRIVER_OBJECT theDriverObject, PUNICODE_STRING theRegistryPath) { HANDLE hThread = NULL; NTSTATUS ntStatus = STATUS_SUCCESS; OBJECT_ATTRIBUTES ThreadAttributes; KEVENT kEvent; PETHREAD pThread = NULL; KAFFINITY threadAffinityMask = (1ull << 0); theDriverObject->DriverUnload = OnUnload; DbgPrint("Entering KERNEL mode..\n"); InitializeObjectAttributes(&ThreadAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE); __try { ntStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &ThreadAttributes, NULL, NULL, (PKSTART_ROUTINE)ThreadStart, &kEvent); if (NT_SUCCESS(ntStatus)) { ZwSetInformationThread(hThread, ThreadAffinityMask, &threadAffinityMask, sizeof(threadAffinityMask)); ntStatus = ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, *PsThreadType, KernelMode, (PVOID*)&pThread, NULL); if (NT_SUCCESS(ntStatus)) { // Wait for the thread to signal completion KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL); // Clean up ZwClose(hThread); ObDereferenceObject(pThread); } else { DbgPrint("ObReferenceObjectByHandle failed!\n"); } } else { DbgPrint("Could not create system thread!\n"); } } __except (EXCEPTION_EXECUTE_HANDLER) { DbgPrint("Error while creating system thread!\n"); ntStatus = GetExceptionCode(); } return ntStatus; } Код (Text): VOID ThreadStart(PVOID lpParam) { KEVENT *pEvent = (KEVENT*)lpParam; LARGE_INTEGER interval; HANDLE timerHandle; NTSTATUS status; OBJECT_ATTRIBUTES timerAttributes; WCHAR buffer[256]; interval.QuadPart = -10000000; // 1 second in 100-nanosecond intervals InitializeObjectAttributes(&timerAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); status = ZwCreateTimer(&timerHandle, TIMER_ALL_ACCESS, &timerAttributes, SynchronizationTimer); if (!NT_SUCCESS(status)) { DbgPrint("Failed to create timer object.\n"); PsTerminateSystemThread(status); } auto cr8 = __readcr8(); __writecr8(HIGH_LEVEL); _disable(); unsigned __int64 time = __rdtsc(); _enable(); __writecr8(cr8); for (int i = 0; i < SECONDS_IN_24_HOURS; ++i) { double currentTime = MyTimer(time, data->frequency); RtlStringCbPrintfW(buffer, sizeof(buffer), L"Thread countdown at: %d seconds, Current time: %lf seconds\n", i + 1, currentTime); DbgPrint("%ws", buffer); // Set the timer to expire in 1 second status = ZwSetTimer(timerHandle, &interval, NULL, NULL, FALSE, 0, NULL); if (!NT_SUCCESS(status)) { DbgPrint("Failed to set timer.\n"); break; } status = ZwWaitForSingleObject(timerHandle, FALSE, NULL); if (!NT_SUCCESS(status)) { DbgPrint("Failed to wait for timer.\n"); break; } } DbgPrint("---------------- 24 hours have passed! ----------------\n"); KeSetEvent(pEvent, 0, FALSE); ZwClose(timerHandle); PsTerminateSystemThread(STATUS_SUCCESS); } --- Сообщение объединено, 15 июн 2024 --- Я исправил это Код (Text): KeSetEvent(&ddx->kill, 0, FALSE); KeWaitForSingleObject(ddx->hThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(ddx->hThread); Код (Text): for (int i = 0; i < SECONDS_IN_24_HOURS; ++i) { if (KeReadStateEvent(&ddx->kill) != 0) { break; } Код (Text): PreviousState = TRUE; status = ZwSetTimer(timerHandle, &interval, NULL, NULL, FALSE, 0, &PreviousState); if (!NT_SUCCESS(status)) { DbgPrint("Failed to set timer, status = %lx\n", status); break; } if (PreviousState) { DbgPrint("Set timer previous state wrong\n"); } // Wait for the timer to expire status = ZwWaitForSingleObject(timerHandle, FALSE, NULL); if (!NT_SUCCESS(status)) { DbgPrint("Failed to wait for timer, status = %lx\n", status); break; } // Cancel the timer CurrentState = FALSE; status = ZwCancelTimer(timerHandle, &CurrentState); if (!NT_SUCCESS(status)) { DbgPrint("Failed to cancel timer, status = %lx\n", status); break; } Код (Text): KeInitializeEvent(&ddx->kill, NotificationEvent, FALSE); Теперь он выгружается идеально, без утечек
Подскажите по чём учили написание драйверов? Я последний раз на этом форуме был 16-летним пацанёнком. Спустя 20 лет решил вспомнить увлечения и заново изучить программирование. Посоветуете что-нибудь?
Да =)) а помню как с помощью приложух свина, по конструированию инструкций свой первый полиморф писал ...