线程创建

#include <ntifs.h>

KEVENT g_kEvent;

VOID DriverUnload(PDRIVER_OBJECT pDriver);

VOID ThreadProc(PVOID StartContext)
{
	ULONG uId = (ULONG)PsGetCurrentThreadId();
	KdPrint(("%wZ,%d\n", StartContext, uId));

	//执行即将结束,将事件置为激发态。
	KeSetEvent(&g_kEvent, 0, TRUE);
	//使用内核线程的时候,需要注意一点,当线程执行完毕的时候,必须主动调用下面
	//这个函数
	PsTerminateSystemThread(STATUS_SUCCESS);
}


NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pPath)
{
	UNREFERENCED_PARAMETER(pPath);
	DbgBreakPoint();


	HANDLE hThread = 0;
	CLIENT_ID Id = {0};
	UNICODE_STRING szString;
	RtlInitUnicodeString(&szString, L"Hello allen");
	//1 创建一个系统线程,能够执行简单代码,并且验证和主线程不是同一个线程
	ULONG uId = (ULONG)PsGetCurrentThreadId();
	KdPrint(("%wZ,Id:%d\n", &szString,uId));
	// 初始化事件对象
	KeInitializeEvent(&g_kEvent, SynchronizationEvent, FALSE);
	PsCreateSystemThread(
		&hThread,
		0,
		NULL,
		NULL,//这里填写NULL,说明创建的是内核线程
		&Id,
		ThreadProc,//回调函数
		&szString
	);
	KeWaitForSingleObject(
		&g_kEvent,
		Executive,
		KernelMode,
		FALSE,
		0         //再内核层的等待函数,0是永久等待
	);
	pDriver->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}


VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
	UNREFERENCED_PARAMETER(pDriver);

}

遍历线程

#include <ntifs.h>
// 根据TID返回线程ETHREAD,失败返回NULL
PETHREAD LookupThread(HANDLE hTid)
{
	PETHREAD pEThread = NULL;
	if (NT_SUCCESS(PsLookupThreadByThreadId(
		hTid,
		&pEThread)))
		return pEThread;
	return NULL;
}
VOID EnumThread(
	PEPROCESS pEProcess  //要枚举的是哪一个进程的线程
) 
{
	PEPROCESS pEProc = NULL;
	PETHREAD  pEThrd = NULL;
	// 循环遍历线程(假设线程的最大值不超过0x25600)
	ULONG i = 0;
	for (i = 4; i < 0x25600; i += 4) {
		// a. 根据TID返回ETHREAD
		pEThrd = LookupThread((HANDLE)i);
		if (!pEThrd)  continue;
		// b. 获得线程所属进程,如果相等则打印线程信息
		pEProc = IoThreadToProcess(pEThrd);
		if (pEProc == pEProcess) {
			DbgPrint("[THREAD]ETHREAD=%p TID=%ld\n",
				pEThrd, (ULONG)PsGetThreadId(pEThrd));
		}
		// c. 将线程对象引用计数减1
		ObDereferenceObject(pEThrd);
	}
}

结束线程等

#include <ntifs.h>
NTSTATUS ZwOpenThread(
	_Out_  PHANDLE ThreadHandle,
	_In_   ACCESS_MASK DesiredAccess,
	_In_   POBJECT_ATTRIBUTES ObjectAttributes,
	_In_   PCLIENT_ID ClientId);
typedef NTSTATUS(__fastcall *ZWTERMINATETHREAD)(
	HANDLE hThread,
	ULONG uExitCode);
//结束线程,暂停线程,恢复线程,这些函数没有导出,
//就得自己去找   可以先找到它 然后计算他的偏移就可以用代码实现
ZWTERMINATETHREAD ZwTerminateThread = 0x83e79afc; //函数地址,是自己找到的,没有导出
void KernelKillThread(ULONG tID) {
	HANDLE            hThread = NULL;
	CLIENT_ID         ClientId = { 0 };
	OBJECT_ATTRIBUTES objAttribut =
	{ sizeof(OBJECT_ATTRIBUTES) };
	ClientId.UniqueProcess = 0;
	ClientId.UniqueThread = (HANDLE)tID; // TID  
										  //打开线程,如果句柄有效,则结束线程
	ZwOpenThread(&hThread, 1, &objAttribut, &ClientId);
	if (hThread) {
		ZwTerminateThread(hThread, 0);
		ZwClose(hThread);
	}
}