win驱动下线程操作相关函数封装

线程创建

#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);
    }
}

猜你喜欢

转载自blog.51cto.com/haidragon/2131747