驱动小程序2

2018-10-10  本文已影响0人  MagicalGuy

附加进程

#include <ntifs.h>


VOID DriverUnload(PDRIVER_OBJECT pDriver);
// 根据PID返回进程EPROCESS,失败返回NULL
PEPROCESS LookupProcess(HANDLE hPid)
{
    PEPROCESS pEProcess = NULL;
    if (NT_SUCCESS(PsLookupProcessByProcessId(
        hPid, &pEProcess)))
        return pEProcess;
    return NULL;
}


VOID ChangeData(ULONG uId)
{
    KAPC_STATE ks;

    //1 根据ID获得进程内核对象
    PEPROCESS pEprocess = LookupProcess((HANDLE)uId);

    //2 挂靠到此进程上去
    //需要注意:不能挂靠之后,将内存中的数据往用户层地址存储,是不对的。
    //因为当挂靠到目标进程之后,用户层地址就是目标进程的了,也就存储到
    //目标进程中,而且目标进程的那个地址不一定有效,可能造成崩溃。
    KeStackAttachProcess(
        pEprocess,
        &ks
    );

    //3 修改内存
    char * p = (char *)0x1dfaf0;
    p[5] = 'h';
    p[6] = 'e';
    p[7] = 'l';
    p[8] = 'l';
    p[9] = '\0';
    //4 解除挂靠
    KeUnstackDetachProcess(&ks);
}

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

    ChangeData(1716);


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

=========================
IO计时器

#include <ntifs.h>

KEVENT g_kEvent;

VOID DriverUnload(PDRIVER_OBJECT pDriver);

VOID TimerProc(
    DEVICE_OBJECT *DeviceObject,
    PVOID Context
)
{
    UNREFERENCED_PARAMETER(DeviceObject);
    static ULONG i = 0;
    i++;
    KdPrint(("外部传入的是%d ,内部变化:%d\n", Context, i));
}


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


    //初始化一些变量
    PDEVICE_OBJECT pDevice = NULL;
    UNICODE_STRING strDeviceName;
    RtlInitUnicodeString(&strDeviceName, L"\\Device\\Hello");
    //1 创建一个设备
    IoCreateDevice(
        pDriver,            //驱动对象指针
        0,                  //设备扩展大小,传0
        &strDeviceName,     //设备名称
        FILE_DEVICE_UNKNOWN,//设备类型
        0,                  //设备特征
        FALSE,              //设备是否独占
        &pDevice            //传出创建好的设备指针
    );

    // 初始化一个IO计时器
    IoInitializeTimer(
        pDevice,
        TimerProc,
        (PVOID)100
    );

    //启动IO计时器
    IoStartTimer(pDevice);

    pDriver->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
    UNREFERENCED_PARAMETER(pDriver);
    //停止IO计时器
    IoStopTimer(pDriver->DeviceObject);
    IoDeleteDevice(pDriver->DeviceObject);
}

=================

object hook

#include <ntifs.h>
VOID DriverUnload(PDRIVER_OBJECT objDriver);
typedef ULONG(*OBGETOBJECTTYPE)(PVOID Object);
typedef NTSTATUS(*PARSEPRODECEDURE)(IN PVOID ParseObject,
    IN PVOID ObjectType,
    IN OUT PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE AccessMode,
    IN ULONG Attributes,
    IN OUT PUNICODE_STRING CompleteName,
    IN OUT PUNICODE_STRING RemainingName,
    IN OUT PVOID Context OPTIONAL,
    IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
    OUT PVOID *Object);
