整个内核就是一个进程. 内核有一个线程表,跟踪该系统中所有的线程.
回收用户级线程: 如果线程管理开销非常小,没必要这样做
要求必须安装WinDDK,驱动程序开发工具包
本示例有2个项目
windows桌面应用程序项目一: KernelThread
- ThreadApp.h
#include <windows.h>
#include <tchar.h>
#define DRIVER_NAME TEXT( "TestDriver.sys" )
#define DRIVER_SERVICE_NAME TEXT(" TestDriver ")
#define Message(n) MessageBox(0, TEXT(n), \
TEXT("Test Driver Info"), 0)
BOOL StartDriver(LPTSTR szCurrentDriver);
BOOL StopDriver(void);
- ThreadApp.cpp
#include "ThreadApp.h"
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR szCommandLine, int iCmdShow)
{
StartDriver(DRIVER_NAME);
ShellAbout(0, DRIVER_SERVICE_NAME, TEXT(""), NULL);
StopDriver();
return 0;
}
BOOL StartDriver(LPTSTR szCurrentDriver)
{
HANDLE hFile = 0;
DWORD dwReturn = 0;
SC_HANDLE hSCManager = { 0 };
SC_HANDLE hService = { 0 };
SERVICE_STATUS ServiceStatus = { 0 };
TCHAR szDriverPath[MAX_PATH] = { 0 };
GetSystemDirectory(szDriverPath, MAX_PATH);
TCHAR szDriver[MAX_PATH + 1];
#ifdef _UNICODE
wsprintf(szDriver, L"\\drivers\\%ws", DRIVER_NAME);
#else
sprintf(szDriver, "\\drivers\\%s", DRIVER_NAME);
#endif
_tcscat_s(szDriver, (_tcslen(szDriver) + 1) * sizeof(TCHAR),
szDriver);
BOOL bSuccess = CopyFile(szCurrentDriver, szDriverPath, FALSE);
if (FALSE == bSuccess)
{
Message("copy driver failed");
return bSuccess;
}
hSCManager = OpenSCManager(NULL, NULL,
SC_MANAGER_CREATE_SERVICE);
if (0 == hSCManager)
{
Message("open sc manager failed!");
return FALSE;
}
hService = CreateService(hSCManager, DRIVER_SERVICE_NAME,
DRIVER_SERVICE_NAME, SERVICE_START | DELETE | SERVICE_STOP,
SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE,
szDriverPath, NULL, NULL, NULL, NULL, NULL);
if (0 == hService)
{
hService = OpenService(hSCManager, DRIVER_SERVICE_NAME,
SERVICE_START | DELETE | SERVICE_STOP);
Message("create service failed!");
Message("open service failed!");
return FALSE;
}
BOOL startSuccess = StartService(hService, 0, NULL);
if (FALSE == startSuccess)
{
Message("start service failed!");
return startSuccess;
}
CloseHandle(hFile);
return TRUE;
}
BOOL StopDriver(void)
{
SC_HANDLE hSCManager = { 0 };
SC_HANDLE hService = { 0 };
SERVICE_STATUS ServiceStatus = { 0 };
TCHAR szDriverPath[MAX_PATH] = { 0 };
GetSystemDirectory(szDriverPath, MAX_PATH);
TCHAR szDriver[MAX_PATH + 1];
#ifdef _UNICODE
wsprintf(szDriver, L"\\DRIVERS\\%WS", DRIVER_NAME);
#else
sprintf(szDriver, "\\drivers\\%s", DRIVER_NAME);
#endif
_tcscat_s(szDriver, (_tcslen(szDriver) + 1) * sizeof(TCHAR),
szDriver);
hSCManager = OpenSCManager(NULL, NULL,
SC_MANAGER_CREATE_SERVICE);
if (0 == hSCManager)
{
return FALSE;
}
hService = OpenService(hSCManager, DRIVER_SERVICE_NAME,
SERVICE_START | DELETE | SERVICE_STOP);
if (hService)
{
ControlService(hService, SERVICE_CONTROL_STOP,
&ServiceStatus);
DeleteService(hService);
CloseServiceHandle(hService);
BOOL ifSuccess = DeleteFile(szDriverPath);
return TRUE;
}
return FALSE;
}
控制台项目2: DriverApp
- DriverApp.h
//每个驱动程序都必须在此头文件中
#include "ntddk.h"
//声明2个主例程
DRIVER_INITIALIZE DriverEntry; //驱动程序入口点
DRIVER_UNLOAD OnUnload; //驱动程序卸载
- DriverApp.cpp
#include "DriverApp.h"
VOID ThreadStart(PVOID lpStartContext)
{
PKEVENT pEvent = (PKEVENT)lpStartContext;
DbgPrint("Hello! I am kernel thread. My ID is %u. Regards..",
(ULONG)PsGetCurrentThreadId());
KeSetEvent(pEvent, 0, 0);
PsTerminateSystemThread(STATUS_SUCCESS);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT theDriverObject, PUNICODE_STRING theRegistryPath)
{
//确保执行第一天命令之前已经声明了所有变量
HANDLE hThread = NULL;
NTSTATUS ntStatus = 0;
OBJECT_ATTRIBUTES ThreadAttributes;
KEVENT kEvent = { 0 };
PETHREAD pThread = 0;
theDriverObject->DriverUnload = OnUnload; //设置卸载例程
DbgPrint("Entering KERNEL mode..");
//初始化对象,在创建内核线程之前
InitializeObjectAttributes(&ThreadAttributes, NULL, OBJ_KERNEL_HANDLE,
NULL, NULL);
//内核开发必须消息谨慎,哪怕一丁点的错误都会导致**蓝屏死机**或机器崩溃,所以使用__try - __except块
__try
{
KeInitializeEvent(&kEvent, SynchronizationEvent, 0);
ntStatus = PsCreateSystemThread(&hThread, GENERIC_ALL, &ThreadAttributes,
NULL, NULL, (PKSTART_ROUTINE)&ThreadStart, &kEvent);
if (NT_SUCCESS(ntStatus))
{
//与用户空间创建句柄不同.需要在返回时初始化一个触发事件
//此例程无法使用PsCreateSystemThread返回的句柄
KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
ZwClose(hThread); //关闭内核句柄和防止内存泄漏
}
else
{
DbgPrint("Could not create system thread!");
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("Error while creating system thread!");
}
return STATUS_SUCCESS;
}
VOID OnUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("Leaving KERNEL mode..");
}
- 最后要实现PKSTART_ROUTINE或线程的开始地址,线程的指令从这里开始执行.例如
VOID (__stdcall* KSTART_ROUTINE)(PVOID StartCOntext);