NTSTATUS NTAPI KspCreateObjectType( IN HANDLE ParentHandle, IN LPWSTR ObjectType, PVOID CreateParameters, UINT CreateParametersSize, IN ACCESS_MASK DesiredAccess, OUT PHANDLE NodeHandle) { NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING Name; /* calculate request length */ Name.Length = 0; Name.MaximumLength = wcslen(ObjectType) * sizeof(WCHAR) + CreateParametersSize + 1 * sizeof(WCHAR); Name.MaximumLength += sizeof(WCHAR); /* acquire request buffer */ Name.Buffer = AllocateItem(NonPagedPool, Name.MaximumLength); /* check for success */ if (!Name.Buffer) { /* insufficient resources */ return STATUS_INSUFFICIENT_RESOURCES; } /* build a request which looks like {ObjectClass}\CreateParameters * For pins the parent is the reference string used in registration * For clocks it is full path for pin\{ClockGuid}\ClockCreateParams */ RtlAppendUnicodeToString(&Name, ObjectType); RtlAppendUnicodeToString(&Name, L"\\"); /* append create parameters */ RtlMoveMemory(Name.Buffer + (Name.Length / sizeof(WCHAR)), CreateParameters, CreateParametersSize); Name.Length += CreateParametersSize; Name.Buffer[Name.Length / 2] = L'\0'; InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL); /* create the instance */ Status = IoCreateFile(NodeHandle, DesiredAccess, &ObjectAttributes, &IoStatusBlock, NULL, 0, 0, FILE_OPEN, 0, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK); /* free request buffer */ FreeItem(Name.Buffer); return Status; }
PFCB CdfsCreateFCB(PCWSTR FileName) { PFCB Fcb; Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB); if(!Fcb) return NULL; RtlZeroMemory(Fcb, sizeof(FCB)); RtlInitEmptyUnicodeString(&Fcb->PathName, Fcb->PathNameBuffer, sizeof(Fcb->PathNameBuffer)); if (FileName) { RtlAppendUnicodeToString(&Fcb->PathName, FileName); if (wcsrchr(Fcb->PathName.Buffer, '\\') != 0) { Fcb->ObjectName = wcsrchr(Fcb->PathName.Buffer, '\\'); } else { Fcb->ObjectName = Fcb->PathName.Buffer; } } ExInitializeResourceLite(&Fcb->PagingIoResource); ExInitializeResourceLite(&Fcb->MainResource); ExInitializeResourceLite(&Fcb->NameListResource); Fcb->RFCB.PagingIoResource = &Fcb->PagingIoResource; Fcb->RFCB.Resource = &Fcb->MainResource; Fcb->RFCB.IsFastIoPossible = FastIoIsNotPossible; InitializeListHead(&Fcb->ShortNameList); return(Fcb); }
NTSTATUS NTAPI SmpInvokeAutoChk(IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING Arguments, IN ULONG Flags) { ANSI_STRING MessageString; CHAR MessageBuffer[256]; UNICODE_STRING Destination; WCHAR Buffer[1024]; BOOLEAN BootState, BootOkay, ShutdownOkay; /* Check if autochk should show dots (if the user booted with /SOS) */ if (SmpQueryRegistrySosOption()) SmpEnableDots = FALSE; /* Make sure autochk was actually found */ if (Flags & SMP_INVALID_PATH) { /* It wasn't, so create an error message to print on the screen */ sprintf_nt(MessageBuffer, "%wZ program not found - skipping AUTOCHECK\r\n", FileName); RtlInitAnsiString(&MessageString, MessageBuffer); if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&Destination, &MessageString, TRUE))) { /* And show it */ NtDisplayString(&Destination); RtlFreeUnicodeString(&Destination); } } else { /* Autochk is there, so record the BSD state */ BootState = SmpSaveAndClearBootStatusData(&BootOkay, &ShutdownOkay); /* Build the path to autochk and place its arguments */ RtlInitEmptyUnicodeString(&Destination, Buffer, sizeof(Buffer)); RtlAppendUnicodeStringToString(&Destination, FileName); RtlAppendUnicodeToString(&Destination, L" "); RtlAppendUnicodeStringToString(&Destination, Arguments); /* Execute it */ SmpExecuteImage(FileName, Directory, &Destination, 0, Flags & ~SMP_AUTOCHK_FLAG, NULL); /* Restore the BSD state */ if (BootState) SmpRestoreBootStatusData(BootOkay, ShutdownOkay); } /* We're all done! */ return STATUS_SUCCESS; }
// // 实现我们自己的AddDevice函数 // NTSTATUS myAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ) { if(gDeviceObject != NULL) { // 在这里面创建我们自己的设备对象,或者申请所需要的资源。 // 为了区分不同实例,将设备对象名构造成:”MyNdisDevice”+HardwareID。 UNICODE_STRING nameString; WCHAR wcsName[256]; UNICODE_STRING preName = RTL_CONSTANT_STRING(L"\\Device\\MyNdisDevice"); // 首先取得设备的HDID。 ULONG nameLength = 0; WCHAR wcsHardwareID[256]; //足够大了 NTSTATUS status = IoGetDeviceProperty (PhysicalDeviceObject, DevicePropertyHardwareID, 256, wcsHardwareID, &nameLength); if(status != STATUS_SUCCESS){ KdPrint(("Failed to get hardware ID %x\n", status)); return status; } // 下面构造设备对象的名字,根据上面的规则:“MyNdisDevice”+ HardwareID。 RtlInitEmptyUnicodeString( &nameString, wcsName, 256*2); RtlCopyUnicodeString( &nameString, &preName); //RtlUnicodeStringPrintf(&nameString, L"%wZ_%d_", &preName, 0); RtlAppendUnicodeToString( &nameString, wcsHardwareID); status = IoCreateDevice(DriverObject, 0, &nameString, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &gDeviceObject); // 如果创建失败了,我们有权利让函数以失败返回 // 但这样我们的驱动加载也就失败了 if(status != STATUS_SUCCESS){ KdPrint(("Failed to create device %ws\n", nameString)); return status; } } //ExAllocatePoolWithTag(); //申请资源及其他 // // 还可以加入其他正确的操作 // // 现在调用保存的Ndis库中的AddDevice实现 // 千万不要忘记,否则就会大错特错了 return systemAddDevice(DriverObject, PhysicalDeviceObject); }
NTSTATUS MyDLPKBF_CreateDevice (IN PDRIVER_OBJECT pDriverObject, IN ULONG DeviceNumber) { PDEVICE_OBJECT pDevObj; UNICODE_STRING uniNtDeviceName, uniDosDeviceName, uniNumber; WCHAR ntDeviceNameBuffer[MYDLP_MAX_NAME_LENGTH]; WCHAR dosDeviceNameBuffer[MYDLP_MAX_NAME_LENGTH]; WCHAR numberBuffer[2]; PMYDLPKBF_DEVICE_EXTENSION pDevExt; NTSTATUS status; DbgPrint("MyDLPKBF_CreateDevice: Start\n"); status = STATUS_SUCCESS; uniNtDeviceName.Buffer = ntDeviceNameBuffer; uniNtDeviceName.MaximumLength = MYDLP_MAX_NAME_LENGTH * 2; uniNtDeviceName.Length = 0; uniDosDeviceName.Buffer = dosDeviceNameBuffer; uniDosDeviceName.MaximumLength = MYDLP_MAX_NAME_LENGTH * 2; uniDosDeviceName.Length = 0; uniNumber.Buffer = numberBuffer; uniNumber.MaximumLength = 4; uniNumber.Length = 0; RtlIntegerToUnicodeString( DeviceNumber, 10, &uniNumber); RtlAppendUnicodeToString( &uniNtDeviceName, NT_DEVICE_NAME); RtlAppendUnicodeStringToString( &uniNtDeviceName, &uniNumber); RtlAppendUnicodeToString( &uniDosDeviceName, DOS_DEVICE_NAME); RtlAppendUnicodeStringToString( &uniDosDeviceName, &uniNumber); status = IoCreateDevice(pDriverObject, sizeof(MYDLPKBF_DEVICE_EXTENSION), &uniNtDeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj); if(!NT_SUCCESS(status)) { DbgPrint("MyDLPKBF_CreateDevice: IoCreateDevice failed\ device no:%d\n", DeviceNumber); return status; }
/****************************************************************************\ * * NT_ConcatUnicodeStrings() * * DESCRIPTION: * * This routine concatenates two NULL terminated strings and returns * the result as an allocated UNICODE string. * * ARGUMENTS: * * s1, s2 - strings to concatenate * MaxLength - max length of the UNICODE string. If 0, then max length of * the allocated string equals the length of the concatenated * string. * * RETURN VALUE: * * Pointer to the allocated string, NULL if the allocation failed * \****************************************************************************/ PUNICODE_STRING NT_ConcatUnicodeStrings( IN PWSTR s1, IN PWSTR s2, IN USHORT MaxLength ) { PUNICODE_STRING String; size_t ActualMaxLength = (wcslen(s1) + wcslen(s2) + 1); ASSERT( (MaxLength > ActualMaxLength) || MaxLength == 0 ); if ( MaxLength > ActualMaxLength ) ActualMaxLength = MaxLength; String = NT_AllocUnicodeString( (USHORT)ActualMaxLength ); if ( String ) { /* RtlAppendUnicodeToString must not fail here if we have correctly * calculated the required size. */ NTSTATUS Status = RtlAppendUnicodeToString( String, s1 ); ASSERT( Status == STATUS_SUCCESS ); Status = RtlAppendUnicodeToString( String, s2 ); ASSERT( Status == STATUS_SUCCESS ); } return (String); }
static NTSTATUS XenM2BPdoQueryDeviceText(PXENM2B_PDO_EXTENSION pPdoExt, PIRP pIrp) { PIO_STACK_LOCATION pIrpStack; PVOID pBuffer; UNICODE_STRING Text; NTSTATUS Status; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); switch (pIrpStack->Parameters.QueryDeviceText.DeviceTextType) { case DeviceTextDescription: TraceDebug(("%s: DeviceTextDescription\n", __FUNCTION__)); break; case DeviceTextLocationInformation: TraceDebug(("%s: DeviceTextLocationInformation\n", __FUNCTION__)); break; default: pIrp->IoStatus.Information = 0; return STATUS_NOT_SUPPORTED; } pBuffer = ExAllocatePoolWithTag(PagedPool, XENM2B_MAX_TEXT_LENGTH, XENM2B_POOL_TAG); if (pBuffer == NULL) return STATUS_INSUFFICIENT_RESOURCES; RtlZeroMemory(pBuffer, XENM2B_MAX_TEXT_LENGTH); Text.Buffer = pBuffer; Text.MaximumLength = XENM2B_MAX_TEXT_LENGTH; Text.Length = 0; switch (pIrpStack->Parameters.QueryDeviceText.DeviceTextType) { case DeviceTextDescription: RtlAppendUnicodeStringToString(&Text, &pPdoExt->DeviceName); break; case DeviceTextLocationInformation: RtlAppendUnicodeToString(&Text, L"Xen PV HID Device on XenM2B Bus"); break; default: ASSERT(FALSE); break; } TraceDebug(("%s: %wZ\n", __FUNCTION__, &Text)); pIrp->IoStatus.Information = (ULONG_PTR)pBuffer; return STATUS_SUCCESS; }
NTSTATUS NTAPI IoQueryDeviceDescription(PINTERFACE_TYPE BusType OPTIONAL, PULONG BusNumber OPTIONAL, PCONFIGURATION_TYPE ControllerType OPTIONAL, PULONG ControllerNumber OPTIONAL, PCONFIGURATION_TYPE PeripheralType OPTIONAL, PULONG PeripheralNumber OPTIONAL, PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, PVOID Context) { NTSTATUS Status; ULONG BusLoopNumber = -1; /* Root Bus */ OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING RootRegKey; HANDLE RootRegHandle; IO_QUERY Query; /* Set up the String */ RootRegKey.Length = 0; RootRegKey.MaximumLength = 2048; RootRegKey.Buffer = ExAllocatePoolWithTag(PagedPool, RootRegKey.MaximumLength, TAG_IO_RESOURCE); RtlAppendUnicodeToString(&RootRegKey, L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM"); /* Open a handle to the Root Registry Key */ InitializeObjectAttributes( &ObjectAttributes, &RootRegKey, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&RootRegHandle, KEY_READ, &ObjectAttributes); if (NT_SUCCESS(Status)) { /* Use a helper function to loop though this key and get the info */ Query.BusType = BusType; Query.BusNumber = BusNumber; Query.ControllerType = ControllerType; Query.ControllerNumber = ControllerNumber; Query.PeripheralType = PeripheralType; Query.PeripheralNumber = PeripheralNumber; Query.CalloutRoutine = CalloutRoutine; Query.Context = Context; Status = IopQueryBusDescription(&Query, RootRegKey, RootRegHandle, &BusLoopNumber, TRUE); /* Close registry */ ZwClose(RootRegHandle); } /* Free Memory */ ExFreePoolWithTag(RootRegKey.Buffer, TAG_IO_RESOURCE); return Status; }
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS ntStatus; ntStatus= STATUS_SUCCESS; PPJoyBus_DebugLevel= PPJOY_DEFAULT_DEBUGLEVEL; PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_WARN, ("Built " __DATE__ " at " __TIME__) ); PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_FENTRY, ("DriverEntry (DriverObject=0x%p,RegistryPath=0x%p)",DriverObject, RegistryPath) ); RtlZeroMemory (&Globals,sizeof(Globals)); /* Setup copy of DriverObject first so we can use it for event log function */ Globals.DriverObject= DriverObject; /* Allocate buffer to store registry path to the parameters registry key */ Globals.ParamRegistryPath.MaximumLength= RegistryPath->Length+sizeof(UNICODE_NULL)+sizeof(PARAM_KEY_NAME); Globals.ParamRegistryPath.Length= RegistryPath->Length; Globals.ParamRegistryPath.Buffer= ExAllocatePoolWithTag (PagedPool,Globals.ParamRegistryPath.MaximumLength,PPJOYBUS_POOL_TAG); if (!Globals.ParamRegistryPath.Buffer) { PPJoyBus_WriteEventLog (PPJ_MSG_ERRORALLOCMEM,&ntStatus,sizeof(ntStatus),L""); ntStatus= STATUS_INSUFFICIENT_RESOURCES; goto Exit; } /* Copy driver registry path and append the parameters subkey name */ RtlCopyUnicodeString (&Globals.ParamRegistryPath,RegistryPath); RtlAppendUnicodeToString (&Globals.ParamRegistryPath,PARAM_KEY_NAME); ExInitializeFastMutex (&Globals.Mutex); PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_BABBLE2, ("ParamRegistryPath=%S",Globals.ParamRegistryPath.Buffer) ); /* Set up pointers to our other entry points in the DeviceObject */ DriverObject->MajorFunction[IRP_MJ_CREATE]= PPJoyBus_CreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE]= PPJoyBus_CreateClose; DriverObject->MajorFunction[IRP_MJ_POWER]= PPJoyBus_Power; DriverObject->MajorFunction[IRP_MJ_PNP]= PPJoyBus_PnP; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= PPJoyBus_Ioctl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]= PPJoyBus_InternalIoctl; DriverObject->DriverUnload= PPJoyBus_Unload; DriverObject->DriverExtension->AddDevice= PPJoyBus_AddDevice; PPJoyBus_WriteEventLog (PPJ_MSG_DRIVERSTARTEDVER,&ntStatus,sizeof(ntStatus),LVER_PRODUCTVERSION_STR); Exit: PPJOY_EXITPROC (FILE_PPJOYBUS|PPJOY_FEXIT_STATUSOK , "DriverEntry", ntStatus); return ntStatus; } /* DriverEntry */
static BOOL AppendUserEnvironmentVariable(PWSTR* Environment, LPWSTR lpName, LPWSTR lpValue) { NTSTATUS Status; UNICODE_STRING Name, Value; RtlInitUnicodeString(&Name, lpName); Value.Length = 0; Value.MaximumLength = 1024 * sizeof(WCHAR); Value.Buffer = LocalAlloc(LPTR, Value.MaximumLength); if (Value.Buffer == NULL) return FALSE; Value.Buffer[0] = UNICODE_NULL; Status = RtlQueryEnvironmentVariable_U(*Environment, &Name, &Value); if (NT_SUCCESS(Status)) RtlAppendUnicodeToString(&Value, L";"); RtlAppendUnicodeToString(&Value, lpValue); Status = RtlSetEnvironmentVariable(Environment, &Name, &Value); LocalFree(Value.Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status); return FALSE; } return TRUE; }
//read EnableReplace key from reg to check if replace the key with our define key void ReadRegistery(IN PUNICODE_STRING RegistryPath) { UNICODE_STRING parameter_path; RTL_QUERY_REGISTRY_TABLE query_table[2]; NTSTATUS status; parameter_path.Length = 0; parameter_path.MaximumLength = RegistryPath->Length + sizeof(PARAMETER_KEY); parameter_path.Buffer = (PWSTR) ExAllocatePool(PagedPool, parameter_path.MaximumLength); if (parameter_path.Buffer == NULL) { return; } RtlZeroMemory(parameter_path.Buffer,parameter_path.MaximumLength); RtlCopyUnicodeString(¶meter_path, RegistryPath); RtlAppendUnicodeToString(¶meter_path, PARAMETER_KEY); RtlZeroMemory(&query_table[0], sizeof(query_table)); query_table[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; query_table[0].Name = ENABLEWRITEPORT_VALUE; query_table[0].EntryContext = &bEnableReplace; status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, parameter_path.Buffer, &query_table[0], NULL, NULL ); ExFreePool(parameter_path.Buffer); if (!NT_SUCCESS(status)) { KdPrint(("Kb_sniff_Mp: Query registry failed.\n")); } }
VOID InitializeProvider( PWCH ProviderName, ULONG Priority ) /*++ Routine Description: This routine reads provider information out of the registry and creates an unregistered provider entry. Arguments: ProviderName - The registry name for the provider. Priority - The priority to assign to this provider. Return Value: None. --*/ { UNICODE_STRING keyName; PVOID buffer = NULL; ULONG bufferLength; NTSTATUS status; OBJECT_ATTRIBUTES objectAttributes; ULONG lengthRequired; UNICODE_STRING valueName; HANDLE handle; PAGED_CODE(); // // Allocate space for the registry string // bufferLength = sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" ) + wcslen( ProviderName ) * sizeof( WCHAR ) + sizeof( L"\\NetworkProvider" ); buffer = ExAllocatePoolWithTag( PagedPool, bufferLength, ' puM' ); if ( buffer == NULL ) { return; } // // Build the registry string // RtlMoveMemory( buffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" ) ); keyName.Buffer = buffer; keyName.MaximumLength = (USHORT)bufferLength; keyName.Length = sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" ) - 2; status = RtlAppendUnicodeToString( &keyName, ProviderName ); ASSERT( NT_SUCCESS( status ) ); status = RtlAppendUnicodeToString( &keyName, L"\\NetworkProvider" ); ASSERT( NT_SUCCESS( status ) ); InitializeObjectAttributes( &objectAttributes, &keyName, OBJ_CASE_INSENSITIVE, 0, NULL ); status = ZwOpenKey( &handle, KEY_QUERY_VALUE, &objectAttributes ); ExFreePool( buffer ); if ( !NT_SUCCESS( status )) { return; } buffer = NULL; RtlInitUnicodeString( &valueName, L"DeviceName" ); status = ZwQueryValueKey( handle, &valueName, KeyValueFullInformation, buffer, 0, &lengthRequired ); if ( status == STATUS_BUFFER_TOO_SMALL ) { buffer = ExAllocatePoolWithTag( PagedPool, lengthRequired + 2, ' puM' ); if ( buffer == NULL) { return; } status = ZwQueryValueKey( handle, &valueName, KeyValueFullInformation, buffer, lengthRequired, &lengthRequired ); } if ( !NT_SUCCESS( status) ) { if ( buffer != NULL ) { ExFreePool( buffer ); } ZwClose( handle ); return; } // // Wahoo! We actually have the device name in hand. Add the // provider to the unregistered list. // AddUnregisteredProvider( (PWCH)((PCHAR)buffer + ((PKEY_VALUE_FULL_INFORMATION)buffer)->DataOffset), Priority ); ExFreePool( buffer ); ZwClose( handle ); return; }
static NTSTATUS OpenRegistryHandlesFromSymbolicLink(IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, IN OPTIONAL PHANDLE GuidKey, IN OPTIONAL PHANDLE DeviceKey, IN OPTIONAL PHANDLE InstanceKey) { OBJECT_ATTRIBUTES ObjectAttributes; WCHAR PathBuffer[MAX_PATH]; UNICODE_STRING BaseKeyU; UNICODE_STRING GuidString, SubKeyName, ReferenceString; PWCHAR StartPosition, EndPosition; HANDLE ClassesKey; PHANDLE GuidKeyRealP, DeviceKeyRealP, InstanceKeyRealP; HANDLE GuidKeyReal, DeviceKeyReal, InstanceKeyReal; NTSTATUS Status; SubKeyName.Buffer = NULL; if (GuidKey != NULL) GuidKeyRealP = GuidKey; else GuidKeyRealP = &GuidKeyReal; if (DeviceKey != NULL) DeviceKeyRealP = DeviceKey; else DeviceKeyRealP = &DeviceKeyReal; if (InstanceKey != NULL) InstanceKeyRealP = InstanceKey; else InstanceKeyRealP = &InstanceKeyReal; *GuidKeyRealP = INVALID_HANDLE_VALUE; *DeviceKeyRealP = INVALID_HANDLE_VALUE; *InstanceKeyRealP = INVALID_HANDLE_VALUE; BaseKeyU.Buffer = PathBuffer; BaseKeyU.Length = 0; BaseKeyU.MaximumLength = MAX_PATH * sizeof(WCHAR); RtlAppendUnicodeToString(&BaseKeyU, BaseKeyString); /* Open the DeviceClasses key */ InitializeObjectAttributes(&ObjectAttributes, &BaseKeyU, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenKey(&ClassesKey, DesiredAccess | KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to open %wZ\n", &BaseKeyU); goto cleanup; } StartPosition = wcschr(SymbolicLinkName->Buffer, L'{'); EndPosition = wcschr(SymbolicLinkName->Buffer, L'}'); if (!StartPosition || !EndPosition || StartPosition > EndPosition) { DPRINT1("Bad symbolic link: %wZ\n", SymbolicLinkName); return STATUS_INVALID_PARAMETER_1; } GuidString.Buffer = StartPosition; GuidString.MaximumLength = GuidString.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)StartPosition); InitializeObjectAttributes(&ObjectAttributes, &GuidString, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, ClassesKey, NULL); Status = ZwOpenKey(GuidKeyRealP, DesiredAccess | KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); ZwClose(ClassesKey); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to open %wZ%wZ (%x)\n", &BaseKeyU, &GuidString, Status); goto cleanup; } SubKeyName.MaximumLength = SymbolicLinkName->Length + sizeof(WCHAR); SubKeyName.Length = 0; SubKeyName.Buffer = ExAllocatePool(PagedPool, SubKeyName.MaximumLength); if (!SubKeyName.Buffer) { Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } RtlAppendUnicodeStringToString(&SubKeyName, SymbolicLinkName); SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL; SubKeyName.Buffer[0] = L'#'; SubKeyName.Buffer[1] = L'#'; SubKeyName.Buffer[2] = L'?'; SubKeyName.Buffer[3] = L'#'; ReferenceString.Buffer = wcsrchr(SubKeyName.Buffer, '\\'); if (ReferenceString.Buffer != NULL) { ReferenceString.Buffer[0] = L'#'; SubKeyName.Length = (USHORT)((ULONG_PTR)(ReferenceString.Buffer) - (ULONG_PTR)SubKeyName.Buffer); ReferenceString.Length = SymbolicLinkName->Length - SubKeyName.Length; } else { RtlInitUnicodeString(&ReferenceString, L"#"); } InitializeObjectAttributes(&ObjectAttributes, &SubKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, *GuidKeyRealP, NULL); Status = ZwOpenKey(DeviceKeyRealP, DesiredAccess | KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to open %wZ%wZ\\%wZ\n", &BaseKeyU, &GuidString, &SubKeyName); goto cleanup; } InitializeObjectAttributes(&ObjectAttributes, &ReferenceString, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, *DeviceKeyRealP, NULL); Status = ZwOpenKey(InstanceKeyRealP, DesiredAccess, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to open %wZ%wZ\\%wZ%\\%wZ (%x)\n", &BaseKeyU, &GuidString, &SubKeyName, &ReferenceString, Status); goto cleanup; } Status = STATUS_SUCCESS; cleanup: if (SubKeyName.Buffer != NULL) ExFreePool(SubKeyName.Buffer); if (NT_SUCCESS(Status)) { if (!GuidKey) ZwClose(*GuidKeyRealP); if (!DeviceKey) ZwClose(*DeviceKeyRealP); if (!InstanceKey) ZwClose(*InstanceKeyRealP); } else { if (*GuidKeyRealP != INVALID_HANDLE_VALUE) ZwClose(*GuidKeyRealP); if (*DeviceKeyRealP != INVALID_HANDLE_VALUE) ZwClose(*DeviceKeyRealP); if (*InstanceKeyRealP != INVALID_HANDLE_VALUE) ZwClose(*InstanceKeyRealP); } return Status; }
/*++ * @name IopOpenInterfaceKey * * Returns the alias device interface of the specified device interface * * @param InterfaceClassGuid * FILLME * * @param DesiredAccess * FILLME * * @param pInterfaceKey * FILLME * * @return Usual NTSTATUS * * @remarks None * *--*/ static NTSTATUS IopOpenInterfaceKey(IN CONST GUID *InterfaceClassGuid, IN ACCESS_MASK DesiredAccess, OUT HANDLE *pInterfaceKey) { UNICODE_STRING LocalMachine = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\"); UNICODE_STRING GuidString; UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE InterfaceKey = INVALID_HANDLE_VALUE; NTSTATUS Status; GuidString.Buffer = KeyName.Buffer = NULL; Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString); if (!NT_SUCCESS(Status)) { DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status); goto cleanup; } KeyName.Length = 0; KeyName.MaximumLength = LocalMachine.Length + ((USHORT)wcslen(REGSTR_PATH_DEVICE_CLASSES) + 1) * sizeof(WCHAR) + GuidString.Length; KeyName.Buffer = ExAllocatePool(PagedPool, KeyName.MaximumLength); if (!KeyName.Buffer) { DPRINT("ExAllocatePool() failed\n"); Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } Status = RtlAppendUnicodeStringToString(&KeyName, &LocalMachine); if (!NT_SUCCESS(Status)) { DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status); goto cleanup; } Status = RtlAppendUnicodeToString(&KeyName, REGSTR_PATH_DEVICE_CLASSES); if (!NT_SUCCESS(Status)) { DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status); goto cleanup; } Status = RtlAppendUnicodeToString(&KeyName, L"\\"); if (!NT_SUCCESS(Status)) { DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status); goto cleanup; } Status = RtlAppendUnicodeStringToString(&KeyName, &GuidString); if (!NT_SUCCESS(Status)) { DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status); goto cleanup; } InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey( &InterfaceKey, DesiredAccess, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); goto cleanup; } *pInterfaceKey = InterfaceKey; Status = STATUS_SUCCESS; cleanup: if (!NT_SUCCESS(Status)) { if (InterfaceKey != INVALID_HANDLE_VALUE) ZwClose(InterfaceKey); } RtlFreeUnicodeString(&GuidString); RtlFreeUnicodeString(&KeyName); return Status; }
PLDEVOBJ NTAPI EngLoadImageEx( _In_z_ LPWSTR pwszDriverName, _In_ ULONG ldevtype) { WCHAR acwBuffer[MAX_PATH]; PLDEVOBJ pldev; UNICODE_STRING strDriverName; SIZE_T cwcLength; LPWSTR pwsz; TRACE("EngLoadImageEx(%ls, %lu)\n", pwszDriverName, ldevtype); ASSERT(pwszDriverName); /* Initialize buffer for the the driver name */ RtlInitEmptyUnicodeString(&strDriverName, acwBuffer, sizeof(acwBuffer)); /* Start path with systemroot */ RtlAppendUnicodeToString(&strDriverName, L"\\SystemRoot\\System32\\"); /* Get Length of given string */ cwcLength = wcslen(pwszDriverName); /* Check if we have a system32 path given */ pwsz = pwszDriverName + cwcLength; while (pwsz > pwszDriverName) { if ((*pwsz == L'\\') && (_wcsnicmp(pwsz, L"\\system32\\", 10) == 0)) { /* Driver name starts after system32 */ pwsz += 10; break; } pwsz--; } /* Append the driver name */ RtlAppendUnicodeToString(&strDriverName, pwsz); /* MSDN says "The driver must include this suffix in the pwszDriver string." But in fact it's optional. The function can also load .sys files without appending the .dll extension. */ if ((cwcLength < 4) || ((_wcsnicmp(pwszDriverName + cwcLength - 4, L".dll", 4) != 0) && (_wcsnicmp(pwszDriverName + cwcLength - 4, L".sys", 4) != 0)) ) { /* Append the .dll suffix */ RtlAppendUnicodeToString(&strDriverName, L".dll"); } /* Lock loader */ EngAcquireSemaphore(ghsemLDEVList); /* Search the List of LDEVS for the driver name */ for (pldev = gpldevHead; pldev != NULL; pldev = pldev->pldevNext) { /* Check if the ldev is associated with a file */ if (pldev->pGdiDriverInfo) { ERR("Driver Name 1 %wZ\n", &strDriverName); ERR("Driver Name 2 %wZ\n", &pldev->pGdiDriverInfo->DriverName); /* Check for match (case insensative) */ if (RtlEqualUnicodeString(&pldev->pGdiDriverInfo->DriverName, &strDriverName, 1)) { /* Image found in LDEV list */ break; } } } /* Did we find one? */ if (!pldev) { /* No, allocate a new LDEVOBJ */ pldev = LDEVOBJ_AllocLDEV(ldevtype); if (!pldev) { ERR("Could not allocate LDEV\n"); goto leave; } /* Load the image */ if (!LDEVOBJ_bLoadImage(pldev, &strDriverName)) { LDEVOBJ_vFreeLDEV(pldev); pldev = NULL; ERR("LDEVOBJ_bLoadImage failed\n"); goto leave; } /* Shall we load a driver? */ if (ldevtype != LDEV_IMAGE) { /* Load the driver */ if (!LDEVOBJ_bEnableDriver(pldev)) { ERR("LDEVOBJ_bEnableDriver failed\n"); /* Unload the image. */ LDEVOBJ_vUnloadImage(pldev); LDEVOBJ_vFreeLDEV(pldev); pldev = NULL; goto leave; } } /* Insert the LDEV into the global list */ pldev->pldevPrev = NULL; pldev->pldevNext = gpldevHead; if (gpldevHead) gpldevHead->pldevPrev = pldev; gpldevHead = pldev; } /* Increase ref count */ pldev->cRefs++; leave: /* Unlock loader */ EngReleaseSemaphore(ghsemLDEVList); TRACE("EngLoadImageEx returning %p\n", pldev); return pldev; }
BOOLEAN Ext2QueryGlobalParameters( IN PUNICODE_STRING RegistryPath) { NTSTATUS Status; UNICODE_STRING ParameterPath; RTL_QUERY_REGISTRY_TABLE QueryTable[2]; ULONG WritingSupport = 0; ULONG CheckingBitmap = 0; ULONG Ext3ForceWriting = 0; ULONG AutoMount = 0; UNICODE_STRING UniName; ANSI_STRING AnsiName; WCHAR UniBuffer[CODEPAGE_MAXLEN]; USHORT Buffer[HIDINGPAT_LEN]; ParameterPath.Length = 0; ParameterPath.MaximumLength = RegistryPath->Length + sizeof(PARAMETERS_KEY) + sizeof(WCHAR); ParameterPath.Buffer = (PWSTR) Ext2AllocatePool( PagedPool, ParameterPath.MaximumLength, 'LG2E' ); if (!ParameterPath.Buffer) { DbgBreak(); DEBUG(DL_ERR, ( "Ex2QueryParameters: failed to allocate Parameters...\n")); return FALSE; } RtlCopyUnicodeString(&ParameterPath, RegistryPath); RtlAppendUnicodeToString(&ParameterPath, PARAMETERS_KEY); /* querying value of WritingSupport */ RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2); QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; QueryTable[0].Name = WRITING_SUPPORT; QueryTable[0].EntryContext = &WritingSupport; Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, ParameterPath.Buffer, &QueryTable[0], NULL, NULL ); DEBUG(DL_ERR, ( "Ext2QueryParameters: WritingSupport=%xh\n", WritingSupport)); /* querying value of CheckingBitmap */ RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2); QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; QueryTable[0].Name = CHECKING_BITMAP; QueryTable[0].EntryContext = &CheckingBitmap; Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, ParameterPath.Buffer, &QueryTable[0], NULL, NULL ); DEBUG(DL_ERR, ( "Ext2QueryParameters: CheckingBitmap=%xh\n", CheckingBitmap)); /* querying value of Ext3ForceWriting */ RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2); QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; QueryTable[0].Name = EXT3_FORCEWRITING; QueryTable[0].EntryContext = &Ext3ForceWriting; Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, ParameterPath.Buffer, &QueryTable[0], NULL, NULL ); DEBUG(DL_ERR, ( "Ext2QueryParameters: Ext3ForceWriting=%xh\n", Ext3ForceWriting)); /* querying value of AutoMount */ RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2); QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; QueryTable[0].Name = AUTO_MOUNT; QueryTable[0].EntryContext = &AutoMount; Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, ParameterPath.Buffer, &QueryTable[0], NULL, NULL ); SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); if (NT_SUCCESS(Status) && AutoMount == 0) { ClearLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); } DEBUG(DL_ERR, ( "Ext2QueryParameters: AutoMount=%xh\n", AutoMount)); /* querying codepage */ RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2); QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; QueryTable[0].Name = CODEPAGE_NAME; QueryTable[0].EntryContext = &(UniName); UniName.MaximumLength = CODEPAGE_MAXLEN * sizeof(WCHAR); UniName.Length = 0; UniName.Buffer = (PWSTR)UniBuffer; Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, ParameterPath.Buffer, &QueryTable[0], NULL, NULL ); if (NT_SUCCESS(Status)) { DEBUG(DL_ERR, ( "Ext2QueryParameters: Ext2CodePage=%wZ\n", &UniName)); AnsiName.MaximumLength = CODEPAGE_MAXLEN; AnsiName.Length = 0; AnsiName.Buffer = &(Ext2Global->Codepage.AnsiName[0]); Status = RtlUnicodeStringToAnsiString( &AnsiName, &UniName, FALSE); if (!NT_SUCCESS(Status)) { DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong CodePage %wZ ...\n", &UniName)); RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8); } } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: CodePage not specified.\n")); RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8); } Ext2Global->Codepage.AnsiName[CODEPAGE_MAXLEN - 1] = 0; /* querying name hiding patterns: prefix*/ RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2); QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; QueryTable[0].Name = HIDING_PREFIX; QueryTable[0].EntryContext = &(UniName); UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR); UniName.Length = 0; UniName.Buffer = Buffer; Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, ParameterPath.Buffer, &QueryTable[0], NULL, NULL ); if (NT_SUCCESS(Status)) { DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingPrefix=%wZ\n", &UniName)); AnsiName.MaximumLength =HIDINGPAT_LEN; AnsiName.Length = 0; AnsiName.Buffer = &(Ext2Global->sHidingPrefix[0]); Status = RtlUnicodeStringToAnsiString( &AnsiName, &UniName, FALSE); if (NT_SUCCESS(Status)) { Ext2Global->bHidingPrefix = TRUE; } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingPrefix ...\n")); } } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingPrefix not specified.\n")); } Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0; /* querying name hiding patterns: suffix */ RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2); QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; QueryTable[0].Name = HIDING_SUFFIX; QueryTable[0].EntryContext = &(UniName); UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR); UniName.Length = 0; UniName.Buffer = Buffer; Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, ParameterPath.Buffer, &QueryTable[0], NULL, NULL ); if (NT_SUCCESS(Status)) { DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingSuffix=%wZ\n", &UniName)); AnsiName.MaximumLength = HIDINGPAT_LEN; AnsiName.Length = 0; AnsiName.Buffer = &(Ext2Global->sHidingSuffix[0]); Status = RtlUnicodeStringToAnsiString( &AnsiName, &UniName, FALSE); if (NT_SUCCESS(Status)) { Ext2Global->bHidingSuffix = TRUE; } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingSuffix ...\n")); } } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingSuffix not specified.\n")); } Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0; { if (WritingSupport) { SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING); } else { ClearLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING); } if (CheckingBitmap) { SetLongFlag(Ext2Global->Flags, EXT2_CHECKING_BITMAP); } else { ClearLongFlag(Ext2Global->Flags, EXT2_CHECKING_BITMAP); } if (Ext3ForceWriting) { DbgPrint("Ext2Fsd -- Warning: Ext3ForceWriting enabled !!!\n"); SetLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING); SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING); } else { ClearLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING); } } Ext2Global->RegistryPath.Buffer = ParameterPath.Buffer; Ext2Global->RegistryPath.Length = 0; Ext2Global->RegistryPath.MaximumLength = ParameterPath.MaximumLength; RtlCopyUnicodeString(&Ext2Global->RegistryPath, RegistryPath); RtlAppendUnicodeToString(&Ext2Global->RegistryPath, VOLUMES_KEY); return TRUE; }
BOOLEAN Ext2QueryRegistrySettings(IN PUNICODE_STRING RegistryPath) { UNICODE_STRING ParameterPath; UNICODE_STRING UniName; ANSI_STRING AnsiName; ULONG WritingSupport = 0; ULONG CheckingBitmap = 0; ULONG Ext3ForceWriting = 0; ULONG AutoMount = 0; WCHAR UniBuffer[CODEPAGE_MAXLEN]; USHORT Buffer[HIDINGPAT_LEN]; NTSTATUS Status; ParameterPath.Length = 0; ParameterPath.MaximumLength = RegistryPath->Length + sizeof(PARAMETERS_KEY) + sizeof(WCHAR); ParameterPath.Buffer = (PWSTR) Ext2AllocatePool( PagedPool, ParameterPath.MaximumLength, 'LG2E' ); if (!ParameterPath.Buffer) { DbgBreak(); DEBUG(DL_ERR, ( "Ex2QueryParameters: failed to allocate Parameters...\n")); return FALSE; } RtlCopyUnicodeString(&ParameterPath, RegistryPath); RtlAppendUnicodeToString(&ParameterPath, PARAMETERS_KEY); /* enable automount of ext2/3/4 volumes */ SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); /* query parameter settings from registry */ Ext2QueryGlobalParameters(&ParameterPath); /* set global codepage settings */ if (wcslen(&Ext2Global->Codepage.PageName[0])) { UniName.Length = sizeof(WCHAR) * wcslen(&Ext2Global->Codepage.PageName[0]); UniName.MaximumLength = CODEPAGE_MAXLEN * sizeof(WCHAR); UniName.Buffer = &Ext2Global->Codepage.PageName[0]; AnsiName.MaximumLength = CODEPAGE_MAXLEN; AnsiName.Length = 0; AnsiName.Buffer = &Ext2Global->Codepage.AnsiName[0]; Status = RtlUnicodeStringToAnsiString( &AnsiName, &UniName, FALSE); if (!NT_SUCCESS(Status)) { DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong CodePage %wZ ...\n", &UniName)); RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8); } } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: CodePage not specified.\n")); RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8); } Ext2Global->Codepage.AnsiName[CODEPAGE_MAXLEN - 1] = 0; /* set global hidden prefix pattern */ if (wcslen(&Ext2Global->wHidingPrefix[0])) { UniName.Length = sizeof(WCHAR) * wcslen(&Ext2Global->wHidingPrefix[0]); UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR); UniName.Buffer = &Ext2Global->wHidingPrefix[0]; AnsiName.MaximumLength = HIDINGPAT_LEN; AnsiName.Length = 0; AnsiName.Buffer = &(Ext2Global->sHidingPrefix[0]); Status = RtlUnicodeStringToAnsiString( &AnsiName, &UniName, FALSE); if (NT_SUCCESS(Status)) { Ext2Global->bHidingPrefix = TRUE; } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingPrefix ...\n")); } } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingPrefix not specified.\n")); } Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0; /* set global hidden suffix pattern */ if (wcslen(&Ext2Global->wHidingSuffix[0])) { UniName.Length = sizeof(WCHAR) * wcslen(&Ext2Global->wHidingSuffix[0]); UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR); UniName.Buffer = &Ext2Global->wHidingSuffix[0]; AnsiName.MaximumLength = HIDINGPAT_LEN; AnsiName.Length = 0; AnsiName.Buffer = &(Ext2Global->sHidingSuffix[0]); Status = RtlUnicodeStringToAnsiString( &AnsiName, &UniName, FALSE); if (NT_SUCCESS(Status)) { Ext2Global->bHidingSuffix = TRUE; } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingSuffix ...\n")); } } else { DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingSuffix not specified.\n")); } Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0; Ext2Global->RegistryPath.Buffer = ParameterPath.Buffer; Ext2Global->RegistryPath.Length = 0; Ext2Global->RegistryPath.MaximumLength = ParameterPath.MaximumLength; RtlCopyUnicodeString(&Ext2Global->RegistryPath, RegistryPath); RtlAppendUnicodeToString(&Ext2Global->RegistryPath, VOLUMES_KEY); return TRUE; }
/// <summary> /// Get exported function address /// </summary> /// <param name="pBase">Module base</param> /// <param name="name_ord">Function name or ordinal</param> /// <param name="pProcess">Target process for user module</param> /// <param name="baseName">Dll name for api schema</param> /// <returns>Found address, NULL if not found</returns> PVOID BBGetModuleExport( IN PVOID pBase, IN PCCHAR name_ord, IN PEPROCESS pProcess, IN PUNICODE_STRING baseName ) { PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)pBase; PIMAGE_NT_HEADERS32 pNtHdr32 = NULL; PIMAGE_NT_HEADERS64 pNtHdr64 = NULL; PIMAGE_EXPORT_DIRECTORY pExport = NULL; ULONG expSize = 0; ULONG_PTR pAddress = 0; ASSERT( pBase != NULL ); if (pBase == NULL) return NULL; // Protect from UserMode AV __try { // Not a PE file if (pDosHdr->e_magic != IMAGE_DOS_SIGNATURE) return NULL; pNtHdr32 = (PIMAGE_NT_HEADERS32)((PUCHAR)pBase + pDosHdr->e_lfanew); pNtHdr64 = (PIMAGE_NT_HEADERS64)((PUCHAR)pBase + pDosHdr->e_lfanew); // Not a PE file if (pNtHdr32->Signature != IMAGE_NT_SIGNATURE) return NULL; // 64 bit image if (pNtHdr32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { pExport = (PIMAGE_EXPORT_DIRECTORY)(pNtHdr64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)pBase); expSize = pNtHdr64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; } // 32 bit image else { pExport = (PIMAGE_EXPORT_DIRECTORY)(pNtHdr32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)pBase); expSize = pNtHdr32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; } PUSHORT pAddressOfOrds = (PUSHORT)(pExport->AddressOfNameOrdinals + (ULONG_PTR)pBase); PULONG pAddressOfNames = (PULONG)(pExport->AddressOfNames + (ULONG_PTR)pBase); PULONG pAddressOfFuncs = (PULONG)(pExport->AddressOfFunctions + (ULONG_PTR)pBase); for (ULONG i = 0; i < pExport->NumberOfFunctions; ++i) { USHORT OrdIndex = 0xFFFF; PCHAR pName = NULL; // Find by index if ((ULONG_PTR)name_ord <= 0xFFFF) { OrdIndex = (USHORT)i; } // Find by name else if ((ULONG_PTR)name_ord > 0xFFFF && i < pExport->NumberOfNames) { pName = (PCHAR)(pAddressOfNames[i] + (ULONG_PTR)pBase); OrdIndex = pAddressOfOrds[i]; } // Weird params else return NULL; if (((ULONG_PTR)name_ord <= 0xFFFF && (USHORT)((ULONG_PTR)name_ord) == OrdIndex + pExport->Base) || ((ULONG_PTR)name_ord > 0xFFFF && strcmp( pName, name_ord ) == 0)) { pAddress = pAddressOfFuncs[OrdIndex] + (ULONG_PTR)pBase; // Check forwarded export if (pAddress >= (ULONG_PTR)pExport && pAddress <= (ULONG_PTR)pExport + expSize) { WCHAR strbuf[256] = { 0 }; ANSI_STRING forwarder = { 0 }; ANSI_STRING import = { 0 }; UNICODE_STRING uForwarder = { 0 }; ULONG delimIdx = 0; PVOID forwardBase = NULL; PVOID result = NULL; // System image, not supported if (pProcess == NULL) return NULL; RtlInitAnsiString( &forwarder, (PCSZ)pAddress ); RtlInitEmptyUnicodeString( &uForwarder, strbuf, sizeof( strbuf ) ); RtlAnsiStringToUnicodeString( &uForwarder, &forwarder, FALSE ); for (ULONG i = 0; i < uForwarder.Length / sizeof( WCHAR ); i++) { if (uForwarder.Buffer[i] == L'.') { uForwarder.Length = (USHORT)(i * sizeof( WCHAR )); uForwarder.Buffer[i] = L'\0'; delimIdx = i; break; } } // Get forward function name/ordinal RtlInitAnsiString( &import, forwarder.Buffer + delimIdx + 1 ); RtlAppendUnicodeToString( &uForwarder, L".dll" ); // // Check forwarded module // UNICODE_STRING resolved = { 0 }; UNICODE_STRING resolvedName = { 0 }; BBResolveImagePath( NULL, pProcess, KApiShemaOnly, &uForwarder, baseName, &resolved ); BBStripPath( &resolved, &resolvedName ); forwardBase = BBGetUserModule( pProcess, &resolvedName, PsGetProcessWow64Process( pProcess ) != NULL ); result = BBGetModuleExport( forwardBase, import.Buffer, pProcess, &resolvedName ); RtlFreeUnicodeString( &resolved ); return result; } break; } } } __except (EXCEPTION_EXECUTE_HANDLER) { DPRINT( "BlackBone: %s: Exception\n", __FUNCTION__ ); } return (PVOID)pAddress; }
/*++ * @name IoRegisterDeviceInterface * @implemented * * Registers a device interface class, if it has not been previously registered, * and creates a new instance of the interface class, which a driver can * subsequently enable for use by applications or other system components. * Documented in WDK. * * @param PhysicalDeviceObject * Points to an optional PDO that narrows the search to only the * device interfaces of the device represented by the PDO * * @param InterfaceClassGuid * Points to a class GUID specifying the device interface class * * @param ReferenceString * Optional parameter, pointing to a unicode string. For a full * description of this rather rarely used param (usually drivers * pass NULL here) see WDK * * @param SymbolicLinkName * Pointer to the resulting unicode string * * @return Usual NTSTATUS * * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a * system thread * *--*/ NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName) { PUNICODE_STRING InstancePath; UNICODE_STRING GuidString; UNICODE_STRING SubKeyName; UNICODE_STRING InterfaceKeyName; UNICODE_STRING BaseKeyName; UCHAR PdoNameInfoBuffer[sizeof(OBJECT_NAME_INFORMATION) + (256 * sizeof(WCHAR))]; POBJECT_NAME_INFORMATION PdoNameInfo = (POBJECT_NAME_INFORMATION)PdoNameInfoBuffer; UNICODE_STRING DeviceInstance = RTL_CONSTANT_STRING(L"DeviceInstance"); UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink"); HANDLE ClassKey; HANDLE InterfaceKey; HANDLE SubKey; ULONG StartIndex; OBJECT_ATTRIBUTES ObjectAttributes; ULONG i; NTSTATUS Status, SymLinkStatus; PEXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension; ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); DPRINT("IoRegisterDeviceInterface(): PDO %p, RefString: %wZ\n", PhysicalDeviceObject, ReferenceString); /* Parameters must pass three border of checks */ DeviceObjectExtension = (PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension; /* 1st level: Presence of a Device Node */ if (DeviceObjectExtension->DeviceNode == NULL) { DPRINT("PhysicalDeviceObject 0x%p doesn't have a DeviceNode\n", PhysicalDeviceObject); return STATUS_INVALID_DEVICE_REQUEST; } /* 2nd level: Presence of an non-zero length InstancePath */ if (DeviceObjectExtension->DeviceNode->InstancePath.Length == 0) { DPRINT("PhysicalDeviceObject 0x%p's DOE has zero-length InstancePath\n", PhysicalDeviceObject); return STATUS_INVALID_DEVICE_REQUEST; } /* 3rd level: Optional, based on WDK documentation */ if (ReferenceString != NULL) { /* Reference string must not contain path-separator symbols */ for (i = 0; i < ReferenceString->Length / sizeof(WCHAR); i++) { if ((ReferenceString->Buffer[i] == '\\') || (ReferenceString->Buffer[i] == '/')) return STATUS_INVALID_DEVICE_REQUEST; } } Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString); if (!NT_SUCCESS(Status)) { DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status); return Status; } /* Create Pdo name: \Device\xxxxxxxx (unnamed device) */ Status = ObQueryNameString( PhysicalDeviceObject, PdoNameInfo, sizeof(PdoNameInfoBuffer), &i); if (!NT_SUCCESS(Status)) { DPRINT("ObQueryNameString() failed with status 0x%08lx\n", Status); return Status; } ASSERT(PdoNameInfo->Name.Length); /* Create base key name for this interface: HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID} */ ASSERT(((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode); InstancePath = &((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->InstancePath; BaseKeyName.Length = (USHORT)wcslen(BaseKeyString) * sizeof(WCHAR); BaseKeyName.MaximumLength = BaseKeyName.Length + GuidString.Length; BaseKeyName.Buffer = ExAllocatePool( PagedPool, BaseKeyName.MaximumLength); if (!BaseKeyName.Buffer) { DPRINT("ExAllocatePool() failed\n"); return STATUS_INSUFFICIENT_RESOURCES; } wcscpy(BaseKeyName.Buffer, BaseKeyString); RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString); /* Create BaseKeyName key in registry */ InitializeObjectAttributes( &ObjectAttributes, &BaseKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF, NULL, /* RootDirectory */ NULL); /* SecurityDescriptor */ Status = ZwCreateKey( &ClassKey, KEY_WRITE, &ObjectAttributes, 0, /* TileIndex */ NULL, /* Class */ REG_OPTION_VOLATILE, NULL); /* Disposition */ if (!NT_SUCCESS(Status)) { DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); ExFreePool(BaseKeyName.Buffer); return Status; } /* Create key name for this interface: ##?#ACPI#PNP0501#1#{GUID} */ InterfaceKeyName.Length = 0; InterfaceKeyName.MaximumLength = 4 * sizeof(WCHAR) + /* 4 = size of ##?# */ InstancePath->Length + sizeof(WCHAR) + /* 1 = size of # */ GuidString.Length; InterfaceKeyName.Buffer = ExAllocatePool( PagedPool, InterfaceKeyName.MaximumLength); if (!InterfaceKeyName.Buffer) { DPRINT("ExAllocatePool() failed\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlAppendUnicodeToString(&InterfaceKeyName, L"##?#"); StartIndex = InterfaceKeyName.Length / sizeof(WCHAR); RtlAppendUnicodeStringToString(&InterfaceKeyName, InstancePath); for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++) { if (InterfaceKeyName.Buffer[StartIndex + i] == '\\') InterfaceKeyName.Buffer[StartIndex + i] = '#'; } RtlAppendUnicodeToString(&InterfaceKeyName, L"#"); RtlAppendUnicodeStringToString(&InterfaceKeyName, &GuidString); /* Create the interface key in registry */ InitializeObjectAttributes( &ObjectAttributes, &InterfaceKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF, ClassKey, NULL); /* SecurityDescriptor */ Status = ZwCreateKey( &InterfaceKey, KEY_WRITE, &ObjectAttributes, 0, /* TileIndex */ NULL, /* Class */ REG_OPTION_VOLATILE, NULL); /* Disposition */ if (!NT_SUCCESS(Status)) { DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); ZwClose(ClassKey); ExFreePool(BaseKeyName.Buffer); return Status; } /* Write DeviceInstance entry. Value is InstancePath */ Status = ZwSetValueKey( InterfaceKey, &DeviceInstance, 0, /* TileIndex */ REG_SZ, InstancePath->Buffer, InstancePath->Length); if (!NT_SUCCESS(Status)) { DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); ZwClose(InterfaceKey); ZwClose(ClassKey); ExFreePool(InterfaceKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); return Status; } /* Create subkey. Name is #ReferenceString */ SubKeyName.Length = 0; SubKeyName.MaximumLength = sizeof(WCHAR); if (ReferenceString && ReferenceString->Length) SubKeyName.MaximumLength += ReferenceString->Length; SubKeyName.Buffer = ExAllocatePool( PagedPool, SubKeyName.MaximumLength); if (!SubKeyName.Buffer) { DPRINT("ExAllocatePool() failed\n"); ZwClose(InterfaceKey); ZwClose(ClassKey); ExFreePool(InterfaceKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); return STATUS_INSUFFICIENT_RESOURCES; } RtlAppendUnicodeToString(&SubKeyName, L"#"); if (ReferenceString && ReferenceString->Length) RtlAppendUnicodeStringToString(&SubKeyName, ReferenceString); /* Create SubKeyName key in registry */ InitializeObjectAttributes( &ObjectAttributes, &SubKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, InterfaceKey, /* RootDirectory */ NULL); /* SecurityDescriptor */ Status = ZwCreateKey( &SubKey, KEY_WRITE, &ObjectAttributes, 0, /* TileIndex */ NULL, /* Class */ REG_OPTION_VOLATILE, NULL); /* Disposition */ if (!NT_SUCCESS(Status)) { DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); ZwClose(InterfaceKey); ZwClose(ClassKey); ExFreePool(InterfaceKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); return Status; } /* Create symbolic link name: \??\ACPI#PNP0501#1#{GUID}\ReferenceString */ SymbolicLinkName->Length = 0; SymbolicLinkName->MaximumLength = SymbolicLinkName->Length + 4 * sizeof(WCHAR) /* 4 = size of \??\ */ + InstancePath->Length + sizeof(WCHAR) /* 1 = size of # */ + GuidString.Length + sizeof(WCHAR); /* final NULL */ if (ReferenceString && ReferenceString->Length) SymbolicLinkName->MaximumLength += sizeof(WCHAR) + ReferenceString->Length; SymbolicLinkName->Buffer = ExAllocatePool( PagedPool, SymbolicLinkName->MaximumLength); if (!SymbolicLinkName->Buffer) { DPRINT("ExAllocatePool() failed\n"); ZwClose(SubKey); ZwClose(InterfaceKey); ZwClose(ClassKey); ExFreePool(InterfaceKeyName.Buffer); ExFreePool(SubKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); return STATUS_INSUFFICIENT_RESOURCES; } RtlAppendUnicodeToString(SymbolicLinkName, L"\\??\\"); StartIndex = SymbolicLinkName->Length / sizeof(WCHAR); RtlAppendUnicodeStringToString(SymbolicLinkName, InstancePath); for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++) { if (SymbolicLinkName->Buffer[StartIndex + i] == '\\') SymbolicLinkName->Buffer[StartIndex + i] = '#'; } RtlAppendUnicodeToString(SymbolicLinkName, L"#"); RtlAppendUnicodeStringToString(SymbolicLinkName, &GuidString); SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0'; /* Create symbolic link */ DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name); SymLinkStatus = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name); /* If the symbolic link already exists, return an informational success status */ if (SymLinkStatus == STATUS_OBJECT_NAME_COLLISION) { /* HACK: Delete the existing symbolic link and update it to the new PDO name */ IoDeleteSymbolicLink(SymbolicLinkName); IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name); SymLinkStatus = STATUS_OBJECT_NAME_EXISTS; } if (!NT_SUCCESS(SymLinkStatus)) { DPRINT1("IoCreateSymbolicLink() failed with status 0x%08lx\n", SymLinkStatus); ZwClose(SubKey); ZwClose(InterfaceKey); ZwClose(ClassKey); ExFreePool(SubKeyName.Buffer); ExFreePool(InterfaceKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); ExFreePool(SymbolicLinkName->Buffer); return SymLinkStatus; } if (ReferenceString && ReferenceString->Length) { RtlAppendUnicodeToString(SymbolicLinkName, L"\\"); RtlAppendUnicodeStringToString(SymbolicLinkName, ReferenceString); } SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0'; /* Write symbolic link name in registry */ SymbolicLinkName->Buffer[1] = '\\'; Status = ZwSetValueKey( SubKey, &SymbolicLink, 0, /* TileIndex */ REG_SZ, SymbolicLinkName->Buffer, SymbolicLinkName->Length); if (!NT_SUCCESS(Status)) { DPRINT1("ZwSetValueKey() failed with status 0x%08lx\n", Status); ExFreePool(SymbolicLinkName->Buffer); } else { SymbolicLinkName->Buffer[1] = '?'; } ZwClose(SubKey); ZwClose(InterfaceKey); ZwClose(ClassKey); ExFreePool(SubKeyName.Buffer); ExFreePool(InterfaceKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); return NT_SUCCESS(Status) ? SymLinkStatus : Status; }
NTSTATUS GetRegistrySettings( _In_ PUNICODE_STRING RegistryPath ) /*++ Routine Description: Initialize Driver Framework settings from the driver specific registry settings under \REGISTRY\MACHINE\SYSTEM\ControlSetxxx\Services\<driver>\Parameters Arguments: RegistryPath - Registry path passed to DriverEntry Returns: NTSTATUS - SUCCESS if able to configure the framework --*/ { NTSTATUS ntStatus; UNICODE_STRING parametersPath; RTL_QUERY_REGISTRY_TABLE paramTable[3]; DPF(D_TERSE, ("[GetRegistrySettings]")); PAGED_CODE(); RtlInitUnicodeString(¶metersPath, NULL); parametersPath.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(WCHAR); parametersPath.Buffer = (PWCH) ExAllocatePoolWithTag(PagedPool, parametersPath.MaximumLength, MINADAPTER_POOLTAG); if (parametersPath.Buffer == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(parametersPath.Buffer, parametersPath.MaximumLength); RtlAppendUnicodeToString(¶metersPath, RegistryPath->Buffer); RtlAppendUnicodeToString(¶metersPath, L"\\Parameters"); RtlZeroMemory(¶mTable[0], sizeof(paramTable)); g_DoNotCreateDataFiles = 0; // default is off. paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; paramTable[0].Name = L"DoNotCreateDataFiles"; paramTable[0].EntryContext = &g_DoNotCreateDataFiles; paramTable[0].DefaultType = REG_DWORD; paramTable[0].DefaultData = &g_DoNotCreateDataFiles; paramTable[0].DefaultLength = sizeof(ULONG); #ifdef SYSVAD_BTH_BYPASS g_DisableBthScoBypass = 0; // default is off. paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; paramTable[1].Name = L"DisableBthScoBypass"; paramTable[1].EntryContext = &g_DisableBthScoBypass; paramTable[1].DefaultType = REG_DWORD; paramTable[1].DefaultData = &g_DisableBthScoBypass; paramTable[1].DefaultLength = sizeof(ULONG); #endif // SYSVAD_BTH_BYPASS ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, parametersPath.Buffer, ¶mTable[0], NULL, NULL ); if (!NT_SUCCESS(ntStatus)) { DPF(D_VERBOSE, ("RtlQueryRegistryValues failed, using default values, 0x%x", ntStatus)); // // Don't return error because we will operate with default values. // } // // Dump settings. // DPF(D_VERBOSE, ("DoNotCreateDataFiles: %u", g_DoNotCreateDataFiles)); #ifdef SYSVAD_BTH_BYPASS DPF(D_VERBOSE, ("DisableBthScoBypass: %u", g_DisableBthScoBypass)); #endif // SYSVAD_BTH_BYPASS // // Cleanup. // ExFreePool(parametersPath.Buffer); return STATUS_SUCCESS; }
/*++ * @name CsrSbApiPortInitialize * * The CsrSbApiPortInitialize routine initializes the LPC Port used for * communications with the Session Manager (SM) and initializes the static * thread that will handle connection requests and APIs. * * @param None * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise. * * @remarks None. * *--*/ NTSTATUS NTAPI CsrSbApiPortInitialize(VOID) { ULONG Size; PSECURITY_DESCRIPTOR PortSd; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE hRequestThread; CLIENT_ID ClientId; /* Calculate how much space we'll need for the Port Name */ Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR); /* Create the buffer for it */ CsrSbApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size); if (!CsrSbApiPortName.Buffer) return STATUS_NO_MEMORY; /* Setup the rest of the empty string */ CsrSbApiPortName.Length = 0; CsrSbApiPortName.MaximumLength = (USHORT)Size; /* Now append the full port name */ RtlAppendUnicodeStringToString(&CsrSbApiPortName, &CsrDirectoryName); RtlAppendUnicodeToString(&CsrSbApiPortName, UNICODE_PATH_SEP); RtlAppendUnicodeToString(&CsrSbApiPortName, SB_PORT_NAME); if (CsrDebug & 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName); /* Create Security Descriptor for this Port */ Status = CsrCreateLocalSystemSD(&PortSd); if (!NT_SUCCESS(Status)) return Status; /* Initialize the Attributes */ InitializeObjectAttributes(&ObjectAttributes, &CsrSbApiPortName, 0, NULL, PortSd); /* Create the Port Object */ Status = NtCreatePort(&CsrSbApiPort, &ObjectAttributes, sizeof(SB_CONNECTION_INFO), sizeof(SB_API_MSG), 32 * sizeof(SB_API_MSG)); if (PortSd) RtlFreeHeap(CsrHeap, 0, PortSd); if (NT_SUCCESS(Status)) { /* Create the Thread to handle the API Requests */ Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, (PVOID)CsrSbApiRequestThread, NULL, &hRequestThread, &ClientId); if (NT_SUCCESS(Status)) { /* Add it as a Static Server Thread */ CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread, &ClientId, 0); /* Activate it */ Status = NtResumeThread(hRequestThread, NULL); } } return Status; }
NTSTATUS NTAPI IntCreateNewRegistryPath( PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension) { static UNICODE_STRING VideoIdValueName = RTL_CONSTANT_STRING(L"VideoId"); static UNICODE_STRING ControlVideoPathName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\"); HANDLE DevInstRegKey, SettingsKey, NewKey; UCHAR VideoIdBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + GUID_STRING_LENGTH]; UNICODE_STRING VideoIdString; UUID VideoId; PKEY_VALUE_PARTIAL_INFORMATION ValueInformation ; NTSTATUS Status; ULONG ResultLength; USHORT KeyMaxLength; OBJECT_ATTRIBUTES ObjectAttributes; /* Open the hardware key: HKLM\System\CurrentControlSet\Enum\... */ Status = IoOpenDeviceRegistryKey(DeviceExtension->PhysicalDeviceObject, PLUGPLAY_REGKEY_DEVICE, KEY_ALL_ACCESS, &DevInstRegKey); if (Status != STATUS_SUCCESS) { ERR_(VIDEOPRT, "IoOpenDeviceRegistryKey failed: status 0x%lx\n", Status); return Status; } /* Query the VideoId value */ ValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)VideoIdBuffer; Status = ZwQueryValueKey(DevInstRegKey, &VideoIdValueName, KeyValuePartialInformation, ValueInformation, sizeof(VideoIdBuffer), &ResultLength); if (!NT_SUCCESS(Status)) { /* Create a new video Id */ Status = ExUuidCreate(&VideoId); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "ExUuidCreate failed: status 0x%lx\n", Status); ObCloseHandle(DevInstRegKey, KernelMode); return Status; } /* Convert the GUID into a string */ Status = RtlStringFromGUID(&VideoId, &VideoIdString); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "RtlStringFromGUID failed: status 0x%lx\n", Status); ObCloseHandle(DevInstRegKey, KernelMode); return Status; } /* Copy the GUID String to our buffer */ ValueInformation->DataLength = min(VideoIdString.Length, GUID_STRING_LENGTH); RtlCopyMemory(ValueInformation->Data, VideoIdString.Buffer, ValueInformation->DataLength); /* Free the GUID string */ RtlFreeUnicodeString(&VideoIdString); /* Write the VideoId registry value */ Status = ZwSetValueKey(DevInstRegKey, &VideoIdValueName, 0, REG_SZ, ValueInformation->Data, ValueInformation->DataLength); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "ZwSetValueKey failed: status 0x%lx\n", Status); ObCloseHandle(DevInstRegKey, KernelMode); return Status; } } /* Initialize the VideoId string from the registry data */ VideoIdString.Buffer = (PWCHAR)ValueInformation->Data; VideoIdString.Length = (USHORT)ValueInformation->DataLength; VideoIdString.MaximumLength = VideoIdString.Length; /* Close the hardware key */ ObCloseHandle(DevInstRegKey, KernelMode); /* Calculate the size needed for the new registry path name */ KeyMaxLength = ControlVideoPathName.Length + VideoIdString.Length + sizeof(L"\\0000"); /* Allocate the path name buffer */ DeviceExtension->NewRegistryPath.Length = 0; DeviceExtension->NewRegistryPath.MaximumLength = KeyMaxLength; DeviceExtension->NewRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, KeyMaxLength, TAG_VIDEO_PORT); if (DeviceExtension->NewRegistryPath.Buffer == NULL) { ERR_(VIDEOPRT, "Failed to allocate key name buffer.\n"); return STATUS_INSUFFICIENT_RESOURCES; } /* Copy the root key name and append the VideoId string */ RtlCopyUnicodeString(&DeviceExtension->NewRegistryPath, &ControlVideoPathName); RtlAppendUnicodeStringToString(&DeviceExtension->NewRegistryPath, &VideoIdString); /* Check if we have the key already */ Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); if (Status != STATUS_SUCCESS) { /* Try to create the new key */ Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); } /* Append a the instance path */ /// \todo HACK RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"\\"); RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"0000"); /* Check this key again */ Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); if (Status != STATUS_SUCCESS) { /* Try to create the new key */ Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "Failed create key '%wZ'\n", &DeviceExtension->NewRegistryPath); return Status; } /* Open the new key */ InitializeObjectAttributes(&ObjectAttributes, &DeviceExtension->NewRegistryPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&NewKey, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status); return Status; } /* Open the device profile key */ InitializeObjectAttributes(&ObjectAttributes, &DeviceExtension->RegistryPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&SettingsKey, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status); ObCloseHandle(NewKey, KernelMode); return Status; } /* Copy the registry data from the legacy key */ Status = IntCopyRegistryKey(SettingsKey, NewKey); } return Status; }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) /*++ Routine Description: This routine is called when the driver is loaded by NT. Arguments: DriverObject - Pointer to driver object created by system. RegistryPath - Pointer to the name of the services node for this driver. Return Value: The function value is the final status from the initialization operation. --*/ { NTSTATUS ntStatus; PVOID BufDriverString=NULL,BufProcessEventString=NULL,BufThreadEventString=NULL; UNICODE_STRING uszDriverString; UNICODE_STRING uszProcessEventString; UNICODE_STRING uszThreadEventString; PDEVICE_OBJECT pDeviceObject; HANDLE reg=0; OBJECT_ATTRIBUTES oa; UNICODE_STRING temp; char wbuf[100]; WORD this_cs, this_ss, this_ds, this_es, this_fs, this_gs; ULONG cr4reg; criticalSection csTest; HANDLE Ultimap2Handle; KernelCodeStepping=0; KernelWritesIgnoreWP = 0; this_cs=getCS(); this_ss=getSS(); this_ds=getDS(); this_es=getES(); this_fs=getFS(); this_gs=getGS(); //InitializeObjectAttributes(&ao, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); //PsCreateSystemThread(&Ultimap2Handle, 0, NULL, 0, NULL, TestThread, PsGetCurrentProcess()); DbgPrint("DBK loading..."); #ifdef TOBESIGNED DbgPrint("Signed version"); #endif //lame antiviruses and more lamer users that keep crying rootkit virus.... temp.Buffer=(PWCH)wbuf; temp.Length=0; temp.MaximumLength=100; RtlAppendUnicodeToString(&temp, L"Ke"); //KeServiceDescriptorTable RtlAppendUnicodeToString(&temp, L"Service"); RtlAppendUnicodeToString(&temp, L"Descriptor"); RtlAppendUnicodeToString(&temp, L"Table"); KeServiceDescriptorTable=MmGetSystemRoutineAddress(&temp); DbgPrint("Loading driver\n"); if (RegistryPath) { DbgPrint("Registry path = %S\n", RegistryPath->Buffer); InitializeObjectAttributes(&oa,RegistryPath,OBJ_KERNEL_HANDLE ,NULL,NULL); ntStatus=ZwOpenKey(®,KEY_QUERY_VALUE,&oa); if (ntStatus == STATUS_SUCCESS) { UNICODE_STRING A,B,C,D; PKEY_VALUE_PARTIAL_INFORMATION bufA,bufB,bufC,bufD; ULONG ActualSize; DbgPrint("Opened the key\n"); BufDriverString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufDeviceString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufProcessEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufThreadEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); bufA=BufDriverString; bufB=BufDeviceString; bufC=BufProcessEventString; bufD=BufThreadEventString; RtlInitUnicodeString(&A, L"A"); RtlInitUnicodeString(&B, L"B"); RtlInitUnicodeString(&C, L"C"); RtlInitUnicodeString(&D, L"D"); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&A,KeyValuePartialInformation ,bufA,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&B,KeyValuePartialInformation ,bufB,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&C,KeyValuePartialInformation ,bufC,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&D,KeyValuePartialInformation ,bufD,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) { DbgPrint("Read ok\n"); RtlInitUnicodeString(&uszDriverString,(PCWSTR) bufA->Data); RtlInitUnicodeString(&uszDeviceString,(PCWSTR) bufB->Data); RtlInitUnicodeString(&uszProcessEventString,(PCWSTR) bufC->Data); RtlInitUnicodeString(&uszThreadEventString,(PCWSTR) bufD->Data); DbgPrint("DriverString=%S\n",uszDriverString.Buffer); DbgPrint("DeviceString=%S\n",uszDeviceString.Buffer); DbgPrint("ProcessEventString=%S\n",uszProcessEventString.Buffer); DbgPrint("ThreadEventString=%S\n",uszThreadEventString.Buffer); } else { ExFreePool(bufA); ExFreePool(bufB); ExFreePool(bufC); ExFreePool(bufD); DbgPrint("Failed reading the value\n"); ZwClose(reg); return STATUS_UNSUCCESSFUL;; } } else { DbgPrint("Failed opening the key\n"); return STATUS_UNSUCCESSFUL;; } } else loadedbydbvm=TRUE; ntStatus = STATUS_SUCCESS; if (!loadedbydbvm) { // Point uszDriverString at the driver name #ifndef CETC // Create and initialize device object ntStatus = IoCreateDevice(DriverObject, 0, &uszDriverString, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject); if(ntStatus != STATUS_SUCCESS) { DbgPrint("IoCreateDevice failed\n"); ExFreePool(BufDriverString); ExFreePool(BufDeviceString); ExFreePool(BufProcessEventString); ExFreePool(BufThreadEventString); if (reg) ZwClose(reg); return ntStatus; } // Point uszDeviceString at the device name // Create symbolic link to the user-visible name ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString); if(ntStatus != STATUS_SUCCESS) { DbgPrint("IoCreateSymbolicLink failed: %x\n",ntStatus); // Delete device object if not successful IoDeleteDevice(pDeviceObject); ExFreePool(BufDriverString); ExFreePool(BufDeviceString); ExFreePool(BufProcessEventString); ExFreePool(BufThreadEventString); if (reg) ZwClose(reg); return ntStatus; } #endif } //when loaded by dbvm driver object is 'valid' so store the function addresses DbgPrint("DriverObject=%p\n", DriverObject); // Load structure to point to IRP handlers... DriverObject->DriverUnload = UnloadDriver; DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; if (loadedbydbvm) DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DispatchIoctlDBVM; else DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; //Processlist init #ifndef CETC ProcessEventCount=0; KeInitializeSpinLock(&ProcesslistSL); #endif CreateProcessNotifyRoutineEnabled=FALSE; //threadlist init ThreadEventCount=0; BufferSize=0; processlist=NULL; #ifndef AMD64 //determine if PAE is used cr4reg=(ULONG)getCR4(); if ((cr4reg & 0x20)==0x20) { PTESize=8; //pae PAGE_SIZE_LARGE=0x200000; MAX_PDE_POS=0xC0604000; MAX_PTE_POS=0xC07FFFF8; } else { PTESize=4; PAGE_SIZE_LARGE=0x400000; MAX_PDE_POS=0xC0301000; MAX_PTE_POS=0xC03FFFFC; } #else PTESize=8; //pae PAGE_SIZE_LARGE=0x200000; MAX_PTE_POS=0xFFFFF6FFFFFFFFF8ULL; MAX_PDE_POS=0xFFFFF6FB7FFFFFF8ULL; #endif #ifdef CETC DbgPrint("Going to initialice CETC\n"); InitializeCETC(); #endif //hideme(DriverObject); //ok, for those that see this, enabling this WILL f**k up try except routines, even in usermode you'll get a blue sreen DbgPrint("Initializing debugger\n"); debugger_initialize(); // Return success (don't do the devicestring, I need it for unload) DbgPrint("Cleaning up initialization buffers\n"); if (BufDriverString) { ExFreePool(BufDriverString); BufDriverString=NULL; } if (BufProcessEventString) { ExFreePool(BufProcessEventString); BufProcessEventString=NULL; } if (BufThreadEventString) { ExFreePool(BufThreadEventString); BufThreadEventString=NULL; } if (reg) { ZwClose(reg); reg=0; } //fetch cpu info { DWORD r[4]; DWORD a; __cpuid(r,0); DbgPrint("cpuid.0: r[1]=%x", r[1]); if (r[1]==0x756e6547) //GenuineIntel { __cpuid(r,1); a=r[0]; cpu_stepping=a & 0xf; cpu_model=(a >> 4) & 0xf; cpu_familyID=(a >> 8) & 0xf; cpu_type=(a >> 12) & 0x3; cpu_ext_modelID=(a >> 16) & 0xf; cpu_ext_familyID=(a >> 20) & 0xff; cpu_model=cpu_model + (cpu_ext_modelID << 4); cpu_familyID=cpu_familyID + (cpu_ext_familyID << 4); if ((r[2]<<9) & 1) { DbgPrint("Intel cpu. IA32_FEATURE_CONTROL MSR=%x", readMSR(0x3a)); } else { DbgPrint("Intel cpu without IA32_FEATURE_CONTROL MSR"); } vmx_init_dovmcall(1); setup_APIC_BASE(); //for ultimap } else {
NTSTATUS NTAPI IntCreateRegistryPath( IN PCUNICODE_STRING DriverRegistryPath, OUT PUNICODE_STRING DeviceRegistryPath) { static WCHAR RegistryMachineSystem[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\"; static WCHAR CurrentControlSet[] = L"CURRENTCONTROLSET\\"; static WCHAR ControlSet[] = L"CONTROLSET"; static WCHAR Insert1[] = L"Hardware Profiles\\Current\\System\\CurrentControlSet\\"; static WCHAR Insert2[] = L"\\Device0"; BOOLEAN Valid; UNICODE_STRING AfterControlSet; AfterControlSet = *DriverRegistryPath; /* Check if path begins with \\REGISTRY\\MACHINE\\SYSTEM\\ */ Valid = (DriverRegistryPath->Length > sizeof(RegistryMachineSystem) && 0 == _wcsnicmp(DriverRegistryPath->Buffer, RegistryMachineSystem, wcslen(RegistryMachineSystem))); if (Valid) { AfterControlSet.Buffer += wcslen(RegistryMachineSystem); AfterControlSet.Length -= sizeof(RegistryMachineSystem) - sizeof(UNICODE_NULL); /* Check if path contains CURRENTCONTROLSET */ if (AfterControlSet.Length > sizeof(CurrentControlSet) && 0 == _wcsnicmp(AfterControlSet.Buffer, CurrentControlSet, wcslen(CurrentControlSet))) { AfterControlSet.Buffer += wcslen(CurrentControlSet); AfterControlSet.Length -= sizeof(CurrentControlSet) - sizeof(UNICODE_NULL); } /* Check if path contains CONTROLSETnum */ else if (AfterControlSet.Length > sizeof(ControlSet) && 0 == _wcsnicmp(AfterControlSet.Buffer, ControlSet, wcslen(ControlSet))) { AfterControlSet.Buffer += wcslen(ControlSet); AfterControlSet.Length -= sizeof(ControlSet) - sizeof(UNICODE_NULL); while (AfterControlSet.Length > 0 && *AfterControlSet.Buffer >= L'0' && *AfterControlSet.Buffer <= L'9') { AfterControlSet.Buffer++; AfterControlSet.Length -= sizeof(WCHAR); } Valid = (AfterControlSet.Length > 0 && L'\\' == *AfterControlSet.Buffer); AfterControlSet.Buffer++; AfterControlSet.Length -= sizeof(WCHAR); AfterControlSet.MaximumLength = AfterControlSet.Length; } else { Valid = FALSE; } } if (Valid) { DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert1) + sizeof(Insert2); DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(PagedPool, DeviceRegistryPath->MaximumLength, TAG_VIDEO_PORT); if (DeviceRegistryPath->Buffer != NULL) { /* Build device path */ wcsncpy(DeviceRegistryPath->Buffer, DriverRegistryPath->Buffer, AfterControlSet.Buffer - DriverRegistryPath->Buffer); DeviceRegistryPath->Length = (AfterControlSet.Buffer - DriverRegistryPath->Buffer) * sizeof(WCHAR); RtlAppendUnicodeToString(DeviceRegistryPath, Insert1); RtlAppendUnicodeStringToString(DeviceRegistryPath, &AfterControlSet); RtlAppendUnicodeToString(DeviceRegistryPath, Insert2); /* Check if registry key exists */ Valid = NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceRegistryPath->Buffer)); if (!Valid) ExFreePoolWithTag(DeviceRegistryPath->Buffer, TAG_VIDEO_PORT); } else { Valid = FALSE; } } else { WARN_(VIDEOPRT, "Unparsable registry path %wZ", DriverRegistryPath); } /* If path doesn't point to *ControlSet*, use DriverRegistryPath directly */ if (!Valid) { DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert2); DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(NonPagedPool, DeviceRegistryPath->MaximumLength, TAG_VIDEO_PORT); if (!DeviceRegistryPath->Buffer) return STATUS_NO_MEMORY; RtlCopyUnicodeString(DeviceRegistryPath, DriverRegistryPath); RtlAppendUnicodeToString(DeviceRegistryPath, Insert2); } DbgPrint("Formatted registry key '%wZ' -> '%wZ'\n", DriverRegistryPath, DeviceRegistryPath); return STATUS_SUCCESS; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Registry callback. Logs any registry interaction performed by monitored processes. // Parameters : // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff560903(v=vs.85).aspx // Return value : // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff560903(v=vs.85).aspx // Process : // Checks the operation and logs the associated data. ////////////////////////////////////////////////////////////////////////////////////////////////////////////// NTSTATUS regCallback (PVOID CallbackContext, PVOID Argument1, PVOID Argument2) { NTSTATUS status, tmpCall; UNICODE_STRING full_data, test; PUNICODE_STRING tmp = NULL; PUNICODE_STRING valueName = NULL; PREG_SET_VALUE_KEY_INFORMATION arg = NULL; ULONG returnedLength = 0; PWCHAR pwBuf = NULL; PWCHAR tmp_data = NULL; ULONG pid = (ULONG)PsGetCurrentProcessId(); DWORD i = 0; if(!isProcessMonitoredByPid(pid) || ExGetPreviousMode() == KernelMode) return STATUS_SUCCESS; pwBuf = ExAllocatePoolWithTag(NonPagedPool, (MAXSIZE+1)*sizeof(WCHAR), BUFFER_TAG); if(pwBuf == NULL) return STATUS_SUCCESS; tmp = ExAllocatePoolWithTag(NonPagedPool, MAXSIZE*sizeof(WCHAR), TEMP_TAG); if(tmp == NULL) { ExFreePool(tmp); return STATUS_SUCCESS; } switch((REG_NOTIFY_CLASS)Argument1) { case RegNtPreDeleteKey: status = ObQueryNameString(((PREG_DELETE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength); if(NT_SUCCESS(status)) { #ifdef DEBUG DbgPrint("call DeleteKey() \n"); #endif if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp))) sendLogs(pid, L"REGISTRY_DELETE_KEY", pwBuf); else sendLogs(pid, L"REGISTRY_DELETE_KEY", L"1,0,s,SubKey->ERROR"); } else sendLogs(pid, L"REGISTRY_DELETE_KEY", L"0,-1,s,SubKey->ERROR"); break; case RegNtPreSetValueKey: arg = (PREG_SET_VALUE_KEY_INFORMATION)Argument2; status = ObQueryNameString(arg->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength); if(NT_SUCCESS(status)) { #ifdef DEBUG DbgPrint("call SetValueKey() \n"); #endif switch(arg->Type) { case REG_SZ: tmpCall = RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,sss,SubKey->%wZ,ValueName->%wZ,Data->%ws", tmp, arg->ValueName, ((PWCHAR)arg->Data)); break; default : tmp_data = ExAllocatePoolWithTag(NonPagedPool, MAXSIZE, 'gnaA'); full_data.MaximumLength = MAXSIZE; full_data.Buffer = ExAllocatePoolWithTag(NonPagedPool, full_data.MaximumLength, 'baaH'); RtlZeroMemory(full_data.Buffer, full_data.MaximumLength); for(i=0; i<arg->DataSize; i++) { if(i==100) break; RtlStringCchPrintfW(tmp_data, MAXSIZE, L"\\x%02x", *((PWCHAR)arg->Data+i)); if(i==0) { RtlInitUnicodeString(&test, tmp_data); RtlCopyUnicodeString(&full_data, &test); } if(NT_SUCCESS(RtlAppendUnicodeToString(&full_data, tmp_data))) RtlZeroMemory(tmp_data, MAXSIZE); } tmpCall = RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,sss,SubKey->%wZ,ValueName->%wZ,Data->%wZ", tmp, arg->ValueName, &full_data); ExFreePool(full_data.Buffer); ExFreePool(tmp_data); break; } if(NT_SUCCESS(tmpCall)) sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", pwBuf); else sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", L"1,0,sss,SubKey->ERROR,ValueName->ERROR,Data->ERROR"); } else sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", L"1,0,sss,SubKey->ERROR,ValueName->ERROR,Data->ERROR"); break; case RegNtPreDeleteValueKey: status = ObQueryNameString(((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength); if(NT_SUCCESS(status)) { #ifdef DEBUG DbgPrint("call DeleteValueKey() !\n"); #endif if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,ValueName->%wZ", tmp, ((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->ValueName))) sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", pwBuf); else sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", L"1,0,ss,SubKey->ERROR,ValueName->ERROR"); } else sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", L"1,0,ss,SubKey->ERROR,ValueName->ERROR"); break; case RegNtPreRenameKey: status = ObQueryNameString(((PREG_RENAME_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength); if(NT_SUCCESS(status)) { #ifdef DEBUG DbgPrint("call RenameKey() !\n"); #endif if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,NewName->%wZ", tmp, ((PREG_RENAME_KEY_INFORMATION)Argument2)->NewName))) sendLogs(pid, L"REGISTRY_KEY_RENAME", pwBuf); else sendLogs(pid, L"REGISTRY_KEY_RENAME", L"1,0,ss,SubKey->ERROR,NewName->ERROR"); } else sendLogs(pid, L"REGISTRY_KEY_RENAME", L"1,0,ss,SubKey->ERROR,NewName->ERROR"); break; case RegNtPreEnumerateKey: status = ObQueryNameString(((PREG_ENUMERATE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength); if(NT_SUCCESS(status)) { #ifdef DEBUG DbgPrint("call EnumerateKey() !\n"); #endif if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp))) sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", pwBuf); else sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", L"1,0,s,SubKey->ERROR"); } else sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", L"1,0,s,SubKey->ERROR"); break; case RegNtPreEnumerateValueKey: status = ObQueryNameString(((PREG_ENUMERATE_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength); if(NT_SUCCESS(status)) { #ifdef DEBUG DbgPrint("call EnumerateValueKey() !\n"); #endif if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp))) sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", pwBuf); else sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", L"1,0,s,SubKey->ERROR"); } else sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", L"1,0,s,SubKey->ERROR"); break; case RegNtPreQueryKey: status = ObQueryNameString(((PREG_QUERY_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength); if(NT_SUCCESS(status)) { #ifdef DEBUG DbgPrint("call QueryKey()! \n"); #endif if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp))) sendLogs(pid, L"REGISTRY_QUERY_KEY", pwBuf); else sendLogs(pid, L"REGISTRY_QUERY_KEY", L"1,0,s,SubKey->ERROR"); } else sendLogs(pid, L"REGISTRY_QUERY_KEY", L"1,0,s,SubKey->ERROR"); break; case RegNtPreQueryValueKey: status = ObQueryNameString(((PREG_QUERY_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength); if(NT_SUCCESS(status)) { #ifdef DEBUG DbgPrint("call QueryValueKey() !\n"); #endif if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,ValueName->%wZ", tmp, ((PREG_QUERY_VALUE_KEY_INFORMATION)Argument2)->ValueName))) sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", pwBuf); else sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", L"1,0,ss,SubKey->ERROR,ValueName->ERROR"); } else sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", L"1,0,ss,SubKey->ERROR,ValueName->ERROR"); break; case RegNtPreCreateKey: #ifdef DEBUG DbgPrint("call CreateKey() !\n"); #endif if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_PRE_CREATE_KEY_INFORMATION)Argument2)->CompleteName))) sendLogs(pid,L"REGISTRY_CREATE_KEY", pwBuf); else sendLogs(pid, L"REGISTRY_CREATE_KEY", L"1,0,s,SubKey->ERROR"); break; case RegNtPreCreateKeyEx: #ifdef DEBUG DbgPrint("call CreateKeyEx() !\n"); #endif if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_PRE_CREATE_KEY_INFORMATION)Argument2)->CompleteName))) sendLogs(pid,L"REGISTRY_CREATE_KEY", pwBuf); else sendLogs(pid, L"REGISTRY_CREATE_KEY", L"1,0,s,SubKey->ERROR"); break; case RegNtPreOpenKey: #ifdef DEBUG DbgPrint("call OpenKey() !\n"); #endif if(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer != NULL) { if(!_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\Oracle\\VirtualBox Guest Additions") || !_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\VMware, Inc.\\VMware Tools")) { if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"0,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName))) sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf); return STATUS_OBJECT_NAME_NOT_FOUND; } if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName))) sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf); else sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR"); } else sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR"); break; case RegNtPreOpenKeyEx: #ifdef DEBUG DbgPrint("call OpenKeyEx() !\n"); #endif if(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer != NULL) { if(!_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\Oracle\\VirtualBox Guest Additions") || !_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\VMware, Inc.\\VMware Tools")) { if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"0,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName))) sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf); return STATUS_OBJECT_NAME_NOT_FOUND; } if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName))) sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf); else sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR"); } else sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR"); break; default: break; } ExFreePool(tmp); ExFreePool(pwBuf); return STATUS_SUCCESS; }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) /*++ Routine Description: This routine is called when the driver is loaded by NT. Arguments: DriverObject - Pointer to driver object created by system. RegistryPath - Pointer to the name of the services node for this driver. Return Value: The function value is the final status from the initialization operation. --*/ { NTSTATUS ntStatus; PVOID BufDriverString=NULL,BufProcessEventString=NULL,BufThreadEventString=NULL; UNICODE_STRING uszDriverString; UNICODE_STRING uszProcessEventString; UNICODE_STRING uszThreadEventString; PDEVICE_OBJECT pDeviceObject; HANDLE reg=0; OBJECT_ATTRIBUTES oa; UNICODE_STRING temp; char wbuf[100]; WORD this_cs, this_ss, this_ds, this_es, this_fs, this_gs; ULONG cr4reg; criticalSection csTest; DbgPrint("I'm alive!\n"); //DbgPrint("%S",oa.ObjectName.Buffer); KernelCodeStepping=0; this_cs=getCS(); this_ss=getSS(); this_ds=getDS(); this_es=getES(); this_fs=getFS(); this_gs=getGS(); #ifdef AMD64 DbgPrint("cs=%x ss=%x ds=%x es=%x fs=%x gs=%x\n",getCS(), getSS(), getDS(), getES(), getFS(), getGS()); DbgPrint("fsbase=%llx gsbase=%llx gskernel=%llx\n", readMSR(0xc0000100), readMSR(0xc0000101), readMSR(0xc0000102)); DbgPrint("rbp=%llx\n", getRBP()); DbgPrint("gs:188=%llx\n", __readgsqword(0x188)); DbgPrint("current csr=%x\n", _mm_getcsr()); #endif DbgPrint("Test critical section routines\n"); RtlZeroMemory(&csTest,sizeof(criticalSection)); DbgPrint("csTest.locked=%d\n",csTest.locked); csEnter(&csTest); DbgPrint("After enter\n"); DbgPrint("csTest.locked=%d\n",csTest.locked); csLeave(&csTest); DbgPrint("After leave\n"); DbgPrint("csTest.locked=%d\n",csTest.locked); //lame antiviruses and more lamer users that keep crying rootkit virus.... temp.Buffer=(PWCH)wbuf; temp.Length=0; temp.MaximumLength=100; RtlAppendUnicodeToString(&temp, L"Ke"); //KeServiceDescriptorTable RtlAppendUnicodeToString(&temp, L"Service"); RtlAppendUnicodeToString(&temp, L"Descriptor"); RtlAppendUnicodeToString(&temp, L"Table"); KeServiceDescriptorTable=MmGetSystemRoutineAddress(&temp); DbgPrint("Loading driver\n"); if (RegistryPath) { DbgPrint("Registry path = %S\n", RegistryPath->Buffer); InitializeObjectAttributes(&oa,RegistryPath,OBJ_KERNEL_HANDLE ,NULL,NULL); ntStatus=ZwOpenKey(®,KEY_QUERY_VALUE,&oa); if (ntStatus == STATUS_SUCCESS) { UNICODE_STRING A,B,C,D; PKEY_VALUE_PARTIAL_INFORMATION bufA,bufB,bufC,bufD; ULONG ActualSize; DbgPrint("Opened the key\n"); BufDriverString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufDeviceString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufProcessEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufThreadEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); bufA=BufDriverString; bufB=BufDeviceString; bufC=BufProcessEventString; bufD=BufThreadEventString; RtlInitUnicodeString(&A, L"A"); RtlInitUnicodeString(&B, L"B"); RtlInitUnicodeString(&C, L"C"); RtlInitUnicodeString(&D, L"D"); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&A,KeyValuePartialInformation ,bufA,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&B,KeyValuePartialInformation ,bufB,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&C,KeyValuePartialInformation ,bufC,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&D,KeyValuePartialInformation ,bufD,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) { DbgPrint("Read ok\n"); RtlInitUnicodeString(&uszDriverString,(PCWSTR) bufA->Data); RtlInitUnicodeString(&uszDeviceString,(PCWSTR) bufB->Data); RtlInitUnicodeString(&uszProcessEventString,(PCWSTR) bufC->Data); RtlInitUnicodeString(&uszThreadEventString,(PCWSTR) bufD->Data); DbgPrint("DriverString=%S\n",uszDriverString.Buffer); DbgPrint("DeviceString=%S\n",uszDeviceString.Buffer); DbgPrint("ProcessEventString=%S\n",uszProcessEventString.Buffer); DbgPrint("ThreadEventString=%S\n",uszThreadEventString.Buffer); } else { ExFreePool(bufA); ExFreePool(bufB); ExFreePool(bufC); ExFreePool(bufD); DbgPrint("Failed reading the value\n"); ZwClose(reg); return STATUS_UNSUCCESSFUL;; } } else { DbgPrint("Failed opening the key\n"); return STATUS_UNSUCCESSFUL;; } } else loadedbydbvm=TRUE; ntStatus = STATUS_SUCCESS; if (!loadedbydbvm) { // Point uszDriverString at the driver name #ifndef CETC // Create and initialize device object ntStatus = IoCreateDevice(DriverObject, 0, &uszDriverString, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject); if(ntStatus != STATUS_SUCCESS) { DbgPrint("IoCreateDevice failed\n"); ExFreePool(BufDriverString); ExFreePool(BufDeviceString); ExFreePool(BufProcessEventString); ExFreePool(BufThreadEventString); if (reg) ZwClose(reg); return ntStatus; } // Point uszDeviceString at the device name // Create symbolic link to the user-visible name ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString); if(ntStatus != STATUS_SUCCESS) { DbgPrint("IoCreateSymbolicLink failed: %x\n",ntStatus); // Delete device object if not successful IoDeleteDevice(pDeviceObject); ExFreePool(BufDriverString); ExFreePool(BufDeviceString); ExFreePool(BufProcessEventString); ExFreePool(BufThreadEventString); if (reg) ZwClose(reg); return ntStatus; } #endif } //when loaded by dbvm driver object is 'valid' so store the function addresses DbgPrint("DriverObject=%p\n", DriverObject); // Load structure to point to IRP handlers... DriverObject->DriverUnload = UnloadDriver; DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; if (loadedbydbvm) DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DispatchIoctlDBVM; else DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; //Processlist init #ifndef CETC ProcessEventCount=0; KeInitializeSpinLock(&ProcesslistSL); #endif CreateProcessNotifyRoutineEnabled=FALSE; //threadlist init ThreadEventCount=0; BufferSize=0; processlist=NULL; #ifndef AMD64 //determine if PAE is used cr4reg=(ULONG)getCR4(); if ((cr4reg & 0x20)==0x20) { PTESize=8; //pae PAGE_SIZE_LARGE=0x200000; MAX_PDE_POS=0xC0604000; MAX_PTE_POS=0xC07FFFF8; } else { PTESize=4; PAGE_SIZE_LARGE=0x400000; MAX_PDE_POS=0xC0301000; MAX_PTE_POS=0xC03FFFFC; } #else PTESize=8; //pae PAGE_SIZE_LARGE=0x200000; MAX_PTE_POS=0xFFFFF6FFFFFFFFF8ULL; MAX_PDE_POS=0xFFFFF6FB7FFFFFF8ULL; #endif #ifdef CETC DbgPrint("Going to initialice CETC\n"); InitializeCETC(); #endif //hideme(DriverObject); //ok, for those that see this, enabling this WILL f**k up try except routines, even in usermode you'll get a blue sreen DbgPrint("Initializing debugger\n"); debugger_initialize(); // Return success (don't do the devicestring, I need it for unload) DbgPrint("Cleaning up initialization buffers\n"); if (BufDriverString) { ExFreePool(BufDriverString); BufDriverString=NULL; } if (BufProcessEventString) { ExFreePool(BufProcessEventString); BufProcessEventString=NULL; } if (BufThreadEventString) { ExFreePool(BufThreadEventString); BufThreadEventString=NULL; } if (reg) { ZwClose(reg); reg=0; } //fetch cpu info { DWORD r[4]; DWORD a; __cpuid(r,1); a=r[0]; cpu_stepping=a & 0xf; cpu_model=(a >> 4) & 0xf; cpu_familyID=(a >> 8) & 0xf; cpu_type=(a >> 12) & 0x3; cpu_ext_modelID=(a >> 16) & 0xf; cpu_ext_familyID=(a >> 20) & 0xff; cpu_model=cpu_model + (cpu_ext_modelID << 4); cpu_familyID=cpu_familyID + (cpu_ext_familyID << 4); } { APIC y; DebugStackState x; DbgPrint("offset of LBR_Count=%d\n", (UINT_PTR)&x.LBR_Count-(UINT_PTR)&x); DbgPrint("Testing forEachCpu(...)\n"); forEachCpu(TestDPC, NULL, NULL, NULL); forEachCpuPassive(TestPassive, 0); DbgPrint("LVT_Performance_Monitor=%x\n", (UINT_PTR)&y.LVT_Performance_Monitor-(UINT_PTR)&y); } return STATUS_SUCCESS; }
BOOLEAN WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead, LPWSTR RegistryPath, LPWSTR ImagePath, LPWSTR ServiceName) { PBOOT_DRIVER_LIST_ENTRY BootDriverEntry; NTSTATUS Status; USHORT PathLength; BootDriverEntry = MmHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY)); if (!BootDriverEntry) return FALSE; // DTE will be filled during actual load of the driver BootDriverEntry->LdrEntry = NULL; // Check - if we have a valid ImagePath, if not - we need to build it // like "System32\\Drivers\\blah.sys" if (ImagePath && (wcslen(ImagePath) > 0)) { // Just copy ImagePath to the corresponding field in the structure PathLength = wcslen(ImagePath) * sizeof(WCHAR) + sizeof(UNICODE_NULL); BootDriverEntry->FilePath.Length = 0; BootDriverEntry->FilePath.MaximumLength = PathLength; BootDriverEntry->FilePath.Buffer = MmHeapAlloc(PathLength); if (!BootDriverEntry->FilePath.Buffer) { MmHeapFree(BootDriverEntry); return FALSE; } Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath); if (!NT_SUCCESS(Status)) { MmHeapFree(BootDriverEntry->FilePath.Buffer); MmHeapFree(BootDriverEntry); return FALSE; } } else { // we have to construct ImagePath ourselves PathLength = wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys"); BootDriverEntry->FilePath.Length = 0; BootDriverEntry->FilePath.MaximumLength = PathLength; BootDriverEntry->FilePath.Buffer = MmHeapAlloc(PathLength); if (!BootDriverEntry->FilePath.Buffer) { MmHeapFree(BootDriverEntry); return FALSE; } Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\"); if (!NT_SUCCESS(Status)) { MmHeapFree(BootDriverEntry->FilePath.Buffer); MmHeapFree(BootDriverEntry); return FALSE; } Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName); if (!NT_SUCCESS(Status)) { MmHeapFree(BootDriverEntry->FilePath.Buffer); MmHeapFree(BootDriverEntry); return FALSE; } Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys"); if (!NT_SUCCESS(Status)) { MmHeapFree(BootDriverEntry->FilePath.Buffer); MmHeapFree(BootDriverEntry); return FALSE; } } // Add registry path PathLength = (wcslen(RegistryPath) + wcslen(ServiceName))*sizeof(WCHAR) + sizeof(UNICODE_NULL); BootDriverEntry->RegistryPath.Length = 0; BootDriverEntry->RegistryPath.MaximumLength = PathLength; BootDriverEntry->RegistryPath.Buffer = MmHeapAlloc(PathLength); if (!BootDriverEntry->RegistryPath.Buffer) return FALSE; Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, RegistryPath); if (!NT_SUCCESS(Status)) return FALSE; Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, ServiceName); if (!NT_SUCCESS(Status)) return FALSE; // Insert entry at top of the list InsertTailList(BootDriverListHead, &BootDriverEntry->Link); return TRUE; }
NTSTATUS CsrpConnectToServer( IN PWSTR ObjectDirectory ) { NTSTATUS Status; REMOTE_PORT_VIEW ServerView; ULONG MaxMessageLength; ULONG ConnectionInformationLength; CSR_API_CONNECTINFO ConnectionInformation; SECURITY_QUALITY_OF_SERVICE DynamicQos; HANDLE PortSection; PORT_VIEW ClientView; ULONG n; LARGE_INTEGER SectionSize; // // Create the port name string by combining the passed in object directory // name with the port name. // n = ((wcslen( ObjectDirectory ) + 1) * sizeof( WCHAR )) + sizeof( CSR_API_PORT_NAME ); CsrPortName.Length = 0; CsrPortName.MaximumLength = (USHORT)n; CsrPortName.Buffer = RtlAllocateHeap( CsrHeap, MAKE_TAG( CSR_TAG ), n ); if (CsrPortName.Buffer == NULL) { return( STATUS_NO_MEMORY ); } RtlAppendUnicodeToString( &CsrPortName, ObjectDirectory ); RtlAppendUnicodeToString( &CsrPortName, L"\\" ); RtlAppendUnicodeToString( &CsrPortName, CSR_API_PORT_NAME ); // // Set up the security quality of service parameters to use over the // port. Use the most efficient (least overhead) - which is dynamic // rather than static tracking. // DynamicQos.ImpersonationLevel = SecurityImpersonation; DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; DynamicQos.EffectiveOnly = TRUE; // // Create a section to contain the Port Memory. Port Memory is private // memory that is shared between the client and server processes. // This allows data that is too large to fit into an API request message // to be passed to the server. // SectionSize.LowPart = CSR_PORT_MEMORY_SIZE; SectionSize.HighPart = 0; Status = NtCreateSection( &PortSection, SECTION_ALL_ACCESS, NULL, &SectionSize, PAGE_READWRITE, SEC_RESERVE, NULL ); if (!NT_SUCCESS( Status )) { return( Status ); } // // Connect to the server. This includes a description of the Port Memory // section so that the LPC connection logic can make the section visible // to both the client and server processes. Also pass information the // server needs in the connection information structure. // ClientView.Length = sizeof( ClientView ); ClientView.SectionHandle = PortSection; ClientView.SectionOffset = 0; ClientView.ViewSize = SectionSize.LowPart; ClientView.ViewBase = 0; ClientView.ViewRemoteBase = 0; ServerView.Length = sizeof( ServerView ); ServerView.ViewSize = 0; ServerView.ViewBase = 0; ConnectionInformationLength = sizeof( ConnectionInformation ); ConnectionInformation.ExpectedVersion = CSR_VERSION; Status = NtConnectPort( &CsrPortHandle, &CsrPortName, &DynamicQos, &ClientView, &ServerView, (PULONG)&MaxMessageLength, (PVOID)&ConnectionInformation, (PULONG)&ConnectionInformationLength ); NtClose( PortSection ); if (!NT_SUCCESS( Status )) { IF_DEBUG { DbgPrint( "CSRDLL: Unable to connect to %wZ Server - Status == %X\n", &CsrPortName, Status ); } return( Status ); }
BOOLEAN LogMessage(PCHAR szFormat, ...) { ULONG Length; char messagebuf[256]; va_list va; IO_STATUS_BLOCK IoStatus; OBJECT_ATTRIBUTES objectAttributes; NTSTATUS status; HANDLE FileHandle; UNICODE_STRING fileName; //format the string va_start(va,szFormat); vsprintf(messagebuf,szFormat,va); va_end(va); //get a handle to the log file object fileName.Buffer = NULL; fileName.Length = 0; fileName.MaximumLength = sizeof(DEFAULT_LOG_FILE_NAME) + sizeof(UNICODE_NULL); fileName.Buffer = ExAllocatePool(PagedPool, fileName.MaximumLength); if (!fileName.Buffer) { return FALSE; } RtlZeroMemory(fileName.Buffer, fileName.MaximumLength); status = RtlAppendUnicodeToString(&fileName, (PWSTR)DEFAULT_LOG_FILE_NAME); //DbgPrint("\n Initializing Object attributes"); InitializeObjectAttributes (&objectAttributes, (PUNICODE_STRING)&fileName, OBJ_CASE_INSENSITIVE, NULL, NULL ); DbgPrint("\n BusLogic - Creating the file"); status = ZwCreateFile(&FileHandle, FILE_APPEND_DATA | SYNCHRONIZE, &objectAttributes, &IoStatus, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if(NT_SUCCESS(status)) { CHAR buf[300]; LARGE_INTEGER time; KeQuerySystemTime(&time); DbgPrint("\n BusLogic - Created the file"); //put a time stamp on the output message sprintf(buf,"%10u-%10u %s",time.HighPart,time.LowPart,messagebuf); //format the string to make sure it appends a newline carrage-return to the //end of the string. Length=strlen(buf); if(buf[Length-1]=='\n') { buf[Length-1]='\r'; strcat(buf,"\n"); Length++; } else { strcat(buf,"\r\n"); Length+=2; } buf[Length+1] = '\0'; DbgPrint("\n BusLogic - Writing to the file"); DbgPrint("\n BusLogic - Buf = %s", buf); status = ZwWriteFile(FileHandle, NULL, NULL, NULL, &IoStatus, buf, Length, NULL, NULL ); ZwClose(FileHandle); } if (fileName.Buffer) ExFreePool (fileName.Buffer); return STATUS_SUCCESS; }
BOOLEAN AddKbLayoutsToRegistry( IN const MUI_LAYOUTS *MuiLayouts) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; HANDLE KeyHandle; HANDLE SubKeyHandle; NTSTATUS Status; ULONG Disposition; ULONG uIndex = 0; ULONG uCount = 0; WCHAR szKeyName[48] = L".DEFAULT\\Keyboard Layout"; WCHAR szValueName[3 + 1]; WCHAR szLangID[8 + 1]; // Open the keyboard layout key RtlInitUnicodeString(&KeyName, szKeyName); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&KeyHandle, KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); return FALSE; } NtClose(KeyHandle); KeyName.MaximumLength = sizeof(szKeyName); Status = RtlAppendUnicodeToString(&KeyName, L"\\Preload"); if (!NT_SUCCESS(Status)) { DPRINT1("RtlAppend failed! (%lx)\n", Status); DPRINT1("String is %wZ\n", &KeyName); return FALSE; } InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&KeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); return FALSE; } RtlInitUnicodeString(&KeyName, L".DEFAULT\\Keyboard Layout\\Substitutes"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&SubKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); NtClose(SubKeyHandle); NtClose(KeyHandle); return FALSE; } while (MuiLayouts[uIndex].LangID != NULL) { if (uIndex > 19) break; RtlStringCchPrintfW(szValueName, ARRAYSIZE(szValueName), L"%u", uIndex + 1); RtlInitUnicodeString(&ValueName, szValueName); RtlStringCchPrintfW(szLangID, ARRAYSIZE(szLangID), L"0000%s", MuiLayouts[uIndex].LangID); if (_wcsicmp(szLangID, MuiLayouts[uIndex].LayoutID) == 0) { Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, (PVOID)MuiLayouts[uIndex].LayoutID, (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex); NtClose(SubKeyHandle); NtClose(KeyHandle); return FALSE; } } else { RtlStringCchPrintfW(szLangID, ARRAYSIZE(szLangID), L"d%03lu%s", uCount, MuiLayouts[uIndex].LangID); Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, (PVOID)szLangID, (wcslen(szLangID)+1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex); NtClose(SubKeyHandle); NtClose(KeyHandle); return FALSE; } RtlInitUnicodeString(&ValueName, szLangID); Status = NtSetValueKey(SubKeyHandle, &ValueName, 0, REG_SZ, (PVOID)MuiLayouts[uIndex].LayoutID, (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status, uIndex); NtClose(SubKeyHandle); NtClose(KeyHandle); return FALSE; } uCount++; } uIndex++; } if (uIndex > 1) AddHotkeySettings(L"2", L"2", L"1"); else AddHotkeySettings(L"3", L"3", L"3"); NtClose(SubKeyHandle); NtClose(KeyHandle); return TRUE; }