PARSEPRODECEDURE g_OldFun;
NTSTATUS NewParseProcedure(IN PVOID ParseObject,
    IN PVOID ObjectType,
    IN OUT PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE AccessMode,
    IN ULONG Attributes,
    IN OUT PUNICODE_STRING CompleteName,
    IN OUT PUNICODE_STRING RemainingName,
    IN OUT PVOID Context OPTIONAL,
    IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
    OUT PVOID *Object)
{
    KdPrint(("Hook Success\n"));

    return g_OldFun(ParseObject, ObjectType, AccessState, AccessMode, Attributes,
        CompleteName,
        RemainingName, Context, SecurityQos, Object);
}
OBGETOBJECTTYPE g_OBGetObjectType;
//获得一个函数地址,这个函数能够通过内核对象得到内核对象的类型
VOID GetObjectTypeAddress()
{
    PUCHAR addr;
    UNICODE_STRING pslookup;
    RtlInitUnicodeString(&pslookup, L"ObGetObjectType");
    
    //               类似于应用层的GetProcAddress
    addr = (PUCHAR)MmGetSystemRoutineAddress(&pslookup);


    g_OBGetObjectType = (OBGETOBJECTTYPE)addr;
}
typedef struct _OBJECT_TYPE_INITIALIZER {
    USHORT Length;
    UCHAR ObjectTypeFlags;
    UCHAR CaseInsensitive;
    UCHAR UnnamedObjectsOnly;
    UCHAR  UseDefaultObject;
    UCHAR  SecurityRequired;
    UCHAR MaintainHandleCount;
    UCHAR MaintainTypeList;
    UCHAR SupportsObjectCallbacks;
    UCHAR CacheAligned;
    ULONG ObjectTypeCode;
    BOOLEAN InvalidAttributes;
    GENERIC_MAPPING GenericMapping;
    BOOLEAN   ValidAccessMask;
    BOOLEAN   RetainAccess;
    POOL_TYPE PoolType;
    BOOLEAN DefaultPagedPoolCharge;
    BOOLEAN DefaultNonPagedPoolCharge;
    PVOID DumpProcedure;
    ULONG OpenProcedure;
    PVOID CloseProcedure;
    PVOID DeleteProcedure;
    ULONG ParseProcedure;
    ULONG SecurityProcedure;
    ULONG QueryNameProcedure;
    UCHAR OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
typedef struct _OBJECT_TYPE {
    LIST_ENTRY TypeList;
    UNICODE_STRING Name;
    PVOID DefaultObject;
    ULONG Index;
    ULONG TotalNumberOfObjects;
    ULONG TotalNumberOfHandles;
    ULONG HighWaterNumberOfObjects;
    ULONG HighWaterNumberOfHandles;
    OBJECT_TYPE_INITIALIZER TypeInfo;
    ULONG  TypeLock;
    ULONG   Key;
    LIST_ENTRY   CallbackList;
} OBJECT_TYPE, *POBJECT_TYPE;
HANDLE KernelCreateFile(
    IN PUNICODE_STRING pstrFile, // 文件路径符号链接
    IN BOOLEAN         bIsDir)   // 是否为文件夹
{
    HANDLE          hFile = NULL;
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    IO_STATUS_BLOCK StatusBlock = { 0 };
    ULONG           ulShareAccess =
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
    ULONG           ulCreateOpt =
        FILE_SYNCHRONOUS_IO_NONALERT;
    // 1. 初始化OBJECT_ATTRIBUTES的内容
    OBJECT_ATTRIBUTES objAttrib = { 0 };
    ULONG             ulAttributes =
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE;
    InitializeObjectAttributes(
        &objAttrib,    // 返回初始化完毕的结构体
        pstrFile,      // 文件对象名称
        ulAttributes,  // 对象属性
        NULL, NULL);   // 一般为NULL
    // 2. 创建文件对象
    ulCreateOpt |= bIsDir ?
    FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE;
    Status = ZwCreateFile(
        &hFile,                // 返回文件句柄
        GENERIC_ALL,           // 文件操作描述
        &objAttrib,            // OBJECT_ATTRIBUTES
        &StatusBlock,          // 接受函数的操作结果
        0,                     // 初始文件大小
        FILE_ATTRIBUTE_NORMAL, // 新建文件的属性
        ulShareAccess,         // 文件共享方式
        FILE_OPEN_IF,          // 文件存在则打开不存在则创建
        ulCreateOpt,           // 打开操作的附加标志位
        NULL,                  // 扩展属性区
        0);                   // 扩展属性区长度
    if (!NT_SUCCESS(Status))
        return (HANDLE)-1;
    return hFile;
}
void OnHook()
{
    //1 随便打开一个文件,得到一个文件对象
    UNICODE_STRING ustrFilePath;
    RtlInitUnicodeString(&ustrFilePath,
        L"\\??\\D:\\123.txt");
    HANDLE hFile = KernelCreateFile(&ustrFilePath, FALSE);
    PVOID pObject;
    ObReferenceObjectByHandle(hFile, GENERIC_ALL, NULL, KernelMode, &pObject, NULL);

    //2 通过这个文件对象得到OBJECT_TYPE这个结构体
    OBJECT_TYPE * FileType = NULL;
    FileType = (OBJECT_TYPE *)g_OBGetObjectType(pObject);
    //3 把这个函数地址保存起来
    g_OldFun = (PARSEPRODECEDURE)FileType->TypeInfo.ParseProcedure;
    //4 把这个函数地址替换为自己的函数。
    FileType->TypeInfo.ParseProcedure = (ULONG)NewParseProcedure;
}

void OffHook()
{

}

NTSTATUS DriverEntry(
    PDRIVER_OBJECT  pDriver,
    PUNICODE_STRING strRegPath)
{
    // 避免编译器报未引用参数的警告
    UNREFERENCED_PARAMETER(strRegPath);
    // 打印一行字符串,并注册驱动卸载函数,以便于驱动卸载
    DbgBreakPoint();//_asm int 3
    __try
    {
        GetObjectTypeAddress();
        OnHook();
    }
    except(1)
    {
        KdPrint(("掠过一个异常\n"));
    }
    KdPrint(("My First Dirver!"));
    pDriver->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT objDriver) {
    // 避免编译器报未引用参数的警告
    UNREFERENCED_PARAMETER(objDriver);
    // 什么也不做,只打印一行字符串
    KdPrint(("My Dirver is unloading..."));
}

===============
注册表操作

#include <ntifs.h>
//创建键
void RegCreateKey(LPWSTR KeyName) {
    OBJECT_ATTRIBUTES objectAttributes;
    UNICODE_STRING usKeyName;
    NTSTATUS ntStatus;
    HANDLE hRegister;
    RtlInitUnicodeString(&usKeyName, KeyName);
    InitializeObjectAttributes(&objectAttributes,
        &usKeyName,
        OBJ_CASE_INSENSITIVE,//对大小写敏感
        NULL,
        NULL);
    ntStatus = ZwCreateKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes,
        0, NULL, REG_OPTION_NON_VOLATILE, NULL);
    if (NT_SUCCESS(ntStatus)) {
        ZwClose(hRegister);
        DbgPrint("ZwCreateKey success!\n");
    }
    else
        DbgPrint("ZwCreateKey failed!\n");
}
//删除键
void RegDeleteKey(LPWSTR KeyName) {
    OBJECT_ATTRIBUTES objectAttributes;
    UNICODE_STRING usKeyName;
    NTSTATUS ntStatus;
    HANDLE hRegister;
    RtlInitUnicodeString(&usKeyName, KeyName);
    InitializeObjectAttributes(&objectAttributes,
        &usKeyName,
        OBJ_CASE_INSENSITIVE,//对大小写敏感
        NULL,
        NULL);
    ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);
    if (NT_SUCCESS(ntStatus)) {
        ntStatus = ZwDeleteKey(hRegister);
        ZwClose(hRegister);
        DbgPrint("ZwDeleteKey success!\n");
    }
    else
        DbgPrint("ZwDeleteKey failed!\n");
}
//设置键值
void RegSetValueKey(LPWSTR KeyName, LPWSTR ValueName, DWORD DataType, PVOID DataBuffer, DWORD DataLength) {
    OBJECT_ATTRIBUTES objectAttributes;
    UNICODE_STRING usKeyName, usValueName;
    NTSTATUS ntStatus;
    HANDLE hRegister;
    ULONG Type;
    RtlInitUnicodeString(&usKeyName, KeyName);
    RtlInitUnicodeString(&usValueName, ValueName);
    InitializeObjectAttributes(&objectAttributes,
        &usKeyName,
        OBJ_CASE_INSENSITIVE,//对大小写敏感
        NULL,
        NULL);
    ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);
    if (NT_SUCCESS(ntStatus))
    {
        ntStatus = ZwSetValueKey(hRegister, &usValueName, 0, DataType, DataBuffer, DataLength);
        ZwFlushKey(hRegister);
        ZwClose(hRegister);
        DbgPrint("ZwSetValueKey success!\n");
    }
    else
        DbgPrint("ZwSetValueKey failed!\n");
}
//读取键值
NTSTATUS RegQueryValueKey(LPWSTR KeyName, LPWSTR ValueName,
    PKEY_VALUE_PARTIAL_INFORMATION *pkvpi)
{
    ULONG ulSize;
    NTSTATUS ntStatus;
    PKEY_VALUE_PARTIAL_INFORMATION pvpi;
    OBJECT_ATTRIBUTES objectAttributes;
    HANDLE hRegister;
    UNICODE_STRING usKeyName;
    UNICODE_STRING usValueName;
    RtlInitUnicodeString(&usKeyName, KeyName);
    RtlInitUnicodeString(&usValueName, ValueName);
    InitializeObjectAttributes(&objectAttributes,
        &usKeyName,
        OBJ_CASE_INSENSITIVE,//对大小写敏感
        NULL,
        NULL);
    ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);

    ntStatus = ZwQueryValueKey(hRegister,
        &usValueName,
        KeyValuePartialInformation,
        NULL,
        0,
        &ulSize);
    if (ntStatus == STATUS_OBJECT_NAME_NOT_FOUND || ulSize == 0)
    {
        DbgPrint("ZwQueryValueKey 1 failed!\n");
        return STATUS_UNSUCCESSFUL;
    }
    pvpi = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(PagedPool, ulSize);
    ntStatus = ZwQueryValueKey(hRegister,
        &usValueName,
        KeyValuePartialInformation,
        pvpi,
        ulSize,
        &ulSize);
    if (!NT_SUCCESS(ntStatus))
    {
        DbgPrint("ZwQueryValueKey 2 failed!\n");
        return STATUS_UNSUCCESSFUL;
    }
    //这里的pvpi是没有释放的用完要释放。
    ExFreePool(pvpi);
    *pkvpi = pvpi;
    DbgPrint("ZwQueryValueKey success!\n");
    return STATUS_SUCCESS;
}

