驱动牛犊
|
阅读:2300回复:0
Regmon(2)
if(NT_SUCCESS(ntStatus))
{ 创建符号连接,以便GUI能够指名,访问这个驱动/设备 创建每个需要处理的方法的分发点 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RegmonDispatch; #if DBG DriverObject->DriverUnload = RegmonUnload; #end if } if(!NT_SUCCESS(ntStatus)) { DbgPrint((“Regmon: Failed to create our device!\n”)); 发生错误,清理环境(资源等) if(GUIDevice) IoDeleteDevice(GUIDevice); IoDeleteSymbolicLink(&deviceLinkUnicodeString); return ntStatus; } 初始化互斥量 MUTEX_INIT(StoreMutex); MUTEX_INIT(HashMutex); MUTEX_INIT(FilterMutex); 初始化根键长度 for(I = 0; I < NUMROOTKEYS; I ++) { RootKey[I].RootNameLen = strlen(RootKey[I].RootName; } for(I = 0; I < 2; I ++) { CurrentUser[I].RootNameLen = strlen(CurrentUser[I].RootName; } 系统表数据结构指针,一个NTOSKRNL导出 ServiceTable = KeServiceDescriptorTable; 用户自定义的结构 DbgPrint((“HookRegistry:Servicetable:%x\n”, ServiceTable)); 获取进程名称的偏移 ProcessNameOffset = GetProcessNameOffset(); 这个函数是牛人自己写的。 分配初始化的输出缓冲区 Store = ExAllocatePool(PagePool, sizeof(*Store)); if(!Store) { IoDeleteDevice(GUIDevice); IoDeleteSymbolicLink(&deviceLinkUnicodeString); return STATUS_INSUFFICENT_RESOURCES; } Store->Len = 0; Store->Next = NULL; NumStore = 1; 如果我们是个启动设备则开始记日志 if(startType != SERVICE_DEMAND_START) { 初始化日志 BoolLogging = TRUE; KeInitializeEvent(&LoggingEvent, SynchronizationEvent, FALSE); GUIActive = TRUE; Fileltet = BootFilter; RegmonUpdateFilters(); HookRegisters(); 告诉用户,日志模式已经开启 RtlInitUnicodeString(&bootMessageUnicodeString, bootMessage); ZwDisplayString(&bootMessageUnicodeString); 注册关闭通知 IoRegisterShutdonwNotification注册一个驱动提供的系统关闭通知函数,在系统被完全关闭之前调用。 IoRegisterShutdown Notification(GUIDevice); } return STATUS_SUCCESS; } RegmonDispatch 这个函数处理设备的请求。需要显示处理的请求来自GUI。当然,当GUI建立,关闭合驱动的通信时,也需要处理Create,Close。 NTSTAUTS RegmonDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION irpStack; 当前堆栈 PVOID inputBuffer; PVOID outputBuffer; ULONG inputBufferLength; ULONG outputBufferLength; ULONG ioControlCode; PSTORE_BUF old; WORK_QUEUE_ITEM workItem; 设置处理成功 Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; 获取Irp中当前位置的指针,这就是代码和参数定位的地方 irpStack = IoGetCurrentIrpStackLocation(Irp); inputBuffer = Irp->AssociatedIrp.SystemBuffer; inputBufferLength = iprStack->Parameters.DeviceIoControl.InputBufferLength; outputBuffer = Irp->AssociatedIrp.SystemBuffer; outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; switch(irpStack->MajorFunction) { case IRP_MJ_CREATE: DbgPrint((“Regmon: IRP_MJ_CREATE\n”)); 关闭启动日志 if(BootLogging) { BootLogging = FALSE; IoUnregisterShutdownNotification(DeviceObject); MUTEX_WAIT(StoreMutex); ExInitializeWorkItem(&workItem, RegmonCloseBootLog, 0); 这个函数已经过期,应该使用IoAllocateWorkItem。返回一个指向私有结构IO_WORKITEM的指针。驱动不应该以任何形式访问这个结构! ExQueueWorkItem(&workItem, CriticalWorkQueue); 这个函数也过期了,应该使用IoQueueWorkItem。插入一个指定的工作项到队列中,这个队列由系统工作线程访问,系统工作线程从队列中移出一个工作项,并调用其中的回调函数。 KeWaitForSingleObject(&LoggingEvent, Executive, KernelMode, FALSE, NULL); MUTEX_RELEASE(StoreMutex); } Sequence = 0; GUIActive = TRUE; DbgPrint((“GUI Active: %d\n”, GUIActive)); break; } } |
|