void testcommunication() { HANDLE port = INVALID_HANDLE_VALUE; UNICODE_STRING test1; RtlUnicodeStringInit(&test1, L"C:\\Program Files\\Microsoft\\filename.txt"); UNICODE_STRING folder; UNICODE_STRING file; NTSTATUS status = GetFolderAndFileFromFilePath(&test1, &folder, &file); status; typedef struct _a { UNICODE_STRING b; UNICODE_STRING c; } a; //maybe we could just provide raw memory access to the items selected in the listview? a ana; ana.b = folder; ana.c = file; HRESULT result = FilterConnectCommunicationPort(SECRETSTASH_PORT_NAME, NULL, NULL, NULL, NULL, &port); if (result == S_OK) { //CommandMessage message; //message.Command = HideAllFiles; UNICODE_STRING test; RtlUnicodeStringInit(&test, L"test"); //LPVOID buffer[4096 / sizeof(LPVOID)]; DWORD bytesReturned = 0; //use this to send data http://stackoverflow.com/questions/10986551/windows-driver-passing-strings-between-user-mode-and-kernel-mode-dynamically result = FilterSendMessage( port, //Port &ana, //Buffer containing the message to be sent sizeof(ana),//Size of the buffer above NULL, //Buffer that receives the reply NULL, //Size of the buffer above &bytesReturned //Amount of data that was actually written to the buffer above ); CloseHandle(port); } free(folder.Buffer); free(file.Buffer); }
VOID BBUnload( IN PDRIVER_OBJECT DriverObject ) { UNICODE_STRING deviceLinkUnicodeString; // Unregister notification PsSetCreateProcessNotifyRoutine( BBProcessNotify, TRUE ); // Cleanup physical regions BBCleanupProcessPhysList(); // Cleanup process mapping info BBCleanupProcessTable(); RtlUnicodeStringInit( &deviceLinkUnicodeString, DOS_DEVICE_NAME ); IoDeleteSymbolicLink( &deviceLinkUnicodeString ); IoDeleteDevice( DriverObject->DeviceObject ); return; }
PVOID GetKernelBase(OUT PULONG pSize) { NTSTATUS status = STATUS_SUCCESS; ULONG bytes = 0; PRTL_PROCESS_MODULES pMods = NULL; PVOID checkPtr = NULL; UNICODE_STRING routineName; ULONG i; // Already found if (g_KernelBase != NULL) { if (pSize) { *pSize = g_KernelSize; } return g_KernelBase; } RtlUnicodeStringInit (&routineName, L"NtOpenFile"); checkPtr = MmGetSystemRoutineAddress (&routineName); if (!checkPtr) { return NULL; } status = ZwQuerySystemInformation (SystemModuleInformation, 0, bytes, &bytes); if (bytes == 0) return NULL; pMods = (PRTL_PROCESS_MODULES)ExAllocatePoolWithTag (NonPagedPool, bytes, 'domP'); RtlZeroMemory (pMods, bytes); status = ZwQuerySystemInformation (SystemModuleInformation, pMods, bytes, &bytes); if (NT_SUCCESS(status)) { PRTL_PROCESS_MODULE_INFORMATION pMod = pMods->Modules; for (i = 0; i < pMods->NumberOfModules; i++) { if (checkPtr >= pMod[i].ImageBase && checkPtr < (PVOID)((PUCHAR)pMod[i].ImageBase + pMod[i].ImageSize)) { g_KernelBase = pMod[i].ImageBase; g_KernelSize = pMod[i].ImageSize; if (pSize) { *pSize = g_KernelSize; } } } } if (pMods) ExFreePoolWithTag (pMods, 'domP'); return g_KernelBase; }
NTSTATUS SarKsDeviceAdd(IN PKSDEVICE device) { NTSTATUS status; UNICODE_STRING referenceString; SarDriverExtension *extension = (SarDriverExtension *)IoGetDriverObjectExtension( device->FunctionalDeviceObject->DriverObject, DriverEntry); RtlUnicodeStringInit(&referenceString, SAR_CONTROL_REFERENCE_STRING + 1); status = IoRegisterDeviceInterface(device->PhysicalDeviceObject, &GUID_DEVINTERFACE_SYNCHRONOUSAUDIOROUTER, &referenceString, &extension->sarInterfaceName); if (!NT_SUCCESS(status)) { return status; } SAR_LOG("KSDevice was created for %p, dev interface: %wZ", device, &extension->sarInterfaceName); return status; }
NTSTATUS Ds4_PreparePdo(PWDFDEVICE_INIT DeviceInit, PUNICODE_STRING DeviceId, PUNICODE_STRING DeviceDescription) { NTSTATUS status; UNICODE_STRING buffer; // prepare device description status = RtlUnicodeStringInit(DeviceDescription, L"Virtual DualShock 4 Controller"); if (!NT_SUCCESS(status)) return status; // Set hardware IDs RtlUnicodeStringInit(&buffer, L"USB\\VID_054C&PID_05C4&REV_0100"); status = WdfPdoInitAddHardwareID(DeviceInit, &buffer); if (!NT_SUCCESS(status)) return status; RtlUnicodeStringCopy(DeviceId, &buffer); RtlUnicodeStringInit(&buffer, L"USB\\VID_054C&PID_05C4"); status = WdfPdoInitAddHardwareID(DeviceInit, &buffer); if (!NT_SUCCESS(status)) return status; // Set compatible IDs RtlUnicodeStringInit(&buffer, L"USB\\Class_03&SubClass_00&Prot_00"); status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer); if (!NT_SUCCESS(status)) return status; RtlUnicodeStringInit(&buffer, L"USB\\Class_03&SubClass_00"); status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer); if (!NT_SUCCESS(status)) return status; RtlUnicodeStringInit(&buffer, L"USB\\Class_03"); status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer); if (!NT_SUCCESS(status)) return status; return STATUS_SUCCESS; }
NTSTATUS Ds4_AssignPdoContext(WDFDEVICE Device, PPDO_IDENTIFICATION_DESCRIPTION Description) { NTSTATUS status; PDS4_DEVICE_DATA ds4 = Ds4GetData(Device); KdPrint(("Initializing DS4 context...\n")); // I/O Queue for pending IRPs WDF_IO_QUEUE_CONFIG pendingUsbQueueConfig, notificationsQueueConfig; // Create and assign queue for incoming interrupt transfer WDF_IO_QUEUE_CONFIG_INIT(&pendingUsbQueueConfig, WdfIoQueueDispatchManual); status = WdfIoQueueCreate(Device, &pendingUsbQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &ds4->PendingUsbInRequests); if (!NT_SUCCESS(status)) { KdPrint(("WdfIoQueueCreate failed 0x%x\n", status)); return status; } // Initialize periodic timer WDF_TIMER_CONFIG timerConfig; WDF_TIMER_CONFIG_INIT_PERIODIC(&timerConfig, Ds4_PendingUsbRequestsTimerFunc, DS4_QUEUE_FLUSH_PERIOD); // Timer object attributes WDF_OBJECT_ATTRIBUTES timerAttribs; WDF_OBJECT_ATTRIBUTES_INIT(&timerAttribs); // PDO is parent timerAttribs.ParentObject = Device; // Create timer status = WdfTimerCreate(&timerConfig, &timerAttribs, &ds4->PendingUsbInRequestsTimer); if (!NT_SUCCESS(status)) { KdPrint(("WdfTimerCreate failed 0x%x\n", status)); return status; } // Create and assign queue for user-land notification requests WDF_IO_QUEUE_CONFIG_INIT(¬ificationsQueueConfig, WdfIoQueueDispatchManual); status = WdfIoQueueCreate(Device, ¬ificationsQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &ds4->PendingNotificationRequests); if (!NT_SUCCESS(status)) { KdPrint(("WdfIoQueueCreate failed 0x%x\n", status)); return status; } // Load/generate MAC address // TODO: tidy up this region WDFKEY keyParams, keyTargets, keyDS, keySerial; UNICODE_STRING keyName, valueName; status = WdfDriverOpenParametersRegistryKey(WdfGetDriver(), STANDARD_RIGHTS_ALL, WDF_NO_OBJECT_ATTRIBUTES, &keyParams); if (!NT_SUCCESS(status)) { KdPrint(("WdfDriverOpenParametersRegistryKey failed 0x%x\n", status)); return status; } RtlUnicodeStringInit(&keyName, L"Targets"); status = WdfRegistryCreateKey(keyParams, &keyName, KEY_ALL_ACCESS, REG_OPTION_NON_VOLATILE, NULL, WDF_NO_OBJECT_ATTRIBUTES, &keyTargets); if (!NT_SUCCESS(status)) { KdPrint(("WdfRegistryCreateKey failed 0x%x\n", status)); return status; } RtlUnicodeStringInit(&keyName, L"DualShock"); status = WdfRegistryCreateKey(keyTargets, &keyName, KEY_ALL_ACCESS, REG_OPTION_NON_VOLATILE, NULL, WDF_NO_OBJECT_ATTRIBUTES, &keyDS); if (!NT_SUCCESS(status)) { KdPrint(("WdfRegistryCreateKey failed 0x%x\n", status)); return status; } DECLARE_UNICODE_STRING_SIZE(serialPath, 4); RtlUnicodeStringPrintf(&serialPath, L"%04d", Description->SerialNo); status = WdfRegistryCreateKey(keyDS, &serialPath, KEY_ALL_ACCESS, REG_OPTION_NON_VOLATILE, NULL, WDF_NO_OBJECT_ATTRIBUTES, &keySerial); if (!NT_SUCCESS(status)) { KdPrint(("WdfRegistryCreateKey failed 0x%x\n", status)); return status; } RtlUnicodeStringInit(&valueName, L"TargetMacAddress"); status = WdfRegistryQueryValue(keySerial, &valueName, sizeof(MAC_ADDRESS), &ds4->TargetMacAddress, NULL, NULL); KdPrint(("MAC-Address: %02X:%02X:%02X:%02X:%02X:%02X\n", ds4->TargetMacAddress.Vendor0, ds4->TargetMacAddress.Vendor1, ds4->TargetMacAddress.Vendor2, ds4->TargetMacAddress.Nic0, ds4->TargetMacAddress.Nic1, ds4->TargetMacAddress.Nic2)); if (status == STATUS_OBJECT_NAME_NOT_FOUND) { GenerateRandomMacAddress(&ds4->TargetMacAddress); status = WdfRegistryAssignValue(keySerial, &valueName, REG_BINARY, sizeof(MAC_ADDRESS), (PVOID)&ds4->TargetMacAddress); if (!NT_SUCCESS(status)) { KdPrint(("WdfRegistryAssignValue failed 0x%x\n", status)); return status; } } else if (!NT_SUCCESS(status)) { KdPrint(("WdfRegistryQueryValue failed 0x%x\n", status)); return status; } WdfRegistryClose(keySerial); WdfRegistryClose(keyDS); WdfRegistryClose(keyTargets); WdfRegistryClose(keyParams); return STATUS_SUCCESS; }
/// <summary> /// Get module base address by name /// </summary> /// <param name="pProcess">Target process</param> /// <param name="ModuleName">Nodule name to search for</param> /// <param name="isWow64">If TRUE - search in 32-bit PEB</param> /// <returns>Found address, NULL if not found</returns> PVOID BBGetUserModule( IN PEPROCESS pProcess, IN PUNICODE_STRING ModuleName, IN BOOLEAN isWow64 ) { ASSERT( pProcess != NULL ); if (pProcess == NULL) return NULL; // Protect from UserMode AV __try { LARGE_INTEGER time = { 0 }; time.QuadPart = -250ll * 10 * 1000; // 250 msec. // Wow64 process if (isWow64) { PPEB32 pPeb32 = (PPEB32)PsGetProcessWow64Process( pProcess ); if (pPeb32 == NULL) { DPRINT( "BlackBone: %s: No PEB present. Aborting\n", __FUNCTION__ ); return NULL; } // Wait for loader a bit for (INT i = 0; !pPeb32->Ldr && i < 10; i++) { DPRINT( "BlackBone: %s: Loader not intialiezd, waiting\n", __FUNCTION__ ); KeDelayExecutionThread( KernelMode, TRUE, &time ); } // Still no loader if (!pPeb32->Ldr) { DPRINT( "BlackBone: %s: Loader was not intialiezd in time. Aborting\n", __FUNCTION__ ); return NULL; } // Search in InLoadOrderModuleList for (PLIST_ENTRY32 pListEntry = (PLIST_ENTRY32)((PPEB_LDR_DATA32)pPeb32->Ldr)->InLoadOrderModuleList.Flink; pListEntry != &((PPEB_LDR_DATA32)pPeb32->Ldr)->InLoadOrderModuleList; pListEntry = (PLIST_ENTRY32)pListEntry->Flink) { UNICODE_STRING ustr; PLDR_DATA_TABLE_ENTRY32 pEntry = CONTAINING_RECORD( pListEntry, LDR_DATA_TABLE_ENTRY32, InLoadOrderLinks ); RtlUnicodeStringInit( &ustr, (PWCH)pEntry->BaseDllName.Buffer ); if (RtlCompareUnicodeString( &ustr, ModuleName, TRUE ) == 0) return (PVOID)pEntry->DllBase; } } // Native process else { PPEB pPeb = PsGetProcessPeb( pProcess ); if (!pPeb) { DPRINT( "BlackBone: %s: No PEB present. Aborting\n", __FUNCTION__ ); return NULL; } // Wait for loader a bit for (INT i = 0; !pPeb->Ldr && i < 10; i++) { DPRINT( "BlackBone: %s: Loader not intialiezd, waiting\n", __FUNCTION__ ); KeDelayExecutionThread( KernelMode, TRUE, &time ); } // Still no loader if (!pPeb->Ldr) { DPRINT( "BlackBone: %s: Loader was not intialiezd in time. Aborting\n", __FUNCTION__ ); return NULL; } // Search in InLoadOrderModuleList for (PLIST_ENTRY pListEntry = pPeb->Ldr->InLoadOrderModuleList.Flink; pListEntry != &pPeb->Ldr->InLoadOrderModuleList; pListEntry = pListEntry->Flink) { PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD( pListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks ); if (RtlCompareUnicodeString( &pEntry->BaseDllName, ModuleName, TRUE ) == 0) return pEntry->DllBase; } } } __except (EXCEPTION_EXECUTE_HANDLER) { DPRINT( "BlackBone: %s: Exception, Code: 0x%X\n", __FUNCTION__, GetExceptionCode() ); } return NULL; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_OBJECT deviceObject = NULL; UNICODE_STRING deviceName; UNICODE_STRING deviceLink; UNREFERENCED_PARAMETER( RegistryPath ); // Get OS Dependant offsets status = BBInitDynamicData( &dynData ); if (!NT_SUCCESS( status )) { DPRINT( "BlackBone: %s: Unsupported OS version. Aborting\n", __FUNCTION__ ); return status; } // Initialize some loader structures status = BBInitLdrData( (PKLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection ); if (!NT_SUCCESS( status )) return status; // // Globals init // InitializeListHead( &g_PhysProcesses ); RtlInitializeGenericTableAvl( &g_ProcessPageTables, &AvlCompare, &AvlAllocate, &AvlFree, NULL ); KeInitializeGuardedMutex( &g_globalLock ); // Setup process termination notifier status = PsSetCreateProcessNotifyRoutine( BBProcessNotify, FALSE ); if (!NT_SUCCESS( status )) { DPRINT( "BlackBone: %s: Failed to setup notify routine with staus 0x%X\n", __FUNCTION__, status ); return status; } RtlUnicodeStringInit( &deviceName, DEVICE_NAME ); status = IoCreateDevice( DriverObject, 0, &deviceName, FILE_DEVICE_BLACKBONE, 0, FALSE, &deviceObject ); if (!NT_SUCCESS( status )) { DPRINT( "BlackBone: %s: IoCreateDevice failed with status 0x%X\n", __FUNCTION__, status ); return status; } DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BBDispatch; DriverObject->DriverUnload = BBUnload; RtlUnicodeStringInit( &deviceLink, DOS_DEVICE_NAME ); status = IoCreateSymbolicLink( &deviceLink, &deviceName ); if (!NT_SUCCESS( status )) { DPRINT( "BlackBone: %s: IoCreateSymbolicLink failed with status 0x%X\n", __FUNCTION__, status ); IoDeleteDevice (deviceObject); } return status; }
/// <summary> /// Get kernel build number /// </summary> /// <param name="pBuildNO">Build number.</param> /// <returns>Status code</returns> NTSTATUS BBGetBuildNO( OUT PULONG pBuildNo ) { ASSERT( pBuildNo != NULL ); if (pBuildNo == 0) return STATUS_INVALID_PARAMETER; NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING strRegKey = { 0 }; UNICODE_STRING strRegValue = { 0 }; UNICODE_STRING strVerVal = { 0 }; HANDLE hKey = NULL; OBJECT_ATTRIBUTES keyAttr = { 0 }; RtlUnicodeStringInit( &strRegKey, L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion" ); RtlUnicodeStringInit( &strRegValue, L"BuildLabEx" ); InitializeObjectAttributes( &keyAttr, &strRegKey, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL ); status = ZwOpenKey( &hKey, KEY_READ, &keyAttr ); if (NT_SUCCESS( status )) { PKEY_VALUE_FULL_INFORMATION pValueInfo = ExAllocatePoolWithTag( PagedPool, 0x1000, BB_POOL_TAG ); ULONG bytes = 0; if (pValueInfo) { status = ZwQueryValueKey( hKey, &strRegValue, KeyValueFullInformation, pValueInfo, 0x1000, &bytes ); if (NT_SUCCESS( status )) { PWCHAR pData = (PWCHAR)((PUCHAR)pValueInfo->Name + pValueInfo->NameLength); for (ULONG i = 0; i < pValueInfo->DataLength; i++) { if (pData[i] == L'.') { for (ULONG j = i + 1; j < pValueInfo->DataLength; j++) { if (pData[j] == L'.') { strVerVal.Buffer = &pData[i] + 1; strVerVal.Length = strVerVal.MaximumLength = (USHORT)((j - i) * sizeof( WCHAR )); status = RtlUnicodeStringToInteger( &strVerVal, 10, pBuildNo ); goto skip1; } } } } skip1:; } ExFreePoolWithTag( pValueInfo, BB_POOL_TAG ); } else status = STATUS_NO_MEMORY; ZwClose( hKey ); } else DPRINT( "BlackBone: %s: ZwOpenKey failed with status 0x%X\n", __FUNCTION__, status ); return status; }
_Use_decl_annotations_ NTSTATUS OnDeviceAdd( WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit ) /*++ Routine Description: OnDeviceAdd is called by the framework in response to AddDevice call from the PnP manager. We create and initialize a device object to represent a new instance of the device. Arguments: Driver - Handle to a framework driver object created in DriverEntry DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure Return Value: Status --*/ { PAGED_CODE(); UNREFERENCED_PARAMETER(Driver); WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES objectAttributes; PDEVICE_CONTEXT deviceContext; WDFDEVICE device; NTSTATUS status; DECLARE_UNICODE_STRING_SIZE(symbolicLinkName, 128); // // Set PnP callbacks. // WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); pnpPowerCallbacks.EvtDevicePrepareHardware = PrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = ReleaseHardware; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); // // PWM only allows exclusive access. // WdfDeviceInitSetExclusive(DeviceInit, TRUE); // // Create device object. // WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&objectAttributes, DEVICE_CONTEXT); objectAttributes.EvtCleanupCallback = OnDeviceContextCleanup; status = WdfDeviceCreate(&DeviceInit, &objectAttributes, &device); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create device (0x%08x)", status); goto Exit; } deviceContext = GetContext(device); // // Prepare config spin lock. // WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes); status = WdfSpinLockCreate(&objectAttributes, &deviceContext->pwmLock); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create config spin lock (0x%08x)", status); goto Exit; } // // Prepare notification list spin lock. // WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes); status = WdfSpinLockCreate(&objectAttributes, &deviceContext->notificationListLock); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create notification list spin lock (0x%08x)", status); goto Exit; } // // Prepare interrupt object. // WDF_INTERRUPT_CONFIG interruptConfig; WDF_INTERRUPT_CONFIG_INIT( &interruptConfig, DmaIsr, DmaDpc ); status = WdfInterruptCreate( device, &interruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceContext->interruptObj ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create interrupt object (0x%08x)", status); goto Exit; } // // Create queues to handle IO. // WDF_IO_QUEUE_CONFIG queueConfig; WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( &queueConfig, WdfIoQueueDispatchParallel); queueConfig.EvtIoDeviceControl = OnIoDeviceControl; queueConfig.PowerManaged = WdfFalse; status = WdfIoQueueCreate( device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceContext->queueObj ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create IO queue (0x%08x)", status); goto Exit; } // // Create a symbolic link. // status = RtlUnicodeStringInit(&symbolicLinkName, BCM_PWM_SYMBOLIC_NAME); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not process the symbolic name (0x%08x)", status); goto Exit; } status = WdfDeviceCreateSymbolicLink( device, &symbolicLinkName ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create a symbolic name (0x%08x)", status); goto Exit; } Exit: return status; }