线程创建
#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);
}
}