NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING str) { UNREFERENCED_PARAMETER(driver); UNREFERENCED_PARAMETER(str); dri = driver; driver->DriverUnload = unload; for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { driver->MajorFunction[i] = dispatch; } PFILE_OBJECT file; UNICODE_STRING tcpname; UNICODE_STRING udpname; UNICODE_STRING ipname; RtlInitUnicodeString(&tcpname, TCP); RtlInitUnicodeString(&udpname, UDP); RtlInitUnicodeString(&ipname, IP); IoGetDeviceObjectPointer(&udpname, FILE_ALL_ACCESS, &file, &udpreal); ObfDereferenceObject(file); IoGetDeviceObjectPointer(&tcpname, FILE_ALL_ACCESS, &file, &tcpreal); ObfDereferenceObject(file); IoGetDeviceObjectPointer(&ipname, FILE_ALL_ACCESS, &file, &ipreal); ObfDereferenceObject(file); attach(&tcpname, DEVTYPE_TCP); attach(&udpname, DEVTYPE_UDP); attach(&ipname, DEVTYPE_IP); return STATUS_SUCCESS; }
// Remembers a SYSTEM token and its owner name if applicable _Use_decl_annotations_ static bool EopmonpCheckProcessToken(HANDLE pid, void* context) { PAGED_CODE(); UNREFERENCED_PARAMETER(context); const char* NTAPI PsGetProcessImageFileName(_In_ PEPROCESS Process); // Get EPROCESS PEPROCESS process = nullptr; auto status = PsLookupProcessByProcessId(pid, &process); if (!NT_SUCCESS(status)) { return true; } // Test if a process name of this pid matches with any of known system // processes. const auto process_name = PsGetProcessImageFileName(process); for (auto system_process_name : kEopmonpSystemProcessNames) { if (!RtlEqualMemory(process_name, system_process_name, strlen(system_process_name) + 1)) { continue; } // System process found const auto token = PsReferencePrimaryToken(process); // Initialize g_eopmonp_offset_to_token if not yet if (!g_eopmonp_offset_to_token && !EopmonpInitTokenOffset(process, token)) { PsDereferencePrimaryToken(token); ObfDereferenceObject(process); return false; // error. cannot continue } // PLACE TO IMPROVE: // EopMon updates a list of system processes' tokens and IDs only once, // while some of them like csrss.exe and winlogon.exe can be terminated and // re-launched when a use logout and logon to the system. One solution would // be installing process notification callback and maintain the latest // system process list. g_eopmonp_system_process_tokens->emplace_back(token, system_process_name); g_eopmonp_system_process_ids->push_back(pid); HYPERPLATFORM_LOG_INFO("System Token %p with PID=%Iu %s", token, pid, system_process_name); PsDereferencePrimaryToken(token); } ObfDereferenceObject(process); return true; }
NTSTATUS OpenProcess( IN ULONG uPID, OUT PHANDLE pHandle, IN ACCESS_MASK DesiredAccess) { NTSTATUS rtStatus = STATUS_SUCCESS; PEPROCESS pEProcess = NULL; HANDLE hTagProcess = NULL; PULONG uPsProcessType = 0; UNICODE_STRING StrType; rtStatus = PsLookupProcessByProcessId((HANDLE)uPID, &pEProcess); if (NT_SUCCESS(rtStatus)) { RtlInitUnicodeString(&StrType, L"PsProcessType"); uPsProcessType = (PULONG)MmGetSystemRoutineAddress(&StrType); if (uPsProcessType) { rtStatus = ObOpenObjectByPointer(pEProcess, 0, 0, DesiredAccess, (POBJECT_TYPE)*uPsProcessType, UserMode, &hTagProcess); if (NT_SUCCESS(rtStatus)) { *pHandle = hTagProcess; } } ObfDereferenceObject(pEProcess); } return rtStatus; }
NTSTATUS GetFilterDriverByDriverName(WCHAR *wzDriverName, PFILTER_DRIVER FilterDriverInfor, FILTER_TYPE Type) { NTSTATUS Status = STATUS_UNSUCCESSFUL; UNICODE_STRING uniDriverName; PDRIVER_OBJECT DriverObject = NULL; POBJECT_TYPE DriverObjectType = *IoDriverObjectType; if (!DriverObjectType) { return Status; } RtlInitUnicodeString(&uniDriverName, wzDriverName); Status = ObReferenceObjectByName( &uniDriverName, OBJ_CASE_INSENSITIVE, NULL, 0, DriverObjectType, KernelMode, NULL, (PVOID*)&DriverObject); if (NT_SUCCESS(Status) && DriverObject) { PDEVICE_OBJECT DeviceObject = NULL; for ( DeviceObject = DriverObject->DeviceObject; DeviceObject; DeviceObject = DeviceObject->NextDevice ) { PDRIVER_OBJECT AttachedDriverObject = DeviceObject->DriverObject; PDEVICE_OBJECT AttachDeviceObject = NULL; for ( AttachDeviceObject = DeviceObject->AttachedDevice; AttachDeviceObject; AttachDeviceObject = AttachDeviceObject->AttachedDevice ) { Status = AddFilterInfo( AttachDeviceObject, AttachedDriverObject, FilterDriverInfor, Type ); AttachedDriverObject = AttachDeviceObject->DriverObject; } } ObfDereferenceObject(DriverObject); } return Status; }
// Gets a creation time of the process _Use_decl_annotations_ static LONGLONG EopmonpGetProcessCreateTimeQuadPart( HANDLE pid) { PAGED_CODE(); PEPROCESS process = nullptr; auto status = PsLookupProcessByProcessId(pid, &process); if (!NT_SUCCESS(status)) { return 0; } const auto create_time = PsGetProcessCreateTimeQuadPart(process); ObfDereferenceObject(process); return create_time; }
void testRoutine(_In_ PDEVICE_OBJECT pDeviceObject, _In_opt_ PVOID pContext){ UNREFERENCED_PARAMETER(pDeviceObject); UNREFERENCED_PARAMETER(pContext); PFILE_OBJECT pFileObj; PDEVICE_OBJECT pDevObj; NTSTATUS status = STATUS_UNSUCCESSFUL; if (!pContext){ DbgPrint("pcontext null"); return; } PMY_WORK_CONTEXT pWorkContext = (PMY_WORK_CONTEXT)pContext; status = IoGetDeviceObjectPointer(pWorkContext->pSymlink, 0, &pFileObj, &pDevObj); if (status){ DbgPrint("failed to access devobj!%lX", status); return; } DbgPrint("not failed to access devobj!%lX", status); ObfDereferenceObject(pFileObj); ObfDereferenceObject(pDevObj); //return; }
PCHAR GetProcessNameByProcessId(HANDLE ProcessId) { NTSTATUS st = STATUS_UNSUCCESSFUL; PEPROCESS ProcessObj = NULL; PCHAR string = NULL; st = PsLookupProcessByProcessId(ProcessId, &ProcessObj); if (NT_SUCCESS(st)) { string = PsGetProcessImageFileName(ProcessObj); ObfDereferenceObject(ProcessObj); } return string; }
VOID NTAPI PopProcessShutDownLists(VOID) { PPOP_SHUTDOWN_WAIT_ENTRY ShutDownWaitEntry; PWORK_QUEUE_ITEM WorkItem; PLIST_ENTRY ListEntry; /* First signal the shutdown event */ KeSetEvent(&PopShutdownEvent, IO_NO_INCREMENT, FALSE); /* Acquire the shutdown list lock */ KeAcquireGuardedMutex(&PopShutdownListMutex); /* Block any further attempts to register a shutdown event */ PopShutdownListAvailable = FALSE; /* Release the list lock, since we are exclusively using the lists now */ KeReleaseGuardedMutex(&PopShutdownListMutex); /* Process the shutdown queue */ while (!IsListEmpty(&PopShutdownQueue)) { /* Get the head entry */ ListEntry = RemoveHeadList(&PopShutdownQueue); WorkItem = CONTAINING_RECORD(ListEntry, WORK_QUEUE_ITEM, List); /* Call the shutdown worker routine */ WorkItem->WorkerRoutine(WorkItem->Parameter); } /* Now process the shutdown thread list */ while (PopShutdownThreadList != NULL) { /* Get the top entry and remove it from the list */ ShutDownWaitEntry = PopShutdownThreadList; PopShutdownThreadList = PopShutdownThreadList->NextEntry; /* Wait for the thread to finish and dereference it */ KeWaitForSingleObject(ShutDownWaitEntry->Thread, 0, 0, 0, 0); ObfDereferenceObject(ShutDownWaitEntry->Thread); /* Finally free the entry */ ExFreePoolWithTag(ShutDownWaitEntry, 0); } }
// Terminates a given process and wait for its completion. _Use_decl_annotations_ static void EopmonpTerminateProcessWorkerRoutine( void* parameter) { PAGED_CODE(); // HYPERPLATFORM_COMMON_DBG_BREAK(); const auto context = reinterpret_cast<EopmonWorkQueueItem*>(parameter); const auto dodgy_pid = context->dodgy_pid; const auto system_process_name = context->system_process_name; const auto process_handle = EopmonpOpenProcess(dodgy_pid); if (!process_handle) { goto exit; } // Terminate it and wait auto status = EopmonpTerminateProcessTree(process_handle, dodgy_pid); if (status == STATUS_PROCESS_IS_TERMINATING) { goto exit_with_close; } // log stuff const auto process_path = EopmonpGetProcessPathByHandle(process_handle); if (!process_path) { HYPERPLATFORM_LOG_INFO( "Exploitation detected. Process %Iu has been killed. Stolen token from " "%s", dodgy_pid, system_process_name); goto exit_with_close; } PEPROCESS process = nullptr; status = PsLookupProcessByProcessId(dodgy_pid, &process); if (!NT_SUCCESS(status)) { HYPERPLATFORM_LOG_INFO( "Exploitation detected. Process %Iu has been killed. Stolen token from " "%s. Image= %wZ", dodgy_pid, system_process_name, process_path); ExFreePoolWithTag(process_path, kHyperPlatformCommonPoolTag); goto exit_with_close; } const auto token = PsReferencePrimaryToken(process); HYPERPLATFORM_LOG_INFO( "Exploitation detected. Process %Iu has been killed. Stolen token %p " "from %s. Image= %wZ", dodgy_pid, token, system_process_name, process_path); PsDereferencePrimaryToken(token); ObfDereferenceObject(process); ExFreePoolWithTag(process_path, kHyperPlatformCommonPoolTag); exit_with_close:; ZwClose(process_handle); // Delete this PID from ones being marked as already queued for (auto& pid_being_killed : g_eopmonp_processes_being_killed) { if (pid_being_killed == dodgy_pid) { pid_being_killed = nullptr; } } exit:; ExFreePoolWithTag(context, kHyperPlatformCommonPoolTag); }
NTSTATUS KernelOpenFile(wchar_t *FileFullName, PHANDLE FileHandle, ACCESS_MASK DesiredAccess, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions) { WCHAR SystemRootName[32]=L"\\SystemRoot"; WCHAR *FileNodeName=NULL; UNICODE_STRING FilePath; PDEVICE_OBJECT RealDevice,DeviceObject; NTSTATUS status=STATUS_UNSUCCESSFUL; PFILE_OBJECT FileObject; FileNodeName = (WCHAR*)ExAllocatePool(NonPagedPool,260*2); if (FileNodeName==NULL) { return status; } RtlZeroMemory(FileNodeName,260*2); if (_wcsnicmp(FileFullName,SystemRootName,wcslen(SystemRootName)) == 0) { int Len; if(!GetWindowsRootName(FileNodeName)) { ExFreePool(FileNodeName); return status; } Len=wcslen(SystemRootName); wcscat(FileNodeName,&FileFullName[Len]); } else { if (FileFullName[1]!=0x003A||FileFullName[2]!=0x005C) { return status; } wcscpy(FileNodeName,&FileFullName[2]); } if(!GetDeviceObjectFromFileFullName(FileFullName,&RealDevice,&DeviceObject)) { ExFreePool(FileNodeName); return status; } RtlInitUnicodeString(&FilePath,FileNodeName); status = IrpCreateFile(&FilePath,DesiredAccess,FileAttributes,ShareAccess,CreateDisposition,CreateOptions,DeviceObject,RealDevice,&FileObject); if (!NT_SUCCESS(status)) { ExFreePool(FileNodeName); return status; } status=ObOpenObjectByPointer( FileObject, OBJ_KERNEL_HANDLE, //verifier下测试要指定OBJ_KERNEL_HANDLE 0, DesiredAccess|0x100000, *IoFileObjectType, 0, FileHandle); ObfDereferenceObject(FileObject); return status; }
BOOL GetDeviceObjectFromFileFullName(WCHAR *FileFullName,PDEVICE_OBJECT *RealDevice, PDEVICE_OBJECT *DeviceObject) { WCHAR wRootName[32]={0}; UNICODE_STRING RootName; OBJECT_ATTRIBUTES ObjectAttributes={0}; NTSTATUS status; HANDLE hFile; IO_STATUS_BLOCK IoStatus; PFILE_OBJECT FileObject; if (FileFullName[0]==0x005C) { wcscpy(wRootName,L"\\SystemRoot"); } else { wcscpy(wRootName,L"\\DosDevices\\*:\\"); wRootName[12]=FileFullName[0]; } RtlInitUnicodeString(&RootName,wRootName); InitializeObjectAttributes(&ObjectAttributes, &RootName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); status = IoCreateFile( &hFile, SYNCHRONIZE, &ObjectAttributes, &IoStatus, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, 0, NULL, IO_NO_PARAMETER_CHECKING); if (!NT_SUCCESS(status)) { return FALSE; } status=ObReferenceObjectByHandle(hFile,1,*IoFileObjectType,KernelMode,&FileObject,NULL); if (!NT_SUCCESS(status)) { ZwClose(hFile); return FALSE; } if(!IoGetFileSystemVpbInfo(FileObject,DeviceObject,RealDevice)) { ObfDereferenceObject(FileObject); ZwClose(hFile); return FALSE; } ObfDereferenceObject(FileObject); ZwClose(hFile); return TRUE; }
//----- (08000DCF) -------------------------------------------------------- NTSTATUS HookDispatch( PDRIVER_OBJECT DriverObject, ULONG DiskIndex ) { PCONFIGURATION_INFORMATION ConfigInfo; NTSTATUS status; PIRP Irp; CHAR SourceString[64] = ""; STRING astr; UNICODE_STRING ustr; PFILE_OBJECT FileObject, FileObject1; PDEVICE_OBJECT DeviceObject, DeviceObject1; PDRIVE_LAYOUT_INFORMATION LayoutInfo; KEVENT Event; IO_STATUS_BLOCK iosb; OBJECT_ATTRIBUTES oa; HANDLE Handle; ULONG i, j; ConfigInfo = IoGetConfigurationInformation(); for(i = DiskIndex; i < ConfigInfo->DiskCount; i++) { sprintf(SourceString, "\\Device\\Harddisk%d\\Partition0", i); RtlInitAnsiString(&astr, SourceString); RtlAnsiStringToUnicodeString(&ustr, &astr, TRUE); status = IoGetDeviceObjectPointer(&ustr, 0x80, &FileObject, &DeviceObject); RtlFreeUnicodeString(&ustr); if (!NT_SUCCESS(status)) { continue; } AddDeviceToHookEntry(FileObject->DeviceObject, i, 0); LayoutInfo = (PDRIVE_LAYOUT_INFORMATION)ExAllocatePool(0, 0x2000); if ( LayoutInfo ) { KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_LAYOUT, DeviceObject, NULL, 0, LayoutInfo, 0x2000, FALSE, &Event, &iosb); if ( Irp ) { status = IoCallDriver(DeviceObject, Irp); if ( status == STATUS_PENDING ) { KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); status = iosb.Status; } if ( NT_SUCCESS(status) ) { for(j = 1; j < LayoutInfo->PartitionCount; j++) { sprintf(SourceString, "\\Device\\Harddisk%d\\Partition%d", i, j); RtlInitAnsiString(&astr, SourceString); RtlAnsiStringToUnicodeString(&ustr, &astr, TRUE); status = IoGetDeviceObjectPointer(&ustr, 0x80, &FileObject1, &DeviceObject1); RtlFreeUnicodeString(&ustr); if (!NT_SUCCESS(status)) { continue; } AddDeviceToHookEntry(FileObject1->DeviceObject, i, j); ObfDereferenceObject(FileObject1); } } } ExFreePool(LayoutInfo); } ObfDereferenceObject(FileObject); } return status; }
Thread::~Thread() { //! Remove any otherwise persistent references to this instance ObfDereferenceObject(system_thread_handle); }
NTSTATUS ForceDelete( wchar_t *path ) { HANDLE fileHandle; NTSTATUS result; IO_STATUS_BLOCK ioBlock; DEVICE_OBJECT *device_object; void* object = NULL; OBJECT_ATTRIBUTES fileObject; wchar_t deviceName[14]; UNICODE_STRING uDeviceName; UNICODE_STRING uPath; EPROCESS *eproc = IoGetCurrentProcess(); //switch context to UserMode KeAttachProcess(eproc); //initialize file to delete variable g_fileToDelete = path; g_fileToDelete += 6; //take from \??\C:\example only \example //e.g "\??\C:\" memset(deviceName,0,sizeof(deviceName)); wcsncpy(deviceName,path,7); uDeviceName.Buffer = deviceName; uDeviceName.Length = 14; //file path to unicode string RtlInitUnicodeString(&uPath,path); InitializeObjectAttributes(&fileObject, &uDeviceName, OBJ_CASE_INSENSITIVE, NULL, NULL); result = ZwOpenFile(&fileHandle, SYNCHRONIZE, &fileObject, &ioBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE); if(result != STATUS_SUCCESS) { DbgPrint("Some problems with open file ;["); goto _end; } if ( !ObReferenceObjectByHandle(fileHandle, 0, 0, 0, &object, 0) ) { device_object = IoGetBaseFileSystemDeviceObject(object); ObfDereferenceObject(object); } ZwClose(fileHandle); InitializeObjectAttributes(&fileObject, &uPath, OBJ_CASE_INSENSITIVE, NULL, NULL); result = IoCreateFileSpecifyDeviceObjectHint( &fileHandle, SYNCHRONIZE | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES | FILE_READ_DATA, //0x100181 &fileObject, &ioBlock, 0, 0, FILE_SHARE_READ | FILE_SHARE_WRITE |FILE_SHARE_DELETE, //FILE_SHARE_VALID_FLAGS, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,//0x60, 0, 0, CreateFileTypeNone, 0, IO_IGNORE_SHARE_ACCESS_CHECK, device_object); if(result != STATUS_SUCCESS) { DbgPrint("error in IoCreateFileSpecifyDeviceObjectHint"); goto _end; } result = ObReferenceObjectByHandle(fileHandle, 0, 0, 0, &object, 0); if(result != STATUS_SUCCESS) { DbgPrint("error in ObReferenceObjectByHandle"); ZwClose(fileHandle); goto _end; } /* METHOD 1 */ ((FILE_OBJECT*)object)->SectionObjectPointer->ImageSectionObject = 0; ((FILE_OBJECT*)object)->DeleteAccess = 1; result = ZwDeleteFile(&fileObject); if(result != STATUS_SUCCESS) { DbgPrint("\n[+]error in ZwDeleteFile"); } ObDereferenceObject(object); ZwClose(fileHandle); result = ZwDeleteFile(&fileObject); if(result != STATUS_SUCCESS) { DbgPrint("\n[+]error in ZwDeleteFile"); /* METHOD 2 */ r0_fileToDelete(path); /* METHOD 3 If simple solutions did not help, try this one. */ hook_it(device_object) }
NTSTATUS NTAPI PciQueryForPciBusInterface(IN PPCI_FDO_EXTENSION FdoExtension) { PDEVICE_OBJECT AttachedDevice; IO_STATUS_BLOCK IoStatusBlock; KEVENT Event; NTSTATUS Status; PIRP Irp; PIO_STACK_LOCATION IoStackLocation; PPCI_BUS_INTERFACE_STANDARD PciInterface; PAGED_CODE(); ASSERT(PCI_IS_ROOT_FDO(FdoExtension)); /* Allocate space for the inteface */ PciInterface = ExAllocatePoolWithTag(NonPagedPool, sizeof(PCI_BUS_INTERFACE_STANDARD), PCI_POOL_TAG); if (!PciInterface) return STATUS_INSUFFICIENT_RESOURCES; /* Get the device the PDO is attached to, should be the Root (ACPI) */ AttachedDevice = IoGetAttachedDeviceReference(FdoExtension->PhysicalDeviceObject); /* Build an IRP for this request */ KeInitializeEvent(&Event, SynchronizationEvent, FALSE); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, AttachedDevice, NULL, 0, NULL, &Event, &IoStatusBlock); if (Irp) { /* Initialize the default PnP response */ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Information = 0; /* Make it a Query Interface IRP */ IoStackLocation = IoGetNextIrpStackLocation(Irp); ASSERT(IoStackLocation->MajorFunction == IRP_MJ_PNP); IoStackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; IoStackLocation->Parameters.QueryInterface.InterfaceType = &GUID_PCI_BUS_INTERFACE_STANDARD; IoStackLocation->Parameters.QueryInterface.Size = sizeof(GUID_PCI_BUS_INTERFACE_STANDARD); IoStackLocation->Parameters.QueryInterface.Version = PCI_BUS_INTERFACE_STANDARD_VERSION; IoStackLocation->Parameters.QueryInterface.Interface = (PINTERFACE)PciInterface; IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData = NULL; /* Send it to the root PDO */ Status = IoCallDriver(AttachedDevice, Irp); if (Status == STATUS_PENDING) { /* Wait for completion */ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = Irp->IoStatus.Status; } /* Check if an interface was returned */ if (!NT_SUCCESS(Status)) { /* No interface was returned by the root PDO */ FdoExtension->PciBusInterface = NULL; ExFreePoolWithTag(PciInterface, 0); } else { /* An interface was returned, save it */ FdoExtension->PciBusInterface = PciInterface; } /* Dereference the device object because we took a reference earlier */ ObfDereferenceObject(AttachedDevice); } else { /* Failure path, dereference the device object and set failure code */ if (AttachedDevice) ObfDereferenceObject(AttachedDevice); ExFreePoolWithTag(PciInterface, 0); Status = STATUS_INSUFFICIENT_RESOURCES; } /* Return status code to caller */ return Status; }