BOOLEAN SampSetUpgradeFlag( ) /*++ Routine Description: This routine sets SAM upgrade flag is set. The upgrade flag is: HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\lsa UpgradeSam = REG_DWORD 1 and the value will be deleted. Arguments: Return Value: TRUE - The flag was set FALSE - The flag was not set or the value was not present --*/ { NTSTATUS NtStatus; UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE KeyHandle; UCHAR Buffer[100]; PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION) Buffer; ULONG KeyValueLength = 100; ULONG ResultLength; PULONG UpgradeFlag; // // Open the Lsa key in the registry // RtlInitUnicodeString( &KeyName, SAMP_LSA_KEY_NAME ); InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, 0, NULL ); NtStatus = NtOpenKey( &KeyHandle, KEY_SET_VALUE, &ObjectAttributes ); if (!NT_SUCCESS(NtStatus)) { return(FALSE); } // // Query the Notification Packages value // RtlInitUnicodeString( &KeyName, L"UpgradeSam" ); NtStatus = NtDeleteValueKey( KeyHandle, &KeyName ); NtClose(KeyHandle); }
_Use_decl_annotations_ NDIS_STATUS FilterAttach( NDIS_HANDLE NdisFilterHandle, NDIS_HANDLE FilterDriverContext, PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters ) /*++ Routine Description: Filter attach routine. Create filter's context, allocate NetBufferLists and NetBuffer pools and any other resources, and read configuration if needed. Arguments: NdisFilterHandle - Specify a handle identifying this instance of the filter. FilterAttach should save this handle. It is a required parameter in subsequent calls to NdisFxxx functions. FilterDriverContext - Filter driver context passed to NdisFRegisterFilterDriver. AttachParameters - attach parameters Return Value: NDIS_STATUS_SUCCESS: FilterAttach successfully allocated and initialize data structures for this filter instance. NDIS_STATUS_RESOURCES: FilterAttach failed due to insufficient resources. NDIS_STATUS_FAILURE: FilterAttach could not set up this instance of this filter and it has called NdisWriteErrorLogEntry with parameters specifying the reason for failure. N.B.: FILTER can use NdisRegisterDeviceEx to create a device, so the upper layer can send Irps to the filter. --*/ { PMS_FILTER pFilter = NULL; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; NTSTATUS NtStatus; NDIS_FILTER_ATTRIBUTES FilterAttributes; ULONG Size; COMPARTMENT_ID OriginalCompartmentID; OBJECT_ATTRIBUTES ObjectAttributes = {0}; const ULONG RegKeyOffset = ARRAYSIZE(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\otlwf\\Parameters\\NdisAdapters\\") - 1; DECLARE_CONST_UNICODE_STRING(RegKeyPath, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\otlwf\\Parameters\\NdisAdapters\\{00000000-0000-0000-0000-000000000000}"); RtlCopyMemory(RegKeyPath.Buffer + RegKeyOffset, AttachParameters->BaseMiniportName->Buffer + 8, sizeof(L"{00000000-0000-0000-0000-000000000000}")); LogFuncEntry(DRIVER_DEFAULT); do { ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject); if (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject) { Status = NDIS_STATUS_INVALID_PARAMETER; break; } // Verify the media type is supported. This is a last resort; the // the filter should never have been bound to an unsupported miniport // to begin with. if (AttachParameters->MiniportMediaType != NdisMediumIP) { LogError(DRIVER_DEFAULT, "Unsupported media type, 0x%x.", (ULONG)AttachParameters->MiniportMediaType); Status = NDIS_STATUS_INVALID_PARAMETER; break; } Size = sizeof(MS_FILTER) + AttachParameters->BaseMiniportInstanceName->Length; pFilter = (PMS_FILTER)FILTER_ALLOC_MEM(NdisFilterHandle, Size); if (pFilter == NULL) { LogWarning(DRIVER_DEFAULT, "Failed to allocate context structure, 0x%x bytes", Size); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pFilter, sizeof(MS_FILTER)); LogVerbose(DRIVER_DEFAULT, "Opening interface registry key %S", RegKeyPath.Buffer); InitializeObjectAttributes( &ObjectAttributes, (PUNICODE_STRING)&RegKeyPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); // Open the registry key NtStatus = ZwOpenKey(&pFilter->InterfaceRegKey, KEY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(NtStatus)) { LogError(DRIVER_DEFAULT, "ZwOpenKey failed to open %S, %!STATUS!", RegKeyPath.Buffer, NtStatus); Status = NDIS_STATUS_FAILURE; break; } // Format of "\DEVICE\{5BA90C49-0D7E-455B-8D3B-614F6714A212}" AttachParameters->BaseMiniportName->Buffer += 8; AttachParameters->BaseMiniportName->Length -= 8 * sizeof(WCHAR); NtStatus = RtlGUIDFromString(AttachParameters->BaseMiniportName, &pFilter->InterfaceGuid); AttachParameters->BaseMiniportName->Buffer -= 8; AttachParameters->BaseMiniportName->Length += 8 * sizeof(WCHAR); if (!NT_SUCCESS(NtStatus)) { LogError(DRIVER_DEFAULT, "Failed to convert FilterModuleGuidName to a GUID, %!STATUS!", NtStatus); Status = NDIS_STATUS_FAILURE; break; } pFilter->InterfaceFriendlyName.Length = pFilter->InterfaceFriendlyName.MaximumLength = AttachParameters->BaseMiniportInstanceName->Length; pFilter->InterfaceFriendlyName.Buffer = (PWSTR)((PUCHAR)pFilter + sizeof(MS_FILTER)); NdisMoveMemory(pFilter->InterfaceFriendlyName.Buffer, AttachParameters->BaseMiniportInstanceName->Buffer, pFilter->InterfaceFriendlyName.Length); pFilter->InterfaceIndex = AttachParameters->BaseMiniportIfIndex; pFilter->InterfaceLuid = AttachParameters->BaseMiniportNetLuid; pFilter->InterfaceCompartmentID = UNSPECIFIED_COMPARTMENT_ID; pFilter->FilterHandle = NdisFilterHandle; NdisZeroMemory(&FilterAttributes, sizeof(NDIS_FILTER_ATTRIBUTES)); FilterAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1; FilterAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES); FilterAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES; FilterAttributes.Flags = 0; NDIS_DECLARE_FILTER_MODULE_CONTEXT(MS_FILTER); Status = NdisFSetAttributes(NdisFilterHandle, pFilter, &FilterAttributes); if (Status != NDIS_STATUS_SUCCESS) { LogError(DRIVER_DEFAULT, "Failed to set attributes, %!NDIS_STATUS!", Status); break; } // Filter initially in Paused state pFilter->State = FilterPaused; // Initialize rundowns to disabled with no active references pFilter->ExternalRefs.Count = EX_RUNDOWN_ACTIVE; pFilter->cmdRundown.Count = EX_RUNDOWN_ACTIVE; // Query the compartment ID for this interface to use for the IP stack pFilter->InterfaceCompartmentID = GetInterfaceCompartmentID(&pFilter->InterfaceLuid); LogVerbose(DRIVER_DEFAULT, "Interface %!GUID! is in Compartment %u", &pFilter->InterfaceGuid, (ULONG)pFilter->InterfaceCompartmentID); // Make sure we are in the right compartment (VOID)otLwfSetCompartment(pFilter, &OriginalCompartmentID); // Register for address changed notifications NtStatus = NotifyUnicastIpAddressChange( AF_INET6, otLwfAddressChangeCallback, pFilter, FALSE, &pFilter->AddressChangeHandle ); // Revert the compartment, now that we have the table otLwfRevertCompartment(OriginalCompartmentID); if (!NT_SUCCESS(NtStatus)) { LogError(DRIVER_DEFAULT, "NotifyUnicastIpAddressChange failed, %!STATUS!", NtStatus); Status = NDIS_STATUS_FAILURE; break; } // Add Filter to global list of Thread Filters NdisAcquireSpinLock(&FilterListLock); InsertTailList(&FilterModuleList, &pFilter->FilterModuleLink); NdisReleaseSpinLock(&FilterListLock); LogVerbose(DRIVER_DEFAULT, "Created Filter: %p", pFilter); } while (FALSE); // Clean up on failure if (Status != NDIS_STATUS_SUCCESS) { if (pFilter != NULL) { if (pFilter->AddressChangeHandle != NULL) { CancelMibChangeNotify2(pFilter->AddressChangeHandle); pFilter->AddressChangeHandle = NULL; } NdisFreeMemory(pFilter, 0, 0); } } LogFuncExitNDIS(DRIVER_DEFAULT, Status); return Status; }
/* * 函数说明: * 初始化通讯 * * 参数: * pFlt * * 返回值: * TRUE 成功 * FALSE 失败 * * 备注: * */ BOOLEAN CComm::Init( __in PFLT_FILTER pFlt ) { BOOLEAN bRet = FALSE; CKrnlStr PortName; NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; PSECURITY_DESCRIPTOR pSd = NULL; OBJECT_ATTRIBUTES Ob = {0}; CLog Log; KdPrintKrnl(LOG_PRINTF_LEVEL_INFO, LOG_RECORED_LEVEL_NEED, L"begin"); __try { if (!pFlt) { KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"input argument error"); __leave; } if (CMinifilter::ms_pMfIns->CheckEnv(MINIFILTER_ENV_TYPE_FLT_FILTER) && ms_CommInfo.pSeverPort) { KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"already init"); __leave; } if (!PortName.Set(g_lpCommPortName, wcslen(g_lpCommPortName))) { KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"PortName.Set failed"); __leave; } ntStatus = FltBuildDefaultSecurityDescriptor(&pSd, FLT_PORT_ALL_ACCESS); if (!NT_SUCCESS(ntStatus)) { KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"FltBuildDefaultSecurityDescriptor failed. (%x)", ntStatus); __leave; } InitializeObjectAttributes( &Ob, PortName.Get(), OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, pSd ); ntStatus = FltCreateCommunicationPort( pFlt, &ms_CommInfo.pSeverPort, &Ob, NULL, (PFLT_CONNECT_NOTIFY)CommKmConnectNotify, (PFLT_DISCONNECT_NOTIFY)CommKmDisconnectNotify, (PFLT_MESSAGE_NOTIFY)CommKmMessageNotify, 1 ); if (!NT_SUCCESS(ntStatus)) { KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"FltCreateCommunicationPort failed. (%x)", ntStatus); __leave; } bRet = TRUE; } __finally { if (pSd) { FltFreeSecurityDescriptor(pSd); pSd = NULL; } if (!bRet) { if (ms_CommInfo.pSeverPort) { FltCloseCommunicationPort(ms_CommInfo.pSeverPort); ms_CommInfo.pSeverPort = NULL; } } } KdPrintKrnl(LOG_PRINTF_LEVEL_INFO, LOG_RECORED_LEVEL_NEED, L"end"); return bRet; }
BOOLEAN ProcessLocaleRegistry(PGENERIC_LIST List) { PGENERIC_LIST_ENTRY Entry; PWCHAR LanguageId; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; HANDLE KeyHandle; NTSTATUS Status; Entry = GetCurrentListEntry(List); if (Entry == NULL) return FALSE; LanguageId = (PWCHAR)GetListEntryUserData(Entry); if (LanguageId == NULL) return FALSE; /* Skip first 4 zeroes */ if (wcslen(LanguageId) >= 4) LanguageId += 4; /* Open the NLS language key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&KeyHandle, KEY_SET_VALUE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); return FALSE; } /* Set default language */ RtlInitUnicodeString(&ValueName, L"Default"); Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, (PVOID)LanguageId, (wcslen(LanguageId) + 1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); NtClose(KeyHandle); return FALSE; } /* Set install language */ RtlInitUnicodeString(&ValueName, L"InstallLanguage"); Status = NtSetValueKey (KeyHandle, &ValueName, 0, REG_SZ, (PVOID)LanguageId, (wcslen(LanguageId) + 1) * sizeof(WCHAR)); NtClose(KeyHandle); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); return FALSE; } return TRUE; }
BOOLEAN obtest( void ) { ULONG i; HANDLE Handles[ 2 ]; NTSTATUS Status; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectTypeAName, "ObjectTypeA" ); RtlInitString( &ObjectTypeBName, "ObjectTypeB" ); RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); ObjectTypeInitializer.ValidAccessMask = -1; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.MaintainHandleCount = TRUE; ObjectTypeInitializer.DumpProcedure = DumpAProc; ObjectTypeInitializer.OpenProcedure = OpenAProc; ObjectTypeInitializer.CloseProcedure = CloseAProc; ObjectTypeInitializer.DeleteProcedure = DeleteAProc; ObjectTypeInitializer.ParseProcedure = ParseAProc; ObCreateObjectType( &ObjectTypeAName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObjectTypeA ); ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.MaintainHandleCount = FALSE; ObjectTypeInitializer.GenericMapping = MyGenericMapping; ObjectTypeInitializer.DumpProcedure = DumpBProc; ObjectTypeInitializer.OpenProcedure = NULL; ObjectTypeInitializer.CloseProcedure = NULL; ObjectTypeInitializer.DeleteProcedure = DeleteBProc; ObjectTypeInitializer.ParseProcedure = NULL; ObCreateObjectType( &ObjectTypeBName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObjectTypeB ); ObpDumpTypes( NULL ); RtlInitString( &DirectoryName, "\\MyObjects" ); InitializeObjectAttributes( &DirectoryObjA, &DirectoryName, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, NULL ); NtCreateDirectoryObject( &DirectoryHandle, 0, &DirectoryObjA ); NtClose( DirectoryHandle ); RtlInitString( &ObjectAName, "\\myobjects\\ObjectA" ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAName, OBJ_CASE_INSENSITIVE, NULL, NULL ); RtlInitString( &ObjectBName, "\\myobjects\\ObjectB" ); InitializeObjectAttributes( &ObjectBObjA, &ObjectBName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = ObCreateObject( KernelMode, ObjectTypeA, &ObjectAObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEA ), 0L, 0L, (PVOID *)&ObjectBodyA ); ObjectA = (POBJECTTYPEA)ObjectBodyA; ObjectA->TypeALength = sizeof( *ObjectA ); for (i=0; i<4; i++) { ObjectA->Stuff[i] = i+1; } KeInitializeEvent( &ObjectA->Event, NotificationEvent, TRUE ); Status = ObCreateObject( KernelMode, ObjectTypeB, &ObjectBObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEB ), 0L, 0L, (PVOID *)&ObjectBodyB ); ObjectB = (POBJECTTYPEB)ObjectBodyB; ObjectB->TypeBLength = sizeof( *ObjectB ); for (i=0; i<16; i++) { ObjectB->Stuff[i] = i+1; } KeInitializeSemaphore ( &ObjectB->Semaphore, 2L, 2L ); Status = ObInsertObject( ObjectBodyA, SYNCHRONIZE | 0x3, NULL, 1, &ObjectBodyA, &ObjectHandleA1 ); DbgPrint( "Status: %lx ObjectBodyA: %lx ObjectHandleA1: %lx\n", Status, ObjectBodyA, ObjectHandleA1 ); Status = ObInsertObject( ObjectBodyB, SYNCHRONIZE | 0x1, NULL, 1, &ObjectBodyB, &ObjectHandleB1 ); DbgPrint( "Status: %lx ObjectBodyB: %lx ObjectHandleB1: %lx\n", Status, ObjectBodyB, ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectAName, "\\MyObjects\\ObjectA" ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAName, OBJ_OPENIF, NULL, NULL ); Status = ObCreateObject( KernelMode, ObjectTypeA, &ObjectAObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEA ), 0L, 0L, (PVOID *)&ObjectBodyA1 ); Status = ObInsertObject( ObjectBodyA1, SYNCHRONIZE | 0x3, NULL, 1, &ObjectBodyA2, &ObjectHandleA2 ); DbgPrint( "Status: %lx ObjectBodyA1: %lx ObjectBodyA2: %lx ObjectHandleA2: %lx\n", Status, ObjectBodyA1, ObjectBodyA2, ObjectHandleA2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); NtClose( ObjectHandleA2 ); ObDereferenceObject( ObjectBodyA2 ); // ObInsertObject,ObjectPointerBias NtWaitForSingleObject( ObjectHandleB1, TRUE, NULL ); Handles[ 0 ] = ObjectHandleA1; Handles[ 1 ] = ObjectHandleB1; NtWaitForMultipleObjects( 2, Handles, WaitAny, TRUE, NULL ); ObReferenceObjectByHandle( ObjectHandleA1, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB1, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByPointer( ObjectBodyA, 0L, ObjectTypeA, KernelMode ); ObReferenceObjectByPointer( ObjectBodyB, 0L, ObjectTypeB, KernelMode ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectAPathName, "\\MyObjects\\ObjectA" ); RtlInitString( &ObjectBPathName, "\\MyObjects\\ObjectB" ); ObReferenceObjectByName( &ObjectAPathName, OBJ_CASE_INSENSITIVE, 0L, ObjectTypeA, KernelMode, NULL, &ObjectBodyA ); ObReferenceObjectByName( &ObjectBPathName, OBJ_CASE_INSENSITIVE, 0L, ObjectTypeB, KernelMode, NULL, &ObjectBodyB ); DbgPrint( "Reference Name %s = %lx\n", ObjectAPathName.Buffer, ObjectBodyA ); DbgPrint( "Reference Name %s = %lx\n", ObjectBPathName.Buffer, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObDereferenceObject( ObjectBodyA ); // ObInsertObject,ObjectPointerBias ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByPointer ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByName ObDereferenceObject( ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAPathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObOpenObjectByName( &ObjectAObjA, 0L, NULL, ObjectTypeA, KernelMode, NULL, &ObjectHandleA2 ); InitializeObjectAttributes( &ObjectBObjA, &ObjectBPathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObOpenObjectByName( &ObjectBObjA, 0L, NULL, ObjectTypeB, KernelMode, NULL, &ObjectHandleB2 ); DbgPrint( "Open Object Name %s = %lx\n", ObjectAPathName.Buffer, ObjectHandleA2 ); DbgPrint( "Open Object Name %s = %lx\n", ObjectBPathName.Buffer, ObjectHandleB2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); NtClose( ObjectHandleA1 ); NtClose( ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByHandle( ObjectHandleA2, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB2, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA2, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB2, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObOpenObjectByPointer( ObjectBodyA, OBJ_CASE_INSENSITIVE, 0L, NULL, ObjectTypeA, KernelMode, &ObjectHandleA1 ); ObOpenObjectByPointer( ObjectBodyB, OBJ_CASE_INSENSITIVE, 0L, NULL, ObjectTypeB, KernelMode, &ObjectHandleB1 ); DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyA, ObjectHandleA1 ); DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyB, ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByHandle( ObjectHandleA1, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB1, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); NtClose( ObjectHandleA1 ); NtClose( ObjectHandleB1 ); NtClose( ObjectHandleA2 ); NtClose( ObjectHandleB2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); TestFunction = NULL; return( TRUE ); }
/* * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ** * * * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ** */ NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath ) { NTSTATUS Status; PSECURITY_DESCRIPTOR SecurityDescriptor; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING uPortName; // Open the registry and read in all the setting we will use in kernel mode EnumerateRegistryValues( theRegistryPath ); // DDK : "...Add itself to the global list of registered minifilters and to provide // the Filter Manager with a list of callback functions and other information // about the minifilter." Status = FltRegisterFilter( theDriverObject, &cfsd_FilterRegistration, &gFilterPointer ); if ( NT_SUCCESS( Status ) ) { #if ENABLE_USER_INTERFACE Status = FltBuildDefaultSecurityDescriptor( &SecurityDescriptor, FLT_PORT_ALL_ACCESS ); if ( NT_SUCCESS( Status ) ) { RtlInitUnicodeString( &uPortName, USER_COMMUNICATION_PORT_NAME ); InitializeObjectAttributes( &ObjectAttributes, &uPortName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, SecurityDescriptor ); Status = FltCreateCommunicationPort( gFilterPointer, // Filter &gUserModeConnection.ServerPort,// *ServerPort &ObjectAttributes, // ObjectAttributes NULL, // ServerPortCookie cfsd_UserModeConnect, // ConnectNotifyCallback cfsd_UserModeDisconnect, // DisconnectNotifyCallback cfsd_UserModeCommunication, // MessageNotifyCallback 1 ); // MaxConnections FltFreeSecurityDescriptor( SecurityDescriptor ); // If we failed to create a communications port then we are going to fail the driver if ( !NT_SUCCESS( Status ) ) { KdPrint( (PRINT_TAG "Failed FltCreateCommunicationPort() with NTSTATUS 0x%x\n",Status ) ); // Release our hidden data memory ExFreePoolWithTag( gFileData, 'parC' ); return Status; } DBG_PRINT( DbgOutput, DBG_USERMODE, (PRINT_TAG_USERMODE "Created communication server port 0x%X for usermode access\n", gUserModeConnection.ServerPort )); } #endif // End #if ENABLE_USER_INTERFACE // DDK : "...Notifies the Filter Manager that the minifilter is ready to // begin attaching to volumes and filtering I/O requests" Status = FltStartFiltering( gFilterPointer ); if ( !NT_SUCCESS( Status )) { #if ENABLE_USER_INTERFACE FltCloseCommunicationPort( gUserModeConnection.ServerPort ); #endif // End #if ENABLE_USER_INTERFACE // If we failed FltStartFiltering() then we unregister ourself with the Filter Manager // so that we no longer recieve calls to process I/O operations. FltUnregisterFilter( gFilterPointer ); // Release our hidden data memory ExFreePoolWithTag( gFileData, 'parC' ); } } return Status; }
static BOOLEAN IsAcpiComputer(VOID) { UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"); UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); UNICODE_STRING AcpiBiosIdentifier = RTL_CONSTANT_STRING(L"ACPI BIOS"); OBJECT_ATTRIBUTES ObjectAttributes; PKEY_BASIC_INFORMATION pDeviceInformation = NULL; ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR); PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL; ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR); ULONG RequiredSize; ULONG IndexDevice = 0; UNICODE_STRING DeviceName, ValueName; HANDLE hDevicesKey = NULL; HANDLE hDeviceKey = NULL; NTSTATUS Status; BOOLEAN ret = FALSE; InitializeObjectAttributes(&ObjectAttributes, &MultiKeyPathU, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&hDevicesKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status); goto cleanup; } pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength); if (!pDeviceInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength); if (!pDeviceInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } while (TRUE) { Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); if (Status == STATUS_NO_MORE_ENTRIES) break; else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) { RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation); DeviceInfoLength = RequiredSize; pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength); if (!pDeviceInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); } if (!NT_SUCCESS(Status)) { DPRINT("NtEnumerateKey() failed with status 0x%08lx\n", Status); goto cleanup; } IndexDevice++; /* Open device key */ DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength; DeviceName.Buffer = pDeviceInformation->Name; InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_CASE_INSENSITIVE, hDevicesKey, NULL); Status = NtOpenKey( &hDeviceKey, KEY_QUERY_VALUE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status); goto cleanup; } /* Read identifier */ Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) { RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation); ValueInfoLength = RequiredSize; pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength); if (!pValueInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); } if (!NT_SUCCESS(Status)) { DPRINT("NtQueryValueKey() failed with status 0x%08lx\n", Status); goto nextdevice; } else if (pValueInformation->Type != REG_SZ) { DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ); goto nextdevice; } ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength; ValueName.Buffer = (PWCHAR)pValueInformation->Data; if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) ValueName.Length -= sizeof(WCHAR); if (RtlCompareUnicodeString(&ValueName, &AcpiBiosIdentifier, FALSE) == 0) { DPRINT("Found ACPI BIOS\n"); ret = TRUE; goto cleanup; } nextdevice: NtClose(hDeviceKey); hDeviceKey = NULL; } cleanup: if (pDeviceInformation) RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation); if (pValueInformation) RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation); if (hDevicesKey) NtClose(hDevicesKey); if (hDeviceKey) NtClose(hDeviceKey); return ret; }
int __cdecl main(int argc, char *argv[]) { static PH_COMMAND_LINE_OPTION options[] = { { FI_ARG_HELP, L"h", NoArgumentType }, { FI_ARG_ACTION, L"a", MandatoryArgumentType }, { FI_ARG_NATIVE, L"N", NoArgumentType }, { FI_ARG_PATTERN, L"p", MandatoryArgumentType }, { FI_ARG_CASESENSITIVE, L"C", NoArgumentType }, { FI_ARG_OUTPUT, L"o", MandatoryArgumentType }, { FI_ARG_FORCE, L"f", NoArgumentType }, { FI_ARG_LENGTH, L"L", MandatoryArgumentType } }; PH_STRINGREF commandLine; NTSTATUS status = STATUS_SUCCESS; if (!NT_SUCCESS(PhInitializePhLibEx(0, 0, 0))) return 1; PhUnicodeStringToStringRef(&NtCurrentPeb()->ProcessParameters->CommandLine, &commandLine); if (!PhParseCommandLine( &commandLine, options, sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION), PH_COMMAND_LINE_IGNORE_FIRST_PART, FiCommandLineCallback, NULL ) || FiArgHelp) { FiPrintHelp(); return 0; } if (!FiArgFileName && ( FiArgAction && PhEqualString2(FiArgAction, L"dir", TRUE) )) { FiArgFileName = PhCreateStringFromUnicodeString(&NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath); } if (!FiArgAction) { FiPrintHelp(); return 1; } else if (PhEqualString2(FiArgAction, L"map", TRUE)) { WCHAR deviceNameBuffer[7] = L"\\??\\ :"; ULONG i; WCHAR targetNameBuffer[0x100]; UNICODE_STRING targetName; targetName.Buffer = targetNameBuffer; targetName.MaximumLength = sizeof(targetNameBuffer); for (i = 0; i < 26; i++) { HANDLE linkHandle; OBJECT_ATTRIBUTES oa; UNICODE_STRING deviceName; deviceNameBuffer[4] = (WCHAR)('A' + i); deviceName.Buffer = deviceNameBuffer; deviceName.Length = 6 * sizeof(WCHAR); InitializeObjectAttributes( &oa, &deviceName, OBJ_CASE_INSENSITIVE, NULL, NULL ); if (NT_SUCCESS(NtOpenSymbolicLinkObject( &linkHandle, SYMBOLIC_LINK_QUERY, &oa ))) { if (NT_SUCCESS(NtQuerySymbolicLinkObject( linkHandle, &targetName, NULL ))) { wprintf(L"%c: %.*s\n", 'A' + i, targetName.Length / 2, targetName.Buffer); } NtClose(linkHandle); } } } else if (!FiArgFileName) { wprintf(L"Error: file name missing.\n"); FiPrintHelp(); return 1; } else if (PhEqualString2(FiArgAction, L"hash", TRUE)) { HANDLE fileHandle; LARGE_INTEGER fileSize; IO_STATUS_BLOCK isb; ULONG mode; if (!FiArgOutput) mode = HASH_MD5; else if (PhEqualString2(FiArgOutput, L"md5", TRUE)) mode = HASH_MD5; else if (PhEqualString2(FiArgOutput, L"sha1", TRUE)) mode = HASH_SHA1; else if (PhEqualString2(FiArgOutput, L"crc32", TRUE)) mode = HASH_CRC32; else { wprintf(L"Invalid hash algorithm. Possibilities: md5, sha1, crc32\n"); return 1; } if (FiCreateFile( &fileHandle, FILE_GENERIC_READ, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY )) { if (NT_SUCCESS(status = PhGetFileSize(fileHandle, &fileSize))) { MD5_CTX md5Context; A_SHA_CTX shaContext; ULONG crc; UCHAR buffer[PAGE_SIZE * 4]; ULONG64 bytesRemaining; bytesRemaining = fileSize.QuadPart; switch (mode) { case HASH_MD5: MD5Init(&md5Context); break; case HASH_SHA1: A_SHAInit(&shaContext); break; case HASH_CRC32: crc = 0; break; } while (bytesRemaining) { status = NtReadFile( fileHandle, NULL, NULL, NULL, &isb, buffer, sizeof(buffer), NULL, NULL ); if (!NT_SUCCESS(status)) break; switch (mode) { case HASH_MD5: MD5Update(&md5Context, buffer, (ULONG)isb.Information); break; case HASH_SHA1: A_SHAUpdate(&shaContext, buffer, (ULONG)isb.Information); break; case HASH_CRC32: crc = PhCrc32(crc, buffer, isb.Information); break; } bytesRemaining -= (ULONG)isb.Information; } if (status == STATUS_END_OF_FILE) status = STATUS_SUCCESS; switch (mode) { case HASH_MD5: { MD5Final(&md5Context); wprintf(L"%s", PhBufferToHexString(md5Context.digest, 16)->Buffer); } break; case HASH_SHA1: { UCHAR hash[20]; A_SHAFinal(&shaContext, hash); wprintf(L"%s", PhBufferToHexString(hash, 20)->Buffer); } break; case HASH_CRC32: { wprintf(L"%08x", crc); } break; } if (!NT_SUCCESS(status)) wprintf(L"Warning: I/O error encountered: %s\n", PhGetNtMessage(status)->Buffer); } NtClose(fileHandle); } if (!NT_SUCCESS(status)) { wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer); return 1; } } else if (PhEqualString2(FiArgAction, L"execute", TRUE)) { if (FiArgNative) { if (!NT_SUCCESS(status = PhCreateProcess( FiFormatFileName(FiArgFileName)->Buffer, FiArgOutput ? &FiArgOutput->sr : NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL ))) { wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer); return 1; } } else { if (!NT_SUCCESS(status = PhCreateProcessWin32( FiArgFileName->Buffer, PhGetString(FiArgOutput), NULL, NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath.Buffer, PH_CREATE_PROCESS_NEW_CONSOLE, NULL, NULL, NULL ))) { wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer); return 1; } } } else if (PhEqualString2(FiArgAction, L"del", TRUE)) { HANDLE fileHandle; if (FiCreateFile( &fileHandle, DELETE | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT )) { FILE_DISPOSITION_INFORMATION dispositionInfo; IO_STATUS_BLOCK isb; dispositionInfo.DeleteFile = TRUE; if (!NT_SUCCESS(status = NtSetInformationFile(fileHandle, &isb, &dispositionInfo, sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation))) { wprintf(L"Error deleting file: %s\n", PhGetNtMessage(status)->Buffer); } NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"touch", TRUE)) { HANDLE fileHandle; if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"mkdir", TRUE)) { HANDLE fileHandle; if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FiArgFileName, FILE_ATTRIBUTE_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"rename", TRUE)) { HANDLE fileHandle; PPH_STRING newFileName; if (!FiArgOutput) { wprintf(L"Error: new file name missing.\n"); FiPrintHelp(); return 1; } newFileName = FiFormatFileName(FiArgOutput); if (FiCreateFile( &fileHandle, DELETE | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { PFILE_RENAME_INFORMATION renameInfo; ULONG renameInfoSize; IO_STATUS_BLOCK isb; renameInfoSize = FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName) + (ULONG)newFileName->Length; renameInfo = PhAllocate(renameInfoSize); renameInfo->ReplaceIfExists = FiArgForce; renameInfo->RootDirectory = NULL; renameInfo->FileNameLength = (ULONG)newFileName->Length; memcpy(renameInfo->FileName, newFileName->Buffer, newFileName->Length); status = NtSetInformationFile(fileHandle, &isb, renameInfo, renameInfoSize, FileRenameInformation); PhFree(renameInfo); if (!NT_SUCCESS(status)) { wprintf(L"Error renaming file: %s\n", PhGetNtMessage(status)->Buffer); } NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"copy", TRUE)) { HANDLE fileHandle; HANDLE outFileHandle; LARGE_INTEGER fileSize; FILE_BASIC_INFORMATION basicInfo; if (!FiArgOutput) { wprintf(L"Error: output file name missing.\n"); FiPrintHelp(); return 1; } if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | FILE_READ_DATA | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT ) && FiCreateFile( &outFileHandle, FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA | SYNCHRONIZE, FiArgOutput, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, !FiArgForce ? FILE_CREATE : FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT )) { #define COPY_BUFFER_SIZE 0x10000 IO_STATUS_BLOCK isb; PVOID buffer; ULONG64 bytesToCopy = FiArgLength; if (NT_SUCCESS(PhGetFileSize(fileHandle, &fileSize))) { PhSetFileSize(outFileHandle, &fileSize); } buffer = PhAllocatePage(COPY_BUFFER_SIZE, NULL); if (!buffer) { wprintf(L"Error allocating buffer.\n"); return 1; } while (bytesToCopy) { status = NtReadFile( fileHandle, NULL, NULL, NULL, &isb, buffer, bytesToCopy >= COPY_BUFFER_SIZE ? COPY_BUFFER_SIZE : (ULONG)bytesToCopy, NULL, NULL ); if (status == STATUS_END_OF_FILE) { break; } else if (!NT_SUCCESS(status)) { wprintf(L"Error reading from file: %s\n", PhGetNtMessage(status)->Buffer); break; } status = NtWriteFile( outFileHandle, NULL, NULL, NULL, &isb, buffer, (ULONG)isb.Information, // number of bytes read NULL, NULL ); if (!NT_SUCCESS(status)) { wprintf(L"Error writing to output file: %s\n", PhGetNtMessage(status)->Buffer); break; } bytesToCopy -= (ULONG)isb.Information; } PhFreePage(buffer); // Copy basic attributes over. if (NT_SUCCESS(NtQueryInformationFile( fileHandle, &isb, &basicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation ))) { NtSetInformationFile( outFileHandle, &isb, &basicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation ); } NtClose(fileHandle); NtClose(outFileHandle); } } else if (PhEqualString2(FiArgAction, L"dir", TRUE)) { HANDLE fileHandle; UNICODE_STRING pattern; PPH_STRING totalSize, totalAllocSize; if (FiCreateFile( &fileHandle, FILE_LIST_DIRECTORY | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { FipDirFileCount = 0; FipDirDirCount = 0; FipDirTotalSize = 0; FipDirTotalAllocSize = 0; if (FiArgPattern) PhStringRefToUnicodeString(&FiArgPattern->sr, &pattern); PhEnumDirectoryFile( fileHandle, FiArgPattern ? &pattern : NULL, FipEnumDirectoryFileForDir, NULL ); NtClose(fileHandle); totalSize = PhFormatUInt64(FipDirTotalSize, TRUE); totalAllocSize = PhFormatUInt64(FipDirTotalAllocSize, TRUE); wprintf( L"%12I64u file(s) %11s bytes\n" L"%12I64u dir(s) %11s bytes allocated\n", FipDirFileCount, totalSize->Buffer, FipDirDirCount, totalAllocSize->Buffer ); PhDereferenceObject(totalSize); PhDereferenceObject(totalAllocSize); } } else if (PhEqualString2(FiArgAction, L"streams", TRUE)) { HANDLE fileHandle; PVOID streams; PFILE_STREAM_INFORMATION stream; if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { if (NT_SUCCESS(PhEnumFileStreams(fileHandle, &streams))) { stream = PH_FIRST_STREAM(streams); while (stream) { PPH_STRING size, allocationSize; size = PhFormatUInt64(stream->StreamSize.QuadPart, TRUE); allocationSize = PhFormatUInt64(stream->StreamAllocationSize.QuadPart, TRUE); wprintf( L"%11s %11s %.*s\n", size->Buffer, allocationSize->Buffer, stream->StreamNameLength / 2, stream->StreamName ); PhDereferenceObject(size); PhDereferenceObject(allocationSize); stream = PH_NEXT_STREAM(stream); } } NtClose(fileHandle); } } else { wprintf(L"Error: invalid action \"%s\".\n", FiArgAction->Buffer); FiPrintHelp(); return 1; } }
//@@@@@@@@@@@@@@@@@@@@@@@@ // IRQL = passive level //@@@@@@@@@@@@@@@@@@@@@@@@@ extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS Status = {0}; DbgPrint("Keyboard Filter Driver - DriverEntry\nCompiled at " __TIME__ " on " __DATE__ "\n"); ///////////////////////////////////////////////////////////////////////////////////////// // Fill in IRP dispatch table in the DriverObject to handle I/O Request Packets (IRPs) ///////////////////////////////////////////////////////////////////////////////////////// // For a filter driver, we want pass down ALL IRP_MJ_XX requests to the driver which // we are hooking except for those we are interested in modifying. for(int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) pDriverObject->MajorFunction[i] = DispatchPassDown; DbgPrint("Filled dispatch table with generic pass down routine...\n"); //Explicitly fill in the IRP's we want to hook pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead; //Go ahead and hook the keyboard now HookKeyboard(pDriverObject); DbgPrint("Hooked IRP_MJ_READ routine...\n"); //Set up our worker thread to handle file writes of the scan codes extracted from the //read IRPs InitThreadKeyLogger(pDriverObject); //Initialize the linked list that will serve as a queue to hold the captured keyboard scan codes PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension; InitializeListHead(&pKeyboardDeviceExtension->QueueListHead); //Initialize the lock for the linked list queue KeInitializeSpinLock(&pKeyboardDeviceExtension->lockQueue); //Initialize the work queue semaphore KeInitializeSemaphore(&pKeyboardDeviceExtension->semQueue, 0 , MAXLONG); //Create the log file IO_STATUS_BLOCK file_status; OBJECT_ATTRIBUTES obj_attrib; CCHAR ntNameFile[64] = "\\DosDevices\\c:\\klog.txt"; STRING ntNameString; UNICODE_STRING uFileName; RtlInitAnsiString( &ntNameString, ntNameFile); RtlAnsiStringToUnicodeString(&uFileName, &ntNameString, TRUE ); InitializeObjectAttributes(&obj_attrib, &uFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwCreateFile(&pKeyboardDeviceExtension->hLogFile,GENERIC_WRITE,&obj_attrib,&file_status, NULL,FILE_ATTRIBUTE_NORMAL,0,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0); RtlFreeUnicodeString(&uFileName); if (Status != STATUS_SUCCESS) { DbgPrint("Failed to create log file...\n"); DbgPrint("File Status = %x\n",file_status); } else { DbgPrint("Successfully created log file...\n"); DbgPrint("File Handle = %x\n",pKeyboardDeviceExtension->hLogFile); } // Set the DriverUnload procedure pDriverObject->DriverUnload = Unload; DbgPrint("Set DriverUnload function pointer...\n"); DbgPrint("Exiting Driver Entry......\n"); return STATUS_SUCCESS; }
NTSTATUS LpxTdiOpenConnection ( OUT PHANDLE ConnectionFileHandle, OUT PFILE_OBJECT *ConnectionFileObject, IN PVOID ConnectionContext ) { HANDLE connectionFileHandle; PFILE_OBJECT connectionFileObject; UNICODE_STRING nameString; OBJECT_ATTRIBUTES objectAttributes; UCHAR eaFullBuffer[CONNECTION_EA_BUFFER_LENGTH]; PFILE_FULL_EA_INFORMATION eaBuffer = (PFILE_FULL_EA_INFORMATION)eaFullBuffer; INT i; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; LtDebugPrint (3, ("[LpxTdi] LpxTdiOpenConnection: Entered\n")); // // Init object attributes // RtlInitUnicodeString (&nameString, TRANSPORT_NAME); InitializeObjectAttributes ( &objectAttributes, &nameString, 0, NULL, NULL ); RtlZeroMemory(eaBuffer, CONNECTION_EA_BUFFER_LENGTH); eaBuffer->NextEntryOffset = 0; eaBuffer->Flags = 0; eaBuffer->EaNameLength = TDI_CONNECTION_CONTEXT_LENGTH; eaBuffer->EaValueLength = sizeof (PVOID); for (i=0;i<(int)eaBuffer->EaNameLength;i++) { eaBuffer->EaName[i] = TdiConnectionContext[i]; } RtlMoveMemory ( &eaBuffer->EaName[TDI_CONNECTION_CONTEXT_LENGTH+1], &ConnectionContext, sizeof (PVOID) ); status = ZwCreateFile( &connectionFileHandle, GENERIC_READ, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, 0, 0, eaBuffer, CONNECTION_EA_BUFFER_LENGTH ); if (!NT_SUCCESS(status)) { LtDebugPrint (0, ("[LpxTdi] TdiOpenConnection: FAILURE, NtCreateFile returned status code=%x\n", status)); *ConnectionFileHandle = NULL; *ConnectionFileObject = NULL; return status; } status = ioStatusBlock.Status; if (!NT_SUCCESS(status)) { LtDebugPrint (0, ("[LpxTdi] TdiOpenConnection: FAILURE, IoStatusBlock.Status contains status code=%x\n", status)); *ConnectionFileHandle = NULL; *ConnectionFileObject = NULL; return status; } status = ObReferenceObjectByHandle ( connectionFileHandle, 0L, NULL, KernelMode, (PVOID *) &connectionFileObject, NULL ); if (!NT_SUCCESS(status)) { LtDebugPrint(0, ("[LpxTdi] TdiOpenConnection: ObReferenceObjectByHandle() FAILED %x\n", status)); ZwClose(connectionFileHandle); *ConnectionFileHandle = NULL; *ConnectionFileObject = NULL; return status; } *ConnectionFileHandle = connectionFileHandle; *ConnectionFileObject = connectionFileObject; LtDebugPrint (3, ("[LpxTdi] LpxOpenConnection: returning\n")); return status; } /* LpxOpenConnection */
BOOLEAN FiCreateFile( _Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ PPH_STRING FileName, _In_opt_ ULONG FileAttributes, _In_ ULONG ShareAccess, _In_ ULONG CreateDisposition, _In_opt_ ULONG Options ) { NTSTATUS status; HANDLE fileHandle; OBJECT_ATTRIBUTES oa; IO_STATUS_BLOCK isb; PPH_STRING fileName; UNICODE_STRING fileNameUs; if (!FileAttributes) FileAttributes = FILE_ATTRIBUTE_NORMAL; if (!Options) Options = FILE_SYNCHRONOUS_IO_NONALERT; // Not needed, because we handle Win32 paths anyway. //if (!(FiArgNative)) //{ // status = PhCreateFileWin32( // FileHandle, // FileName->Buffer, // DesiredAccess, // FileAttributes, // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, // CreateDisposition, // Options // ); // if (!NT_SUCCESS(status)) // { // wprintf(L"Error creating/opening file: %s\n", PhGetNtMessage(status)->Buffer); // return FALSE; // } // return TRUE; //} fileName = FiFormatFileName(FileName); if (!PhStringRefToUnicodeString(&fileName->sr, &fileNameUs)) { PhDereferenceObject(fileName); return FALSE; } InitializeObjectAttributes( &oa, &fileNameUs, (!FiArgCaseSensitive ? OBJ_CASE_INSENSITIVE : 0), NULL, NULL ); status = NtCreateFile( &fileHandle, DesiredAccess, &oa, &isb, NULL, FileAttributes, ShareAccess, CreateDisposition, Options, NULL, 0 ); if (!NT_SUCCESS(status)) { wprintf(L"Error creating/opening file: %s\n", PhGetNtMessage(status)->Buffer); return FALSE; } *FileHandle = fileHandle; return TRUE; }
NTSTATUS LpxTdiOpenAddress( OUT PHANDLE AddressFileHandle, OUT PFILE_OBJECT *AddressFileObject, IN PTDI_ADDRESS_LPX Address ) { HANDLE addressFileHandle; PFILE_OBJECT addressFileObject; UNICODE_STRING nameString; OBJECT_ATTRIBUTES objectAttributes; UCHAR eaFullBuffer[ADDRESS_EA_BUFFER_LENGTH]; PFILE_FULL_EA_INFORMATION eaBuffer = (PFILE_FULL_EA_INFORMATION)eaFullBuffer; PTRANSPORT_ADDRESS transportAddress; PTA_ADDRESS taAddress; PTDI_ADDRESS_LPX lpxAddress; INT i; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; LtDebugPrint (3, ("[LpxTdi] TdiOpenAddress: Entered\n")); // // Init object attributes // RtlInitUnicodeString (&nameString, TRANSPORT_NAME); InitializeObjectAttributes ( &objectAttributes, &nameString, 0, NULL, NULL ); RtlZeroMemory(eaBuffer, ADDRESS_EA_BUFFER_LENGTH); eaBuffer->NextEntryOffset = 0; eaBuffer->Flags = 0; eaBuffer->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH; eaBuffer->EaValueLength = FIELD_OFFSET(TRANSPORT_ADDRESS, Address) + FIELD_OFFSET(TA_ADDRESS, Address) + TDI_ADDRESS_LENGTH_LPX; for (i=0;i<(int)eaBuffer->EaNameLength;i++) { eaBuffer->EaName[i] = TdiTransportAddress[i]; } transportAddress = (PTRANSPORT_ADDRESS)&eaBuffer->EaName[eaBuffer->EaNameLength+1]; transportAddress->TAAddressCount = 1; taAddress = (PTA_ADDRESS)transportAddress->Address; taAddress->AddressType = TDI_ADDRESS_TYPE_LPX; taAddress->AddressLength = TDI_ADDRESS_LENGTH_LPX; lpxAddress = (PTDI_ADDRESS_LPX)taAddress->Address; RtlCopyMemory( lpxAddress, Address, sizeof(TDI_ADDRESS_LPX) ); // // Open Address File // status = ZwCreateFile( &addressFileHandle, GENERIC_READ, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, 0, 0, eaBuffer, ADDRESS_EA_BUFFER_LENGTH ); if (!NT_SUCCESS(status)) { LtDebugPrint (0,("TdiOpenAddress: FAILURE, NtCreateFile returned status code=%x.\n", status)); *AddressFileHandle = NULL; *AddressFileObject = NULL; return status; } status = ioStatusBlock.Status; if (!NT_SUCCESS(status)) { LtDebugPrint (0, ("TdiOpenAddress: FAILURE, IoStatusBlock.Status contains status code=%x\n", status)); *AddressFileHandle = NULL; *AddressFileObject = NULL; return status; } status = ObReferenceObjectByHandle ( addressFileHandle, 0L, NULL, KernelMode, (PVOID *) &addressFileObject, NULL ); if (!NT_SUCCESS(status)) { LtDebugPrint(0,("\n****** Send Test: FAILED on open of server Connection: %x ******\n", status)); ZwClose(addressFileHandle); *AddressFileHandle = NULL; *AddressFileObject = NULL; return status; } *AddressFileHandle = addressFileHandle; *AddressFileObject = addressFileObject; LtDebugPrint (3, ("[LpxTdi] TdiOpenAddress: returning\n")); return status; }
NTSTATUS SampCleanup18471( ) /*++ Routine Description: Cleans up the transaction log left by fixing bug 18471. This routine builds a transaction with all the keys in the log and then commits the transaction Arguments: None. Return Value: Status codes from the NT registry APIs and NT RXact APIs --*/ { OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE RootKey = NULL; HANDLE AliasKey = NULL; UCHAR Buffer[sizeof(KEY_BASIC_INFORMATION) + 15 * sizeof(WCHAR)]; UCHAR Buffer2[sizeof(KEY_BASIC_INFORMATION) + 15 * sizeof(WCHAR)]; UNICODE_STRING KeyName; WCHAR KeyBuffer[100]; PKEY_BASIC_INFORMATION BasicInfo = (PKEY_BASIC_INFORMATION) Buffer; PKEY_BASIC_INFORMATION BasicInfo2 = (PKEY_BASIC_INFORMATION) Buffer2; ULONG BasicInfoLength; ULONG Index, Index2; // // Open the 18471 key in the registry // RtlInitUnicodeString( &KeyName, SAMP_FIX_18471_KEY_NAME ); InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, 0, NULL ); Status = NtOpenKey( &RootKey, KEY_READ | DELETE, &ObjectAttributes ); if (!NT_SUCCESS(Status)) { // // If the error was that the key did not exist, then there // is nothing to cleanup, so return success. // if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { return(STATUS_SUCCESS); } return(Status); } // // Create a transaction to add all the keys to delete to // Status = SampAcquireWriteLock(); if (!NT_SUCCESS(Status)) { goto Cleanup; } SampSetTransactionDomain(0); SampTransactionWithinDomain = FALSE; // // Now enumerate all the subkeys of the root 18471 key // Index = 0; do { Status = NtEnumerateKey( RootKey, Index, KeyBasicInformation, BasicInfo, sizeof(Buffer), &BasicInfoLength ); // // // Check if this is the RXACT key. If it is, we don't want // to add it to the delete log. // // Otherwise open this key and enumerate all the subkeys of it. // if (NT_SUCCESS(Status) && ((BasicInfo->NameLength != RTLP_RXACT_KEY_NAME_SIZE) || memcmp( BasicInfo->Name, RTLP_RXACT_KEY_NAME, RTLP_RXACT_KEY_NAME_SIZE ) ) ) { KeyName.Buffer = BasicInfo->Name; KeyName.Length = (USHORT) BasicInfo->NameLength; KeyName.MaximumLength = KeyName.Length; InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, RootKey, NULL ); // // Open the key for the alias rid. This really should // succeed // Status = NtOpenKey( &AliasKey, KEY_READ, &ObjectAttributes ); if (!NT_SUCCESS(Status)) { break; } // // Enumerate all the subkeys (the alias members) and add them // to the transaction // Index2 = 0; do { Status = NtEnumerateKey( AliasKey, Index2, KeyBasicInformation, BasicInfo2, sizeof(Buffer2), &BasicInfoLength ); if (NT_SUCCESS(Status)) { // // Build the name of this key from the alias rid and the // member rid // KeyName.Buffer = KeyBuffer; KeyName.MaximumLength = sizeof(KeyBuffer); SampBuild18471CleanupKey( &KeyName, BasicInfo->Name, BasicInfo->NameLength, BasicInfo2->Name, BasicInfo2->NameLength ); Status = RtlAddActionToRXact( SampRXactContext, RtlRXactOperationDelete, &KeyName, 0, NULL, 0 ); } Index2++; } while (NT_SUCCESS(Status)); NtClose(AliasKey); AliasKey = NULL; // // If we suffered a serious error, get out of here now // if (!NT_SUCCESS(Status)) { if (Status != STATUS_NO_MORE_ENTRIES) { break; } else { Status = STATUS_SUCCESS; } } // // Add the alias RID key to the RXact now - we need to add it // after deleting all the children // KeyName.Buffer = KeyBuffer; KeyName.MaximumLength = sizeof(KeyBuffer); SampBuild18471CleanupKey( &KeyName, BasicInfo->Name, BasicInfo->NameLength, NULL, 0 ); Status = RtlAddActionToRXact( SampRXactContext, RtlRXactOperationDelete, &KeyName, 0, NULL, 0 ); } Index++; } while (NT_SUCCESS(Status)); if (Status == STATUS_NO_MORE_ENTRIES) { Status = STATUS_SUCCESS; } if (!NT_SUCCESS(Status)) { goto Cleanup; } RtlInitUnicodeString( &KeyName, SAMP_FIX_18471_SHORT_KEY_NAME ); Status = RtlAddActionToRXact( SampRXactContext, RtlRXactOperationDelete, &KeyName, 0, NULL, 0 ); if (NT_SUCCESS(Status)) { // // Write the new server revision to indicate that this // upgrade has been performed // ULONG Revision = SAMP_SERVER_REVISION; PSAMP_OBJECT ServerContext; // // We need to read the fixed attributes of the server objects. // Create a context to do that. // ServerContext = SampCreateContext( SampServerObjectType, TRUE ); if ( ServerContext != NULL ) { ServerContext->RootKey = SampKey; Status = SampSetFixedAttributes( ServerContext, &Revision ); if (NT_SUCCESS(Status)) { Status = SampStoreObjectAttributes( ServerContext, TRUE ); } SampDeleteContext( ServerContext ); } else { Status = STATUS_INSUFFICIENT_RESOURCES; } } // // Apply the RXACT and delete the remaining keys. // Cleanup: // // Cleanup any floating bits from above. // if (NT_SUCCESS(Status)) { Status = SampReleaseWriteLock( TRUE ); } else { (VOID) SampReleaseWriteLock( FALSE ); } if (RootKey != NULL) { NtClose(RootKey); } ASSERT(AliasKey == NULL); return(Status); }
NTSTATUS SampCheckMemberUpgradedFor18471( IN ULONG AliasRid, IN ULONG MemberRid ) /*++ Routine Description: This routine checks if the SAM upgrade flag is set. The upgrade flag is: HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\lsa UpgradeSam = REG_DWORD 1 Arguments: Return Value: TRUE - The flag was set FALSE - The flag was not set or the value was not present --*/ { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE KeyHandle; NTSTATUS Status; WCHAR KeyName[100]; WCHAR AliasName[15]; // big enough for 4 billion UNICODE_STRING KeyNameString; UNICODE_STRING AliasString; // // Build the full key name. It is of the form: // "fix18471\alias_rid\member_rid" // wcscpy( KeyName, SAMP_FIX_18471_KEY_NAME L"\\" ); AliasString.Buffer = AliasName; AliasString.MaximumLength = sizeof(AliasName); Status = RtlIntegerToUnicodeString( AliasRid, 16, &AliasString ); ASSERT(NT_SUCCESS(Status)); wcscat( KeyName, AliasString.Buffer ); wcscat( KeyName, L"\\" ); AliasString.MaximumLength = sizeof(AliasName); Status = RtlIntegerToUnicodeString( MemberRid, 16, &AliasString ); ASSERT(NT_SUCCESS(Status)); wcscat( KeyName, AliasString.Buffer ); RtlInitUnicodeString( &KeyNameString, KeyName ); // // Open the member key in the registry // InitializeObjectAttributes( &ObjectAttributes, &KeyNameString, OBJ_CASE_INSENSITIVE, 0, NULL ); Status = NtOpenKey( &KeyHandle, KEY_READ, &ObjectAttributes ); NtClose(KeyHandle); return(Status); }
struct file *filp_open(const char *name, int flags, int mode, int *err) { struct file *fp = NULL; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE FileHandle; IO_STATUS_BLOCK IoStatus; ACCESS_MASK DesiredAccess; ULONG CreateDisposition; ULONG ShareAccess; ULONG CreateOptions; USHORT NameLength = 0; USHORT PrefixLength = 0; UNICODE_STRING UnicodeName; PWCHAR UnicodeString = NULL; ANSI_STRING AnsiName; PUCHAR AnsiString = NULL; /* Analyze the flags settings */ if (cfs_is_flag_set(flags, O_WRONLY)) { DesiredAccess = (GENERIC_WRITE | SYNCHRONIZE); ShareAccess = 0; } else if (cfs_is_flag_set(flags, O_RDWR)) { DesiredAccess = (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE); ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE; } else { DesiredAccess = (GENERIC_READ | SYNCHRONIZE); ShareAccess = FILE_SHARE_READ; } if (cfs_is_flag_set(flags, O_CREAT)) { if (cfs_is_flag_set(flags, O_EXCL)) { CreateDisposition = FILE_CREATE; } else { CreateDisposition = FILE_OPEN_IF; } } else { CreateDisposition = FILE_OPEN; } if (cfs_is_flag_set(flags, O_TRUNC)) { if (cfs_is_flag_set(flags, O_EXCL)) { CreateDisposition = FILE_OVERWRITE; } else { CreateDisposition = FILE_OVERWRITE_IF; } } CreateOptions = 0; if (cfs_is_flag_set(flags, O_DIRECTORY)) { cfs_set_flag(CreateOptions, FILE_DIRECTORY_FILE); } if (cfs_is_flag_set(flags, O_SYNC)) { cfs_set_flag(CreateOptions, FILE_WRITE_THROUGH); } if (cfs_is_flag_set(flags, O_DIRECT)) { cfs_set_flag(CreateOptions, FILE_NO_INTERMEDIATE_BUFFERING); } /* Initialize the unicode path name for the specified file */ NameLength = (USHORT)strlen(name); /* Check file & path name */ if (name[0] != '\\') { if (NameLength < 1 || name[1] != ':' || !is_drv_letter_valid(name[0])) { /* invalid file path name */ return ERR_PTR(-EINVAL); } PrefixLength = (USHORT)strlen(dos_file_prefix[0]); } else { int i, j; for (i = 0; i < 3 && dos_file_prefix[i] != NULL; i++) { j = strlen(dos_file_prefix[i]); if (NameLength > j && _strnicmp(dos_file_prefix[i], name, j) == 0) break; } if (i >= 3) return ERR_PTR(-EINVAL); } AnsiString = kmalloc(sizeof(CHAR) * (NameLength + PrefixLength + 1), __GFP_ZERO); if (NULL == AnsiString) return ERR_PTR(-ENOMEM); UnicodeString = kmalloc(sizeof(WCHAR) * (NameLength + PrefixLength + 1), __GFP_ZERO); if (NULL == UnicodeString) { kfree(AnsiString); return ERR_PTR(-ENOMEM); } if (PrefixLength) { RtlCopyMemory(&AnsiString[0], dos_file_prefix[0], PrefixLength); } RtlCopyMemory(&AnsiString[PrefixLength], name, NameLength); NameLength += PrefixLength; AnsiName.MaximumLength = NameLength + 1; AnsiName.Length = NameLength; AnsiName.Buffer = AnsiString; UnicodeName.MaximumLength = (NameLength + 1) * sizeof(WCHAR); UnicodeName.Length = 0; UnicodeName.Buffer = (PWSTR)UnicodeString; RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, FALSE); /* Setup the object attributes structure for the file. */ InitializeObjectAttributes( &ObjectAttributes, &UnicodeName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL ); /* Now to open or create the file now */ Status = ZwCreateFile( &FileHandle, DesiredAccess, &ObjectAttributes, &IoStatus, 0, FILE_ATTRIBUTE_NORMAL, ShareAccess, CreateDisposition, CreateOptions, NULL, 0 ); /* Check the returned status of IoStatus... */ if (!NT_SUCCESS(IoStatus.Status)) { kfree(UnicodeString); kfree(AnsiString); return ERR_PTR(cfs_error_code(IoStatus.Status)); } /* Allocate the file_t: libcfs file object */ fp = kmalloc(sizeof(*fp) + NameLength, __GFP_ZERO); if (NULL == fp) { Status = ZwClose(FileHandle); ASSERT(NT_SUCCESS(Status)); kfree(UnicodeString); kfree(AnsiString); return ERR_PTR(-ENOMEM); } fp->f_handle = FileHandle; strcpy(fp->f_name, name); fp->f_flags = flags; fp->f_mode = (mode_t)mode; fp->f_count = 1; /* free the memory of temporary name strings */ kfree(UnicodeString); kfree(AnsiString); return fp; }
NTSTATUS DraidStart( PDRAID_GLOBALS DraidGlobals ) { NTSTATUS status; OBJECT_ATTRIBUTES objectAttributes; #if 0 TDI_CLIENT_INTERFACE_INFO info; UNICODE_STRING clientName; #endif KDPrintM(DBG_LURN_INFO, ("Starting\n")); InitializeListHead(&DraidGlobals->ArbiterList); KeInitializeSpinLock(&DraidGlobals->ArbiterListSpinlock); InitializeListHead(&DraidGlobals->ClientList); KeInitializeSpinLock(&DraidGlobals->ClientListSpinlock); KeInitializeEvent(&DraidGlobals->DraidExitEvent, NotificationEvent, FALSE); KeInitializeEvent(&DraidGlobals->NetChangedEvent, NotificationEvent, FALSE); InitializeListHead(&DraidGlobals->ListenContextList); KeInitializeSpinLock(&DraidGlobals->ListenContextSpinlock); InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); g_DraidGlobals = DraidGlobals; status = PsCreateSystemThread( &DraidGlobals->DraidThreadHandle, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, DraidListenerThreadProc, DraidGlobals ); if(!NT_SUCCESS(status)) { ASSERT(FALSE); DraidGlobals->DraidThreadHandle = NULL; DraidGlobals->DraidThreadObject = NULL; return STATUS_UNSUCCESSFUL; } status = ObReferenceObjectByHandle( DraidGlobals->DraidThreadHandle, FILE_READ_DATA, NULL, KernelMode, &DraidGlobals->DraidThreadObject, NULL ); if(!NT_SUCCESS(status)) { ASSERT(FALSE); DraidGlobals->DraidThreadObject = NULL; DraidGlobals->DraidThreadHandle = NULL; return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; }
/* @implemented */ NTSTATUS NTAPI RtlCreateUserThread(IN HANDLE ProcessHandle, IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, IN BOOLEAN CreateSuspended, IN ULONG StackZeroBits OPTIONAL, IN SIZE_T StackReserve OPTIONAL, IN SIZE_T StackCommit OPTIONAL, IN PTHREAD_START_ROUTINE StartAddress, IN PVOID Parameter OPTIONAL, OUT PHANDLE ThreadHandle OPTIONAL, OUT PCLIENT_ID ClientId OPTIONAL) { NTSTATUS Status; HANDLE Handle; CLIENT_ID ThreadCid; INITIAL_TEB InitialTeb; OBJECT_ATTRIBUTES ObjectAttributes; CONTEXT Context; /* First, we'll create the Stack */ Status = RtlpCreateUserStack(ProcessHandle, StackReserve, StackCommit, StackZeroBits, &InitialTeb); if (!NT_SUCCESS(Status)) return Status; /* Next, we'll set up the Initial Context */ RtlInitializeContext(ProcessHandle, &Context, Parameter, StartAddress, InitialTeb.StackBase); /* We are now ready to create the Kernel Thread Object */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, SecurityDescriptor); Status = ZwCreateThread(&Handle, THREAD_ALL_ACCESS, &ObjectAttributes, ProcessHandle, &ThreadCid, &Context, &InitialTeb, CreateSuspended); if (!NT_SUCCESS(Status)) { /* Free the stack */ RtlpFreeUserStack(ProcessHandle, &InitialTeb); } else { /* Return thread data */ if (ThreadHandle) *ThreadHandle = Handle; else NtClose(Handle); if (ClientId) *ClientId = ThreadCid; } /* Return success or the previous failure */ return Status; }
// // Start reception thread to handle registration request from client. // NTSTATUS DraidAcceptConnection( PDRAID_GLOBALS DraidGlobals, PDRAID_LISTEN_CONTEXT ListenContext ) { PDRAID_REMOTE_CLIENT_CONNECTION Connection; HANDLE ConFileHandle; PFILE_OBJECT ConFileObject; LPX_ADDRESS RemoteAddr; NTSTATUS status; OBJECT_ATTRIBUTES objectAttributes; HANDLE ThreadHandle; if (ListenContext->TdiListenContext.Status != STATUS_SUCCESS) { // Failed to accept connection. Maybe NIC is disabled. This context will be handled by DraidStopListenAddr KDPrintM(DBG_LURN_INFO, ("Failed to listen. Maybe network is down.\n")); return STATUS_UNSUCCESSFUL; } // // Get information about new connection and prepare for new listening. // ConFileHandle = ListenContext->ListenFileHandle; ConFileObject = ListenContext->ListenFileObject; RtlCopyMemory(&RemoteAddr, &ListenContext->TdiListenContext.RemoteAddress, sizeof(LPX_ADDRESS)); ListenContext->TdiListenContext.Irp = NULL; ListenContext->ListenFileHandle = NULL; ListenContext->ListenFileObject = NULL; KDPrintM(DBG_LURN_INFO, ("Connected from %02X:%02X:%02X:%02X:%02X:%02X 0x%4X\n", RemoteAddr.Node[0], RemoteAddr.Node[1], RemoteAddr.Node[2], RemoteAddr.Node[3], RemoteAddr.Node[4], RemoteAddr.Node[5], NTOHS(RemoteAddr.Port) )); status = DraidListenConnection(ListenContext); if (!NT_SUCCESS(status)) { KDPrintM(DBG_LURN_INFO, ("Failed to listen again\n")); ASSERT(FALSE); // Continue anyway even if anothre listening is failure } // // Now we can Handle accpeted connection. // Connection = ExAllocatePoolWithTag(NonPagedPool, sizeof(DRAID_REMOTE_CLIENT_CONNECTION), DRAID_REMOTE_CLIENT_CHANNEL_POOL_TAG); if (!Connection) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(Connection, sizeof(DRAID_REMOTE_CLIENT_CONNECTION)); Connection->ConnectionFileHandle = ConFileHandle; Connection->ConnectionFileObject = ConFileObject; RtlCopyMemory(&Connection->RemoteAddr, &RemoteAddr, sizeof(LPX_ADDRESS)); // Start reception thread. InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); status = PsCreateSystemThread( &ThreadHandle, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, DraidReceptionThreadProc, (PVOID) Connection ); if(!NT_SUCCESS(status)) { KDPrintM(DBG_LURN_ERROR, ("Reception thread creation failedPsCreateSystemThread FAIL %x\n", status)); ExFreePoolWithTag(Connection, DRAID_REMOTE_CLIENT_CHANNEL_POOL_TAG); return status; } ZwClose(ThreadHandle); // Reception thread will be exited by itself. Close now. InterlockedIncrement(&DraidGlobals->ReceptionThreadCount); return STATUS_SUCCESS; }
static BOOLEAN GetComputerIdentifier(PWSTR Identifier, ULONG IdentifierLength) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; LPCWSTR ComputerIdentifier; HANDLE ProcessorsKey; PKEY_FULL_INFORMATION pFullInfo; ULONG Size, SizeNeeded; NTSTATUS Status; DPRINT("GetComputerIdentifier() called\n"); Size = sizeof(KEY_FULL_INFORMATION); pFullInfo = (PKEY_FULL_INFORMATION)RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); if (!pFullInfo) { DPRINT("RtlAllocateHeap() failed\n"); return FALSE; } /* Open the processors key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&ProcessorsKey, KEY_QUERY_VALUE , &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed (Status 0x%lx)\n", Status); RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo); return FALSE; } /* Get number of subkeys */ Status = NtQueryKey( ProcessorsKey, KeyFullInformation, pFullInfo, Size, &Size); NtClose(ProcessorsKey); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { DPRINT("NtQueryKey() failed (Status 0x%lx)\n", Status); RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo); return FALSE; } /* Find computer identifier */ if (pFullInfo->SubKeys == 0) { /* Something strange happened. No processor detected */ RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo); return FALSE; } if (IsAcpiComputer()) { if (pFullInfo->SubKeys == 1) { /* Computer is mono-CPU */ ComputerIdentifier = L"ACPI UP"; } else { /* Computer is multi-CPUs */ ComputerIdentifier = L"ACPI MP"; } } else { if (pFullInfo->SubKeys == 1) { /* Computer is mono-CPU */ ComputerIdentifier = L"PC UP"; } else { /* Computer is multi-CPUs */ ComputerIdentifier = L"PC MP"; } } RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo); /* Copy computer identifier to return buffer */ SizeNeeded = (wcslen(ComputerIdentifier) + 1) * sizeof(WCHAR); if (SizeNeeded > IdentifierLength) return FALSE; RtlCopyMemory(Identifier, ComputerIdentifier, SizeNeeded); return TRUE; }
NTSTATUS LogfCreate(PLOGFILE* LogFile, PCWSTR LogName, PUNICODE_STRING FileName, ULONG MaxSize, ULONG Retention, BOOLEAN Permanent, BOOLEAN Backup) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; FILE_STANDARD_INFORMATION FileStdInfo; PLOGFILE pLogFile; SIZE_T LogNameLen; BOOLEAN CreateNew; pLogFile = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pLogFile)); if (!pLogFile) { DPRINT1("Cannot allocate heap!\n"); return STATUS_NO_MEMORY; } LogNameLen = (LogName ? wcslen(LogName) : 0) + 1; pLogFile->LogName = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, LogNameLen * sizeof(WCHAR)); if (pLogFile->LogName == NULL) { DPRINT1("Cannot allocate heap\n"); Status = STATUS_NO_MEMORY; goto Quit; } if (LogName) StringCchCopyW(pLogFile->LogName, LogNameLen, LogName); InitializeObjectAttributes(&ObjectAttributes, FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); DPRINT1("Going to create or open %wZ\n", FileName); Status = NtCreateFile(&pLogFile->FileHandle, Backup ? (GENERIC_READ | SYNCHRONIZE) : (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE), &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, Backup ? FILE_OPEN : FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(Status)) { DPRINT1("Cannot create file `%wZ' (Status 0x%08lx)\n", FileName, Status); goto Quit; } CreateNew = (IoStatusBlock.Information == FILE_CREATED); DPRINT1("%wZ %s successfully\n", FileName, CreateNew ? "created" : "opened"); /* * Retrieve the log file size and check whether the file is not too large; * this log format only supports files of theoretical size < 0xFFFFFFFF . * * As it happens that, on Windows (and ReactOS), retrieving the End-Of-File * information using NtQueryInformationFile with the FileEndOfFileInformation * class is invalid (who knows why...), use instead the FileStandardInformation * class, and the EndOfFile member of the returned FILE_STANDARD_INFORMATION * structure will give the desired information. */ Status = NtQueryInformationFile(pLogFile->FileHandle, &IoStatusBlock, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation); if (!NT_SUCCESS(Status)) { DPRINT1("EventLog: NtQueryInformationFile failed (Status 0x%08lx)\n", Status); goto Quit; } if (FileStdInfo.EndOfFile.HighPart != 0) { DPRINT1("EventLog: Log `%wZ' is too large.\n", FileName); Status = STATUS_EVENTLOG_FILE_CORRUPT; // STATUS_FILE_TOO_LARGE; goto Quit; } DPRINT("Initializing LogFile `%S'\n", pLogFile->LogName); Status = ElfCreateFile(&pLogFile->LogFile, FileName, FileStdInfo.EndOfFile.LowPart, MaxSize, Retention, CreateNew, Backup, LogfpAlloc, LogfpFree, LogfpSetFileSize, LogfpWriteFile, LogfpReadFile, LogfpFlushFile); if (!NT_SUCCESS(Status)) goto Quit; pLogFile->Permanent = Permanent; RtlInitializeResource(&pLogFile->Lock); LogfListAddItem(pLogFile); Quit: if (!NT_SUCCESS(Status)) { if (pLogFile->FileHandle != NULL) NtClose(pLogFile->FileHandle); if (pLogFile->LogName) RtlFreeHeap(GetProcessHeap(), 0, pLogFile->LogName); RtlFreeHeap(GetProcessHeap(), 0, pLogFile); } else { *LogFile = pLogFile; } return Status; }
static BOOLEAN GetDisplayIdentifier(PWSTR Identifier, ULONG IdentifierLength) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; WCHAR Buffer[32]; HANDLE BusKey; HANDLE BusInstanceKey; HANDLE ControllerKey; HANDLE ControllerInstanceKey; ULONG BusInstance; ULONG ControllerInstance; ULONG BufferLength; ULONG ReturnedLength; PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; NTSTATUS Status; DPRINT("GetDisplayIdentifier() called\n"); /* Open the bus key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&BusKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed (Status %lx)\n", Status); return FALSE; } BusInstance = 0; while (TRUE) { swprintf(Buffer, L"%lu", BusInstance); RtlInitUnicodeString(&KeyName, Buffer); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, BusKey, NULL); Status = NtOpenKey(&BusInstanceKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed (Status %lx)\n", Status); NtClose(BusKey); return FALSE; } /* Open the controller type key */ RtlInitUnicodeString(&KeyName, L"DisplayController"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, BusInstanceKey, NULL); Status = NtOpenKey(&ControllerKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); if (NT_SUCCESS(Status)) { ControllerInstance = 0; while (TRUE) { /* Open the pointer controller instance key */ swprintf(Buffer, L"%lu", ControllerInstance); RtlInitUnicodeString(&KeyName, Buffer); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, ControllerKey, NULL); Status = NtOpenKey(&ControllerInstanceKey, KEY_QUERY_VALUE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed (Status %lx)\n", Status); NtClose(ControllerKey); NtClose(BusInstanceKey); NtClose(BusKey); return FALSE; } /* Get controller identifier */ RtlInitUnicodeString(&KeyName, L"Identifier"); BufferLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256 * sizeof(WCHAR); ValueInfo = (KEY_VALUE_PARTIAL_INFORMATION*) RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); if (ValueInfo == NULL) { DPRINT("RtlAllocateHeap() failed\n"); NtClose(ControllerInstanceKey); NtClose(ControllerKey); NtClose(BusInstanceKey); NtClose(BusKey); return FALSE; } Status = NtQueryValueKey(ControllerInstanceKey, &KeyName, KeyValuePartialInformation, ValueInfo, BufferLength, &ReturnedLength); if (NT_SUCCESS(Status)) { DPRINT("Identifier: %S\n", (PWSTR)ValueInfo->Data); BufferLength = min(ValueInfo->DataLength / sizeof(WCHAR), IdentifierLength); RtlCopyMemory (Identifier, ValueInfo->Data, BufferLength * sizeof(WCHAR)); Identifier[BufferLength] = 0; RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); NtClose(ControllerInstanceKey); NtClose(ControllerKey); NtClose(BusInstanceKey); NtClose(BusKey); return TRUE; } NtClose(ControllerInstanceKey); ControllerInstance++; } NtClose(ControllerKey); } NtClose(BusInstanceKey); BusInstance++; } NtClose(BusKey); return FALSE; }
PFILEVIEW NTAPI EngLoadModuleEx( LPWSTR pwsz, ULONG cjSizeOfModule, FLONG fl) { PFILEVIEW pFileView = NULL; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE hRootDir; UNICODE_STRING ustrFileName; IO_STATUS_BLOCK IoStatusBlock; FILE_BASIC_INFORMATION FileInformation; HANDLE hFile; NTSTATUS Status; LARGE_INTEGER liSize; if (fl & FVF_FONTFILE) { pFileView = EngAllocMem(0, sizeof(FONTFILEVIEW), 'vffG'); } else { pFileView = EngAllocMem(0, sizeof(FILEVIEW), 'liFg'); } /* Check for success */ if (!pFileView) return NULL; /* Check if the file is relative to system32 */ if (fl & FVF_SYSTEMROOT) { hRootDir = ghSystem32Directory; } else { hRootDir = ghRootDirectory; } /* Initialize unicode string and object attributes */ RtlInitUnicodeString(&ustrFileName, pwsz); InitializeObjectAttributes(&ObjectAttributes, &ustrFileName, OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, hRootDir, NULL); /* Now open the file */ Status = ZwCreateFile(&hFile, FILE_READ_DATA, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0); Status = ZwQueryInformationFile(hFile, &IoStatusBlock, &FileInformation, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (NT_SUCCESS(Status)) { pFileView->LastWriteTime = FileInformation.LastWriteTime; } /* Create a section from the file */ liSize.QuadPart = cjSizeOfModule; Status = MmCreateSection(&pFileView->pSection, SECTION_ALL_ACCESS, NULL, &liSize, fl & FVF_READONLY ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE, SEC_COMMIT, hFile, NULL); /* Close the file handle */ ZwClose(hFile); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create a section Status=0x%x\n", Status); EngFreeMem(pFileView); return NULL; } pFileView->pvKView = NULL; pFileView->pvViewFD = NULL; pFileView->cjView = 0; return pFileView; }
BOOL GetDllList(VOID) { NTSTATUS Status; OBJECT_ATTRIBUTES Attributes; BOOL bRet = FALSE; BOOL bLoad; HANDLE hKey = NULL; DWORD dwSize; PKEY_VALUE_PARTIAL_INFORMATION kvpInfo = NULL; UNICODE_STRING szKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"); UNICODE_STRING szLoadName = RTL_CONSTANT_STRING(L"LoadAppInit_DLLs"); UNICODE_STRING szDllsName = RTL_CONSTANT_STRING(L"AppInit_DLLs"); InitializeObjectAttributes(&Attributes, &szKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&hKey, KEY_READ, &Attributes); if (NT_SUCCESS(Status)) { dwSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD); kvpInfo = HeapAlloc(GetProcessHeap(), 0, dwSize); if (!kvpInfo) goto end; Status = NtQueryValueKey(hKey, &szLoadName, KeyValuePartialInformation, kvpInfo, dwSize, &dwSize); if (!NT_SUCCESS(Status)) goto end; RtlMoveMemory(&bLoad, kvpInfo->Data, kvpInfo->DataLength); HeapFree(GetProcessHeap(), 0, kvpInfo); kvpInfo = NULL; if (bLoad) { Status = NtQueryValueKey(hKey, &szDllsName, KeyValuePartialInformation, NULL, 0, &dwSize); if (Status != STATUS_BUFFER_TOO_SMALL) goto end; kvpInfo = HeapAlloc(GetProcessHeap(), 0, dwSize); if (!kvpInfo) goto end; Status = NtQueryValueKey(hKey, &szDllsName, KeyValuePartialInformation, kvpInfo, dwSize, &dwSize); if (NT_SUCCESS(Status)) { LPWSTR lpBuffer = (LPWSTR)kvpInfo->Data; if (*lpBuffer != UNICODE_NULL) { INT bytesToCopy, nullPos; bytesToCopy = min(kvpInfo->DataLength, KEY_LENGTH * sizeof(WCHAR)); if (bytesToCopy != 0) { RtlMoveMemory(szAppInit, kvpInfo->Data, bytesToCopy); nullPos = (bytesToCopy / sizeof(WCHAR)) - 1; /* ensure string is terminated */ szAppInit[nullPos] = UNICODE_NULL; bRet = TRUE; } } } } } end: if (hKey) NtClose(hKey); if (kvpInfo) HeapFree(GetProcessHeap(), 0, kvpInfo); return bRet; }
INT WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ INT nCmdShow ) { LONG result; #ifdef DEBUG PHP_BASE_THREAD_DBG dbg; #endif HANDLE currentTokenHandle; CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); #ifndef DEBUG SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); #endif PhInstanceHandle = (HINSTANCE)NtCurrentPeb()->ImageBaseAddress; if (!NT_SUCCESS(PhInitializePhLib())) return 1; if (!PhInitializeAppSystem()) return 1; PhInitializeCommonControls(); currentTokenHandle = PhGetOwnTokenAttributes().TokenHandle; if (currentTokenHandle) { PTOKEN_USER tokenUser; if (NT_SUCCESS(PhGetTokenUser(currentTokenHandle, &tokenUser))) { PhCurrentUserName = PhGetSidFullName(tokenUser->User.Sid, TRUE, NULL); PhFree(tokenUser); } } PhLocalSystemName = PhGetSidFullName(&PhSeLocalSystemSid, TRUE, NULL); // There has been a report of the above call failing. if (!PhLocalSystemName) PhLocalSystemName = PhCreateString(L"NT AUTHORITY\\SYSTEM"); PhApplicationFileName = PhGetApplicationFileName(); PhApplicationDirectory = PhGetApplicationDirectory(); // Just in case if (!PhApplicationFileName) PhApplicationFileName = PhCreateString(L"ProcessHacker.exe"); if (!PhApplicationDirectory) PhApplicationDirectory = PhReferenceEmptyString(); PhpProcessStartupParameters(); PhSettingsInitialization(); PhpEnablePrivileges(); if (PhStartupParameters.RunAsServiceMode) { RtlExitUserProcess(PhRunAsServiceStart(PhStartupParameters.RunAsServiceMode)); } PhpInitializeSettings(); // Activate a previous instance if required. if (PhGetIntegerSetting(L"AllowOnlyOneInstance") && !PhStartupParameters.NewInstance && !PhStartupParameters.ShowOptions && !PhStartupParameters.CommandMode && !PhStartupParameters.PhSvc) { PhActivatePreviousInstance(); } if (PhGetIntegerSetting(L"EnableKph") && !PhStartupParameters.NoKph && !PhIsExecutingInWow64()) PhInitializeKph(); if (PhStartupParameters.CommandMode && PhStartupParameters.CommandType && PhStartupParameters.CommandAction) { NTSTATUS status; status = PhCommandModeStart(); if (!NT_SUCCESS(status) && !PhStartupParameters.Silent) { PhShowStatus(NULL, L"Unable to execute the command", status, 0); } RtlExitUserProcess(status); } #ifdef DEBUG dbg.ClientId = NtCurrentTeb()->ClientId; dbg.StartAddress = wWinMain; dbg.Parameter = NULL; InsertTailList(&PhDbgThreadListHead, &dbg.ListEntry); TlsSetValue(PhDbgThreadDbgTlsIndex, &dbg); #endif PhInitializeAutoPool(&BaseAutoPool); PhEmInitialization(); PhGuiSupportInitialization(); PhTreeNewInitialization(); PhGraphControlInitialization(); PhHexEditInitialization(); PhColorBoxInitialization(); PhSmallIconSize.X = GetSystemMetrics(SM_CXSMICON); PhSmallIconSize.Y = GetSystemMetrics(SM_CYSMICON); PhLargeIconSize.X = GetSystemMetrics(SM_CXICON); PhLargeIconSize.Y = GetSystemMetrics(SM_CYICON); if (PhStartupParameters.ShowOptions) { // Elevated options dialog for changing the value of Replace Task Manager with Process Hacker. PhShowOptionsDialog(PhStartupParameters.WindowHandle); RtlExitUserProcess(STATUS_SUCCESS); } #ifndef DEBUG if (PhIsExecutingInWow64() && !PhStartupParameters.PhSvc) { PhShowWarning( NULL, L"You are attempting to run the 32-bit version of Process Hacker on 64-bit Windows. " L"Most features will not work correctly.\n\n" L"Please run the 64-bit version of Process Hacker instead." ); } #endif PhPluginsEnabled = PhGetIntegerSetting(L"EnablePlugins") && !PhStartupParameters.NoPlugins; if (PhPluginsEnabled) { PhPluginsInitialization(); PhLoadPlugins(); } if (PhStartupParameters.PhSvc) { MSG message; // Turn the feedback cursor off. PostMessage(NULL, WM_NULL, 0, 0); GetMessage(&message, NULL, 0, 0); RtlExitUserProcess(PhSvcMain(NULL, NULL, NULL)); } // Create a mutant for the installer. { HANDLE mutantHandle; OBJECT_ATTRIBUTES oa; UNICODE_STRING mutantName; RtlInitUnicodeString(&mutantName, L"\\BaseNamedObjects\\ProcessHacker2Mutant"); InitializeObjectAttributes( &oa, &mutantName, 0, NULL, NULL ); NtCreateMutant(&mutantHandle, MUTANT_ALL_ACCESS, &oa, FALSE); } // Set priority. { PROCESS_PRIORITY_CLASS priorityClass; priorityClass.Foreground = FALSE; priorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; if (PhStartupParameters.PriorityClass != 0) priorityClass.PriorityClass = (UCHAR)PhStartupParameters.PriorityClass; NtSetInformationProcess(NtCurrentProcess(), ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS)); } if (!PhMainWndInitialization(nCmdShow)) { PhShowError(NULL, L"Unable to initialize the main window."); return 1; } PhDrainAutoPool(&BaseAutoPool); result = PhMainMessageLoop(); RtlExitUserProcess(result); }
// This function is even more a hack // It will remove the dll from the Debug manager // but vs.net does not unload the symbols (don't know why) // The dll can be loaded again after unloading. // This function leaks memory. void DllLoader::UnloadSymbols() { #ifdef ENABLE_SYMBOL_UNLOADING ANSI_STRING name; OBJECT_ATTRIBUTES attributes; RtlInitAnsiString(&name, GetName()); InitializeObjectAttributes(&attributes, &name, OBJ_CASE_INSENSITIVE, NULL); // Try to unload the symbols from vs.net debugger DbgUnLoadImageSymbols(&name, (ULONG)hModule, 0xFFFFFFFF); LPVOID pBaseAddress=GetXbdmBaseAddress(); if (pBaseAddress) { CoffLoader dllxbdm; if (dllxbdm.ParseHeaders(pBaseAddress)) { int offset=GetDmiOffset(dllxbdm.WindowsHeader->CheckSum); if (offset==0) { CLog::Log(LOGDEBUG,"DllLoader: Unable to unload symbols for %s. No offset for xbdm.dll with checksum 0x%08X found", GetName(), dllxbdm.WindowsHeader->CheckSum); return; } try { std::wstring strNameW; g_charsetConverter.utf8ToW(GetName(), strNameW); // Get the address of the global struct g_dmi // It is located inside the xbdm.dll and // get the LoadedModuleList member (here the entry var) // of the structure. LPBYTE g_dmi=((LPBYTE)pBaseAddress)+offset; LIST_ENTRY* entry=(LIST_ENTRY*)(g_dmi+4); // Search for the dll we are unloading... while (entry) { std::wstring baseName=(wchar_t*)((LDR_DATA_TABLE_ENTRY*)entry)->BaseDllName.Buffer; if (baseName == strNameW) { // ...and remove it from the LoadedModuleList and free its memory. LIST_ENTRY* back=entry->Blink; LIST_ENTRY* front=entry->Flink; back->Flink=front; front->Blink=back; DmFreePool(entry); break; } entry=entry->Flink; } } catch(...) { CLog::Log(LOGDEBUG,"DllLoader: Unloading symbols for %s failed with an exception.", GetName()); } } } else CLog::Log(LOGDEBUG,"DllLoader: Can't unload symbols for %s. xbdm.dll is needed and not loaded", GetName()); #endif }
DualErr DuplicateProcessToken(PGPUInt32 procId, PHANDLE pDupedToken) { CLIENT_ID clientId; DualErr derr; HANDLE procHandle, token; NTSTATUS status; OBJECT_ATTRIBUTES objAttribs; PGPBoolean openedProcess, openedToken; openedProcess = openedToken = FALSE; pgpAssertAddrValid(pDupedToken, HANDLE); InitializeObjectAttributes(&objAttribs, NULL, 0, NULL, NULL); clientId.UniqueThread = NULL; clientId.UniqueProcess = (PVOID) procId; // Open a handle to the process. status = ZwOpenProcess(&procHandle, PROCESS_ALL_ACCESS, &objAttribs, &clientId); if (!NT_SUCCESS(status)) { derr = DualErr(kPGDMinorError_ZwOpenProcessFailed, status); } openedProcess = derr.IsntError(); // Open a handle to the process token. if (derr.IsntError()) { status = ZwOpenProcessToken(procHandle, TOKEN_ALL_ACCESS, &token); if (!NT_SUCCESS(status)) { derr = DualErr(kPGDMinorError_ZwOpenProcessTokenFailed, status); } openedToken = derr.IsntError(); } // Duplicate the token. if (derr.IsntError()) { SECURITY_QUALITY_OF_SERVICE SQOS; SQOS.Length = sizeof(SQOS); SQOS.ImpersonationLevel = SecurityImpersonation; SQOS.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; SQOS.EffectiveOnly = FALSE; objAttribs.SecurityQualityOfService = (PVOID) &SQOS; status = ZwDuplicateToken(token, TOKEN_QUERY | TOKEN_IMPERSONATE, &objAttribs, SecurityAnonymous, TokenImpersonation, pDupedToken); if (!NT_SUCCESS(status)) { derr = DualErr(kPGDMinorError_ZwDuplicateTokenFailed, status); } } if (openedToken) ZwClose(token); if (openedProcess) ZwClose(procHandle); return derr; }
NTSTATUS KphHashFile( __in PUNICODE_STRING FileName, __out PVOID *Hash, __out PULONG HashSize ) { NTSTATUS status; BCRYPT_ALG_HANDLE hashAlgHandle = NULL; ULONG querySize; ULONG hashObjectSize; ULONG hashSize; PVOID hashObject = NULL; PVOID hash = NULL; BCRYPT_HASH_HANDLE hashHandle = NULL; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK iosb; HANDLE fileHandle = NULL; FILE_STANDARD_INFORMATION standardInfo; ULONG remainingBytes; ULONG bytesToRead; PVOID buffer = NULL; PAGED_CODE(); // Open the hash algorithm and allocate memory for the hash object. if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hashAlgHandle, KPH_HASH_ALGORITHM, NULL, 0))) goto CleanupExit; if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hashObjectSize, sizeof(ULONG), &querySize, 0))) { goto CleanupExit; } if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_HASH_LENGTH, (PUCHAR)&hashSize, sizeof(ULONG), &querySize, 0))) { goto CleanupExit; } if (!(hashObject = ExAllocatePoolWithTag(PagedPool, hashObjectSize, 'vhpK'))) { status = STATUS_INSUFFICIENT_RESOURCES; goto CleanupExit; } if (!(hash = ExAllocatePoolWithTag(PagedPool, hashSize, 'vhpK'))) { status = STATUS_INSUFFICIENT_RESOURCES; goto CleanupExit; } if (!NT_SUCCESS(status = BCryptCreateHash(hashAlgHandle, &hashHandle, hashObject, hashObjectSize, NULL, 0, 0))) { goto CleanupExit; } // Open the file and compute the hash. InitializeObjectAttributes(&objectAttributes, FileName, OBJ_KERNEL_HANDLE, NULL, NULL); if (!NT_SUCCESS(status = ZwCreateFile(&fileHandle, FILE_GENERIC_READ, &objectAttributes, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0))) { goto CleanupExit; } if (!NT_SUCCESS(status = ZwQueryInformationFile(fileHandle, &iosb, &standardInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation))) { goto CleanupExit; } if (standardInfo.EndOfFile.QuadPart <= 0) { status = STATUS_UNSUCCESSFUL; goto CleanupExit; } if (standardInfo.EndOfFile.QuadPart > FILE_MAX_SIZE) { status = STATUS_FILE_TOO_LARGE; goto CleanupExit; } if (!(buffer = ExAllocatePoolWithTag(PagedPool, FILE_BUFFER_SIZE, 'vhpK'))) { status = STATUS_INSUFFICIENT_RESOURCES; goto CleanupExit; } remainingBytes = (ULONG)standardInfo.EndOfFile.QuadPart; while (remainingBytes != 0) { bytesToRead = FILE_BUFFER_SIZE; if (bytesToRead > remainingBytes) bytesToRead = remainingBytes; if (!NT_SUCCESS(status = ZwReadFile(fileHandle, NULL, NULL, NULL, &iosb, buffer, bytesToRead, NULL, NULL))) { goto CleanupExit; } if ((ULONG)iosb.Information != bytesToRead) { status = STATUS_INTERNAL_ERROR; goto CleanupExit; } if (!NT_SUCCESS(status = BCryptHashData(hashHandle, buffer, bytesToRead, 0))) goto CleanupExit; remainingBytes -= bytesToRead; } if (!NT_SUCCESS(status = BCryptFinishHash(hashHandle, hash, hashSize, 0))) goto CleanupExit; if (NT_SUCCESS(status)) { *Hash = hash; *HashSize = hashSize; hash = NULL; // Don't free this in the cleanup section } CleanupExit: if (buffer) ExFreePoolWithTag(buffer, 'vhpK'); if (fileHandle) ZwClose(fileHandle); if (hashHandle) BCryptDestroyHash(hashHandle); if (hash) ExFreePoolWithTag(hash, 'vhpK'); if (hashObject) ExFreePoolWithTag(hashObject, 'vhpK'); if (hashAlgHandle) BCryptCloseAlgorithmProvider(hashAlgHandle, 0); 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; KernelCodeStepping=0; this_cs=getCS(); this_ss=getSS(); this_ds=getDS(); this_es=getES(); this_fs=getFS(); this_gs=getGS(); 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 CreateBaseAcls(OUT PACL* Dacl, OUT PACL* RestrictedDacl) { PSID SystemSid, WorldSid, RestrictedSid; SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; NTSTATUS Status; #if 0 // Unused code UCHAR KeyValueBuffer[0x40]; PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo; UNICODE_STRING KeyName; ULONG ProtectionMode = 0; #endif ULONG AclLength; #if 0 // Unused code ULONG ResultLength; HANDLE hKey; OBJECT_ATTRIBUTES ObjectAttributes; /* Open the Session Manager Key */ RtlInitUnicodeString(&KeyName, SM_REG_KEY); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes); if (NT_SUCCESS(Status)) { /* Read the key value */ RtlInitUnicodeString(&KeyName, L"ProtectionMode"); Status = NtQueryValueKey(hKey, &KeyName, KeyValuePartialInformation, KeyValueBuffer, sizeof(KeyValueBuffer), &ResultLength); /* Make sure it's what we expect it to be */ KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer; if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) && (*(PULONG)KeyValuePartialInfo->Data)) { /* Save the Protection Mode */ ProtectionMode = *(PULONG)KeyValuePartialInfo->Data; } /* Close the handle */ NtClose(hKey); } #endif /* Allocate the System SID */ Status = RtlAllocateAndInitializeSid(&NtAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &SystemSid); ASSERT(NT_SUCCESS(Status)); /* Allocate the World SID */ Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &WorldSid); ASSERT(NT_SUCCESS(Status)); /* Allocate the restricted SID */ Status = RtlAllocateAndInitializeSid(&NtAuthority, 1, SECURITY_RESTRICTED_CODE_RID, 0, 0, 0, 0, 0, 0, 0, &RestrictedSid); ASSERT(NT_SUCCESS(Status)); /* Allocate one ACL with 3 ACEs each for one SID */ AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SystemSid) + RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid); *Dacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength); ASSERT(*Dacl != NULL); /* Set the correct header fields */ Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2); ASSERT(NT_SUCCESS(Status)); /* Give the appropriate rights to each SID */ /* FIXME: Should check SessionId/ProtectionMode */ Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid); ASSERT(NT_SUCCESS(Status)); Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid); ASSERT(NT_SUCCESS(Status)); Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid); ASSERT(NT_SUCCESS(Status)); /* Now allocate the restricted DACL */ *RestrictedDacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength); ASSERT(*RestrictedDacl != NULL); /* Initialize it */ Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2); ASSERT(NT_SUCCESS(Status)); /* And add the same ACEs as before */ /* FIXME: Not really fully correct */ Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid); ASSERT(NT_SUCCESS(Status)); Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid); ASSERT(NT_SUCCESS(Status)); Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid); ASSERT(NT_SUCCESS(Status)); /* The SIDs are captured, can free them now */ RtlFreeSid(RestrictedSid); RtlFreeSid(WorldSid); RtlFreeSid(SystemSid); return Status; }
BOOLEAN SampUpgradeFlagSet( ) /*++ Routine Description: This routine checks if the SAM upgrade flag is set. The upgrade flag is: HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\lsa UpgradeSam = REG_DWORD 1 Arguments: Return Value: TRUE - The flag was set FALSE - The flag was not set or the value was not present --*/ { NTSTATUS NtStatus; UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE KeyHandle; UCHAR Buffer[100]; PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION) Buffer; ULONG KeyValueLength = 100; ULONG ResultLength; PULONG UpgradeFlag; // // Open the Lsa key in the registry // RtlInitUnicodeString( &KeyName, SAMP_LSA_KEY_NAME ); InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, 0, NULL ); NtStatus = NtOpenKey( &KeyHandle, KEY_READ, &ObjectAttributes ); if (!NT_SUCCESS(NtStatus)) { return(FALSE); } // // Query the Notification Packages value // RtlInitUnicodeString( &KeyName, L"UpgradeSam" ); NtStatus = NtQueryValueKey( KeyHandle, &KeyName, KeyValuePartialInformation, KeyValueInformation, KeyValueLength, &ResultLength ); NtClose(KeyHandle); if (!NT_SUCCESS(NtStatus)) { return(FALSE); } // // Check that the data is the correct size and type - a ULONG. // if ((KeyValueInformation->DataLength < sizeof(ULONG)) || (KeyValueInformation->Type != REG_DWORD)) { return(FALSE); } // // Check the flag. // UpgradeFlag = (PULONG) KeyValueInformation->Data; if (*UpgradeFlag == 1) { return(TRUE); } return(FALSE); }