//删除键值
void RegDeleteValueKey(LPWSTR KeyName, LPWSTR ValueName) {
    OBJECT_ATTRIBUTES objectAttributes;
    UNICODE_STRING usKeyName, usValueName;
    NTSTATUS ntStatus;
    HANDLE hRegister;
    RtlInitUnicodeString(&usKeyName, KeyName);
    RtlInitUnicodeString(&usValueName, ValueName);
    InitializeObjectAttributes(&objectAttributes,
        &usKeyName,
        OBJ_CASE_INSENSITIVE,//对大小写敏感
        NULL,
        NULL);
    ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);
    if (NT_SUCCESS(ntStatus))
    {
        ntStatus = ZwDeleteValueKey(hRegister, &usValueName);
        ZwFlushKey(hRegister);
        ZwClose(hRegister);
        DbgPrint("ZwDeleteValueKey success!\n");
    }
    else
        DbgPrint("ZwDeleteValueKey failed!\n");
}
//枚举子健
VOID EnumSubKeyTest() {
    WCHAR MY_KEY_NAME[] = L"\\Registry\\Machine\\Software";
    UNICODE_STRING RegUnicodeString;
    HANDLE hRegister;
    OBJECT_ATTRIBUTES objectAttributes;
    NTSTATUS ntStatus;
    ULONG ulSize, i;
    UNICODE_STRING uniKeyName;
    PKEY_FULL_INFORMATION pfi;
    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&RegUnicodeString, MY_KEY_NAME);
    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &RegUnicodeString,
        OBJ_CASE_INSENSITIVE,//对大小写敏感   
        NULL, NULL );
                             //打开注册表

        ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);
    if (NT_SUCCESS(ntStatus)) {
        DbgPrint("Open register successfully\n");
    }
    if (NT_SUCCESS(ntStatus))
    {
        DbgPrint("Open register successfully\n");
    }
    //第一次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的长度
    ZwQueryKey(hRegister, KeyFullInformation, NULL, 0, &ulSize);
    pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize);
    //第二次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的数据
    ZwQueryKey(hRegister, KeyFullInformation, pfi, ulSize, &ulSize);
    for (i = 0; i < pfi->SubKeys; i++)
    {
        PKEY_BASIC_INFORMATION pbi;
        //第一次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的长度
        ZwEnumerateKey(hRegister, i, KeyBasicInformation, NULL, 0, &ulSize);
        pbi = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, ulSize);
        //第二次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的数据
        ZwEnumerateKey(hRegister, i, KeyBasicInformation, pbi, ulSize, &ulSize);
        uniKeyName.Length = (USHORT)pbi->NameLength;
        uniKeyName.MaximumLength = (USHORT)pbi->NameLength;
        uniKeyName.Buffer = pbi->Name;
        DbgPrint("The %d sub item name:%wZ\n", i, &uniKeyName);
        ExFreePool(pbi);
    }
    ExFreePool(pfi);
    ZwClose(hRegister);
}
//枚举子健值
VOID EnumSubValueTest()
{
    WCHAR MY_KEY_NAME[] = L"\\Registry\\Machine\\Software\\Microsoft\\.NETFramework";
    UNICODE_STRING RegUnicodeString;
    HANDLE hRegister;
    OBJECT_ATTRIBUTES objectAttributes;
    ULONG ulSize, i;
    UNICODE_STRING uniKeyName;
    PKEY_FULL_INFORMATION pfi;
    NTSTATUS ntStatus;
    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&RegUnicodeString, MY_KEY_NAME);
    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &RegUnicodeString,

        OBJ_CASE_INSENSITIVE,//对大小写敏感
        NULL,
        NULL);
    //打开注册表
    ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);
    if (NT_SUCCESS(ntStatus))
    {
        DbgPrint("Open register successfully\n");
    }
    //查询VALUE的大小
    ZwQueryKey(hRegister, KeyFullInformation, NULL, 0, &ulSize);
    pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize);
    ZwQueryKey(hRegister, KeyFullInformation, pfi, ulSize, &ulSize);

    for (i = 0; i < pfi->Values; i++)
    {
        PKEY_VALUE_BASIC_INFORMATION pvbi;
        //查询单个VALUE的大小
        ZwEnumerateValueKey(hRegister, i, KeyValueBasicInformation, NULL, 0, &ulSize);
        pvbi = (PKEY_VALUE_BASIC_INFORMATION)ExAllocatePool(PagedPool, ulSize);
        //查询单个VALUE的详情
        ZwEnumerateValueKey(hRegister, i, KeyValueBasicInformation, pvbi, ulSize, &ulSize);
        uniKeyName.Length = (USHORT)pvbi->NameLength;
        uniKeyName.MaximumLength = (USHORT)pvbi->NameLength;
        uniKeyName.Buffer = pvbi->Name;
        DbgPrint("The %d sub value name:%wZ\n", i, &uniKeyName);
        if (pvbi->Type == REG_SZ)
            DbgPrint("The sub value type:REG_SZ\n");
        else if (pvbi->Type == REG_MULTI_SZ)
            DbgPrint("The sub value type:REG_MULTI_SZ\n");
        else if (pvbi->Type == REG_DWORD)
            DbgPrint("The sub value type:REG_DWORD\n");
        else if (pvbi->Type == REG_BINARY)
            DbgPrint("The sub value type:REG_BINARY\n");
        ExFreePool(pvbi);
    }
    ExFreePool(pfi);
    ZwClose(hRegister);
}

