Esempio n. 1
0
NTSTATUS
CmiInitializeTempHive(
	IN OUT PCMHIVE Hive)
{
	NTSTATUS Status;

	RtlZeroMemory (
		Hive,
		sizeof(CMHIVE));

	DPRINT("Hive 0x%p\n", Hive);

	Status = HvInitialize(&Hive->Hive,
                          HINIT_CREATE,
                          0,
                          0,
                          0,
                          CmpAllocate,
                          CmpFree,
                          CmpFileSetSize,
                          CmpFileWrite,
                          CmpFileRead,
                          CmpFileFlush,
                          1,
                          NULL);
	if (!NT_SUCCESS(Status))
	{
		return Status;
	}

	if (!CmCreateRootNode (&Hive->Hive, L""))
	{
		HvFree (&Hive->Hive);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	Hive->Flags = HIVE_NO_FILE;

	/* Add the new hive to the hive list */
	InsertTailList (
		&CmiHiveListHead,
		&Hive->HiveList);

	VERIFY_REGISTRY_HIVE (Hive);

	return STATUS_SUCCESS;
}
Esempio n. 2
0
NTSTATUS
BiInitializeAndValidateHive (
    _In_ PBI_KEY_HIVE Hive
    )
{
    ULONG HiveSize;
    NTSTATUS Status;

    /* Make sure the hive is at least the size of a base block */
    if (Hive->HiveSize < sizeof(HBASE_BLOCK))
    {
        return STATUS_REGISTRY_CORRUPT;
    }

    /* Make sure that the base block accurately describes the size of the hive */
    HiveSize = Hive->BaseBlock->Length + sizeof(HBASE_BLOCK);
    if ((HiveSize < sizeof(HBASE_BLOCK)) || (HiveSize > Hive->HiveSize))
    {
        return STATUS_REGISTRY_CORRUPT;
    }

    /* Initialize a flat memory hive */
    RtlZeroMemory(&Hive->Hive, sizeof(Hive->Hive));
    Status = HvInitialize(&Hive->Hive.Hive,
                          HINIT_FLAT,
                          0,
                          0,
                          Hive->BaseBlock,
                          CmpAllocate,
                          CmpFree,
                          NULL,
                          NULL,
                          NULL,
                          NULL,
                          0,
                          NULL);
    if (NT_SUCCESS(Status))
    {
        /* Cleanup volatile/old data */
        CmPrepareHive(&Hive->Hive.Hive); // CmCheckRegistry 
        Status = STATUS_SUCCESS;
    }

    /* Return the final status */
    return Status;
}
Esempio n. 3
0
NTSTATUS
NTAPI
CmpInitializeHive(OUT PCMHIVE *RegistryHive,
                  IN ULONG OperationType,
                  IN ULONG HiveFlags,
                  IN ULONG FileType,
                  IN PVOID HiveData OPTIONAL,
                  IN HANDLE Primary,
                  IN HANDLE Log,
                  IN HANDLE External,
                  IN PCUNICODE_STRING FileName OPTIONAL,
                  IN ULONG CheckFlags)
{
    PCMHIVE Hive;
    FILE_STANDARD_INFORMATION FileInformation;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_FS_SIZE_INFORMATION FileSizeInformation;
    NTSTATUS Status;
    ULONG Cluster;

    /* Assume failure */
    *RegistryHive = NULL;

    /*
     * The following are invalid:
     * An external hive that is also internal.
     * A log hive that's not a primary hive too.
     * A volatile hive that's linked to permanent storage.
     * An in-memory initialization without hive data.
     * A log hive that's not linked to a correct file type.
     */
    if (((External) && ((Primary) || (Log))) ||
        ((Log) && !(Primary)) ||
        ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) ||
        ((OperationType == HINIT_MEMORY) && (!HiveData)) ||
        ((Log) && (FileType != HFILE_TYPE_LOG)))
    {
        /* Fail the request */
        return STATUS_INVALID_PARAMETER;
    }

    /* Check if this is a primary hive */
    if (Primary)
    {
        /* Get the cluster size */
        Status = ZwQueryVolumeInformationFile(Primary,
                                              &IoStatusBlock,
                                              &FileSizeInformation,
                                              sizeof(FILE_FS_SIZE_INFORMATION),
                                              FileFsSizeInformation);
        if (!NT_SUCCESS(Status)) return Status;

        /* Make sure it's not larger then the block size */
        if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE)
        {
            /* Fail */
            return STATUS_REGISTRY_IO_FAILED;
        }

        /* Otherwise, calculate the cluster */
        Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE;
        Cluster = max(1, Cluster);
    }
    else
    {
        /* Otherwise use cluster 1 */
        Cluster = 1;
    }

    /* Allocate the hive */
    Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(CMHIVE), TAG_CMHIVE);
    if (!Hive) return STATUS_INSUFFICIENT_RESOURCES;

    /* Setup null fields */
    Hive->UnloadEvent = NULL;
    Hive->RootKcb = NULL;
    Hive->Frozen = FALSE;
    Hive->UnloadWorkItem = NULL;
    Hive->GrowOnlyMode = FALSE;
    Hive->GrowOffset = 0;
    Hive->CellRemapArray = NULL;
    Hive->UseCountLog.Next = 0;
    Hive->LockHiveLog.Next = 0;
    Hive->FileObject = NULL;
    Hive->NotifyList.Flink = NULL;
    Hive->NotifyList.Blink = NULL;

    /* Set loading flag */
    Hive->HiveIsLoading = TRUE;

    /* Set the current thread as creator */
    Hive->CreatorOwner = KeGetCurrentThread();

    /* Initialize lists */
    InitializeListHead(&Hive->KcbConvertListHead);
    InitializeListHead(&Hive->KnodeConvertListHead);
    InitializeListHead(&Hive->TrustClassEntry);

    /* Allocate the view log */
    Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool,
                                           sizeof(KGUARDED_MUTEX),
                                           TAG_CMHIVE);
    if (!Hive->ViewLock)
    {
        /* Cleanup allocation and fail */
        ExFreePoolWithTag(Hive, TAG_CMHIVE);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Allocate the flush lock */
    Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool,
                                              sizeof(ERESOURCE),
                                              TAG_CMHIVE);
    if (!Hive->FlusherLock)
    {
        /* Cleanup allocations and fail */
        ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
        ExFreePoolWithTag(Hive, TAG_CMHIVE);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Setup the handles */
    Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary;
    Hive->FileHandles[HFILE_TYPE_LOG] = Log;
    Hive->FileHandles[HFILE_TYPE_EXTERNAL] = External;

    /* Initailize the guarded mutex */
    KeInitializeGuardedMutex(Hive->ViewLock);
    Hive->ViewLockOwner = NULL;

    /* Initialize the flush lock */
    ExInitializeResourceLite(Hive->FlusherLock);

    /* Setup hive locks */
    ExInitializePushLock(&Hive->HiveLock);
    Hive->HiveLockOwner = NULL;
    ExInitializePushLock(&Hive->WriterLock);
    Hive->WriterLockOwner = NULL;
    ExInitializePushLock(&Hive->SecurityLock);
    Hive->HiveSecurityLockOwner = NULL;

    /* Clear file names */
    RtlInitEmptyUnicodeString(&Hive->FileUserName, NULL, 0);
    RtlInitEmptyUnicodeString(&Hive->FileFullPath, NULL, 0);

    /* Initialize the view list */
    CmpInitHiveViewList(Hive);

    /* Initailize the security cache */
    CmpInitSecurityCache(Hive);

    /* Setup flags */
    Hive->Flags = 0;
    Hive->FlushCount = 0;

    /* Set flags */
    Hive->Flags = HiveFlags;

    /* Check if this is a primary */
    if (Primary)
    {
        /* Check how large the file is */
        ZwQueryInformationFile(Primary,
                               &IoStatusBlock,
                               &FileInformation,
                               sizeof(FileInformation),
                               FileStandardInformation);
        Cluster = FileInformation.EndOfFile.LowPart;
    }

    /* Initialize it */
    Status = HvInitialize(&Hive->Hive,
                          OperationType,
                          FileType,
                          HiveFlags,
                          HiveData,
                          CmpAllocate,
                          CmpFree,
                          CmpFileSetSize,
                          CmpFileWrite,
                          CmpFileRead,
                          CmpFileFlush,
                          Cluster,
                          FileName);
    if (!NT_SUCCESS(Status))
    {
        /* Cleanup allocations and fail */
        ExDeleteResourceLite(Hive->FlusherLock);
        ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE);
        ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
        ExFreePoolWithTag(Hive, TAG_CMHIVE);
        return Status;
    }

    /* Check if we should verify the registry */
    if ((OperationType == HINIT_FILE) ||
        (OperationType == HINIT_MEMORY) ||
        (OperationType == HINIT_MEMORY_INPLACE) ||
        (OperationType == HINIT_MAPFILE))
    {
        /* Verify integrity */
        ULONG CheckStatus = CmCheckRegistry(Hive, CheckFlags);
        if (CheckStatus != 0)
        {
            /* Cleanup allocations and fail */
            ExDeleteResourceLite(Hive->FlusherLock);
            ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE);
            ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
            ExFreePoolWithTag(Hive, TAG_CMHIVE);
            return STATUS_REGISTRY_CORRUPT;
        }
    }

    /* Lock the hive list */
    ExAcquirePushLockExclusive(&CmpHiveListHeadLock);

    /* Insert this hive */
    InsertHeadList(&CmpHiveListHead, &Hive->HiveList);

    /* Release the lock */
    ExReleasePushLock(&CmpHiveListHeadLock);

    /* Return the hive and success */
    *RegistryHive = (PCMHIVE)Hive;
    return STATUS_SUCCESS;
}
Esempio n. 4
0
BOOLEAN
RegImportBinaryHive(
    PCHAR ChunkBase,
    ULONG ChunkSize)
{
    PCM_KEY_NODE KeyCell;
    PCM_KEY_FAST_INDEX HashCell;
    PCM_KEY_NODE SubKeyCell;
    FRLDRHKEY SystemKey;
    ULONG i;
    LONG Error;
    PCMHIVE CmHive;
    PHHIVE Hive;
    NTSTATUS Status;

    TRACE("RegImportBinaryHive(%x, %u) called\n", ChunkBase, ChunkSize);

    CmHive = CmpAllocate(sizeof(CMHIVE), TRUE, 0);
    Status = HvInitialize(&CmHive->Hive,
                          HINIT_FLAT,
                          0,
                          0,
                          ChunkBase,
                          CmpAllocate,
                          CmpFree,
                          NULL,
                          NULL,
                          NULL,
                          NULL,
                          1,
                          NULL);
    if (!NT_SUCCESS(Status))
    {
        CmpFree(CmHive, 0);
        ERR("Invalid hive Signature!\n");
        return FALSE;
    }

    Hive = &CmHive->Hive;
    KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, Hive->BaseBlock->RootCell);
    TRACE("KeyCell: %x\n", KeyCell);
    TRACE("KeyCell->Signature: %x\n", KeyCell->Signature);
    if (KeyCell->Signature != CM_KEY_NODE_SIGNATURE)
    {
        ERR("Invalid key cell Signature!\n");
        return FALSE;
    }

    TRACE("Subkeys: %u\n", KeyCell->SubKeyCounts);
    TRACE("Values: %u\n", KeyCell->ValueList.Count);

    /* Open 'System' key */
    Error = RegOpenKey(NULL, L"\\Registry\\Machine\\SYSTEM", &SystemKey);
    if (Error != ERROR_SUCCESS)
    {
        ERR("Failed to open 'system' key!\n");
        return FALSE;
    }

    /* Enumerate and add subkeys */
    if (KeyCell->SubKeyCounts[Stable] > 0)
    {
        HashCell = (PCM_KEY_FAST_INDEX)HvGetCell(Hive, KeyCell->SubKeyLists[Stable]);
        TRACE("HashCell: %x\n", HashCell);
        TRACE("SubKeyCounts: %x\n", KeyCell->SubKeyCounts[Stable]);

        for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
        {
            TRACE("Cell[%d]: %x\n", i, HashCell->List[i].Cell);

            SubKeyCell = (PCM_KEY_NODE)HvGetCell(Hive, HashCell->List[i].Cell);

            TRACE("SubKeyCell[%d]: %x\n", i, SubKeyCell);

            if (!RegImportSubKey(Hive, SubKeyCell, SystemKey))
                return FALSE;
        }
    }

    return TRUE;
}