1. 程式人生 > >win驅動下線程操作相關函數封裝

win驅動下線程操作相關函數封裝

RoCE adp read true ali enc stc 實現 偏移

線程創建

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

win驅動下線程操作相關函數封裝