=====================
seh

#include <ntifs.h>


VOID DriverUnload(PDRIVER_OBJECT pDriver);


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

    __try
    {
        int *p = 0;
        *p = 100;
    }
    except(1)
    {
        KdPrint(("哈哈:掠过了一个异常"));
    }
    pDriver->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
    UNREFERENCED_PARAMETER(pDriver);
}

=========================
结束线程

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

======================
线程操作

#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 world");
    //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>
//获取操作系统版本
ULONG KernelGetVersion()
{
    ULONG NtBuildNumber;
    RTL_OSVERSIONINFOW osi =
    { sizeof(RTL_OSVERSIONINFOW) };
    RtlGetVersion(&osi);
    return osi.dwBuildNumber;
}

//获取时间
VOID Test_GetCurrentTime()
{
    LARGE_INTEGER CurrentTime;
    LARGE_INTEGER LocalTime;
    TIME_FIELDS   TimeFiled;
    // 1. 获取格林威治时间
    KeQuerySystemTime(&CurrentTime);
    // 2. 转换成本地时间
    ExSystemTimeToLocalTime(&CurrentTime, &LocalTime);
    // 3. 转换为时间字段
    RtlTimeToTimeFields(&LocalTime, &TimeFiled);
    DbgPrint("Time : %4d-%2d-%2d %2d:%2d:%2d\n",
        TimeFiled.Year, TimeFiled.Month, TimeFiled.Day,
        TimeFiled.Hour, TimeFiled.Minute, TimeFiled.Second);
}

================

注:
注册表
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter]
"DEFAULT"=dword:0000000f

上一篇 下一篇

猜你喜欢

热点阅读