0.driverbase-Wait函数和创建线程(sytem和本进程)

1. Wait函数

用户模式下的WaitForSingleObject和WaitForMultipleObject都是依赖内核模式下的KeWaitForSingleObject和KeWaitForMultipleObjects函数实现的,其声明如下:

NTSTATUS
  KeWaitForMultipleObjects(
	IN ULONG  Count,//
	IN PVOID  Object[],
	IN WAIT_TYPE  WaitType,
	IN KWAIT_REASON  WaitReason,
	IN KPROCESSOR_MODE  WaitMode,
	IN BOOLEAN  Alertable,//
	IN PLARGE_INTEGER  Timeout  OPTIONAL,
	IN PKWAIT_BLOCK  WaitBlockArray  OPTIONAL
	);
Alertable是一个布尔类型的值。它不同于WaitReason,这个参数以另一种方式影响系统行为,它决定等待是否可以提前终止以提交一个APC。如果等待发生在用户模式中,那么内存管理器就可以把线程的内核模式堆栈换出。如果驱动程序以自动变量(在堆栈中)形式创建事件对象,并且某个线程又在提升的IRQL级上调用了KeSetEvent,而此时该事件对象刚好又被换出内存,结果将产生一个bug check。所以我们应该总把alertable参数指定为FALSE,即在内核模式中等待。

Timeout是一个64位超时值的地址,单位为100纳秒。正数的超时表示一个从1601年1月1日起的绝对时间。调用KeQuerySystemTime函数可以获得当前系统时间。负数代表相对于当前时间的时间间隔。如果你指定了绝对超时,那么系统时钟的改变也将影响到你的超时时间。如果系统时间越过你指定的绝对时间,那么永远都不会超时。相反,如果你指定相对超时,那么你经过的超时时间将不受系统时钟改变的影响,指定为NULL表示永久等待


2.创建线程

内核下创建新线程使用PsCreateSystemThread

NTSTATUS
  PsCreateSystemThread(
	OUT PHANDLE  ThreadHandle,//得到新创建的线程句柄
	IN ULONG  DesiredAccess,//创建的权限
	IN POBJECT_ATTRIBUTES  ObjectAttributes  OPTIONAL,//一般设为NULL
	IN HANDLE  ProcessHandle  OPTIONAL,//如果是进程句柄,则线程属于指定的进程,如果NULL,则为系统进程
	OUT PCLIENT_ID  ClientId  OPTIONAL,//驱动创建时,设为NULL
	IN PKSTART_ROUTINE  StartRoutine,//新线程的运行地址
	IN PVOID  StartContext//新线程接收的参数
	);
系统进程指ID为4的System进程,创建的线程并须自己用PsTerminateSystemThread强制结束线程,否则线程是无法自动退出的,这个调用必须在IRQL=PASSIVE_LEVEL下进行
随手示例创建用户线程和系统线程:

#define  IOCTL_TEST2
			 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS¦FILE_WRITE_ACCESS)
 
#pragma  code_seg("PAGE")
VOID SystemThread(PVOID pContext)
{
	KdPrint(("Entry SystemThreadn"));
 
	PEPROCESS pEProcess = IoGetCurrentProcess();
	PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);
	KdPrint(("This Thread run in %s processn", ProcessName));
	PsTerminateSystemThread(STATUS_SUCCESS);
 
	KdPrint(("Leave SystemThreadn"));
}
 
#pragma  code_seg("PAGE")
VOID MyThread(PVOID pContext)
{
	KdPrint(("Entry MyThread:%sn", (CHAR*)pContext));
 
	PEPROCESS pEProcess = IoGetCurrentProcess();
	PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);
	KdPrint(("This Thread run in %s processn", ProcessName));
	PsTerminateSystemThread(STATUS_SUCCESS);
 
	KdPrint(("Leave MyThreadn"));
}
 
#pragma code_seg("PAGE")
VOID CreateThreadTest()
{
	HANDLE hSysThread = NULL;
	HANDLE hMyThread = NULL;
 
	CHAR *p = "parameter";
	NTSTATUS status = PsCreateSystemThread
		(&hSysThread, 0, NULL, NULL, NULL, SystemThread, NULL);
 
	status = PsCreateSystemThread
		(&hMyThread, 0, NULL, NtCurrentProcess(), NULL, MyThread, (PVOID)p);
 
}

调用方式:使用demo发个IO控制码过去,调用CreateThreadTest即可



你可能感兴趣的:(0.driverbase-Wait函数和创建线程(sytem和本进程))