
🔹 هنگام Load:
اول درایور لود میشود
دوم یک thread کرنل ساخته میشود
سوم هر 2 ثانیه پیام چاپ میکند
🔹 هنگام Stop:
اول فلگ توقف فعال میشود
دوم thread بهصورت امن خارج میشود
سوم سیستم بدون BSOD ادامه میدهد
#pragma warning (disable : 4100) #include <ntifs.h> #include <ntddk.h> HANDLE g_ThreadHandle = NULL; BOOLEAN g_StopThread = FALSE; // تابع Thread VOID ThreadRoutine(PVOID Context) { LARGE_INTEGER interval; UNREFERENCED_PARAMETER(Context); while (!g_StopThread) { // تاخیر 2 ثانیه interval.QuadPart = -2 * 10000000; // -2 ثانیه به واحد 100 نانوثانیه KeDelayExecutionThread(KernelMode, FALSE, &interval); DbgPrintEx(0, 0, "Thread woke up after 2 seconds\n"); } PsTerminateSystemThread(STATUS_SUCCESS); } NTSTATUS UnloadDriver(PDRIVER_OBJECT pDriverObject) { DbgPrintEx(0, 0, "Goodbye!\n"); if (g_ThreadHandle) { g_StopThread = TRUE; // صبر برای پایان Thread با ZwWaitForSingleObject ZwWaitForSingleObject(g_ThreadHandle, FALSE, NULL); // بستن handle ZwClose(g_ThreadHandle); g_ThreadHandle = NULL; } return STATUS_SUCCESS; } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) { UNREFERENCED_PARAMETER(pRegistryPath); pDriverObject->DriverUnload = UnloadDriver; HANDLE threadHandle = NULL; NTSTATUS status = PsCreateSystemThread( &threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, ThreadRoutine, NULL ); if (NT_SUCCESS(status)) { g_ThreadHandle = threadHandle; DbgPrintEx(0, 0, "Driver loaded successfully!\n"); } else { DbgPrintEx(0, 0, "Failed to create system thread\n"); } return STATUS_SUCCESS; }
#pragma warning (disable : 4100) #include <ntifs.h> #include <ntddk.h>
#pragma warning (disable : 4100)
هشدار 4100 مربوط به پارامترهای استفادهنشده (Unreferenced parameter) است.
در درایورهای کرنل خیلی وقتها پارامترها استفاده نمیشوند، پس این هشدار عمداً خاموش شده است.
ntifs.h و ntddk.h
این دو هدر شامل:
APIهای کرنل ویندوز
تعاریف PDRIVER_OBJECT
توابعی مثل PsCreateSystemThread، KeDelayExecutionThread، DbgPrintEx
هستند.
g_ThreadHandle
هندل thread کرنلی که ساخته میشود را نگه میدارد تا:
هنگام unload بتوانیم صبر کنیم تا thread تمام شود
بعد هندل را ببندیم
g_StopThread
یک فلگ کنترلی است:
FALSE → thread ادامه میدهد
TRUE → thread باید خارج شود
این روش، راه استاندارد و امن برای متوقف کردن thread در کرنل است.
تابع Thread (هستهی اصلی)
VOID ThreadRoutine(PVOID Context)
این تابع کد اجرایی thread کرنل است که توسط PsCreateSystemThread اجرا میشود.
متغیر زمان
LARGE_INTEGER interval; UNREFERENCED_PARAMETER(Context);
LARGE_INTEGER برای نگهداری زمان delay استفاده میشود
Context در این مثال استفاده نشده، بنابراین با UNREFERENCED_PARAMETER هشدارش حذف شده
حلقهی thread
while (!g_StopThread)
این یعنی:
تا وقتی درایور unload نشده
thread فعال باقی میماند
خوابیدن thread (معادل Sleep)
interval.QuadPart = -2 * 10000000; KeDelayExecutionThread(KernelMode, FALSE, &interval);
توضیح خیلی مهم:
واحد زمان = 100 نانوثانیه
10,000,000 = 1 ثانیه
عدد منفی یعنی relative delay
پس این خط یعنی:
«thread فعلی 2 ثانیه در کرنل بخوابد»
چاپ پیام
DbgPrintEx(0, 0, "Thread woke up after 2 seconds\n");
هر 2 ثانیه یک پیام در DebugView / WinDbg چاپ میشود.
پایان صحیح thread
PsTerminateSystemThread(STATUS_SUCCESS);
وقتی g_StopThread = TRUE شود:
حلقه تمام میشود
thread بهصورت تمیز و رسمی خاتمه مییابد
❗ این خیلی مهم است، چون thread نباید ناگهانی کشته شود.
تابع UnloadDriver
NTSTATUS UnloadDriver(PDRIVER_OBJECT pDriverObject)
این تابع زمانی اجرا میشود که:
sc stop DriverName
را میزنیم.
چاپ پیام خروج
DbgPrintEx(0, 0, "Goodbye!\n");
توقف امن thread
if (g_ThreadHandle) { g_StopThread = TRUE;
به thread علامت میدهیم که خودش خارج شود
هیچ force یا kill وجود ندارد → کاملاً امن
صبر تا پایان thread
ZwWaitForSingleObject(g_ThreadHandle, FALSE, NULL);
این خط:
صبر میکند تا thread واقعاً تمام شود
جلوی BSOD و dangling thread را میگیرد
آزادسازی منابع
ZwClose(g_ThreadHandle); g_ThreadHandle = NULL;
هندل بسته میشود
اشارهگر null میشود تا دوباره استفاده نشود
تابع DriverEntry (نقطه ورود درایور)
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
این تابع:
هنگام load شدن درایور اجرا میشود
مثل main() در برنامههای معمولی است
تنظیم Unload
pDriverObject->DriverUnload = UnloadDriver;
اگر این خط نباشد:
sc stop کار نمیکند
درایور unload نمیشود
ساخت thread کرنل
NTSTATUS status = PsCreateSystemThread( &threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, ThreadRoutine, NULL );
این کار:
یک thread سطح کرنل میسازد
تابع ThreadRoutine را اجرا میکند
هندل آن را برمیگرداند
بررسی موفقیت
if (NT_SUCCESS(status)) { g_ThreadHandle = threadHandle; DbgPrintEx(0, 0, "Driver loaded successfully!\n"); }
اگر thread ساخته شد:
هندل ذخیره میشود
پیام موفقیت چاپ میشود
Telegram: @CaKeegan
Gmail : amidgm2020@gmail.com