驱动小程序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