📄 binhive.c
字号:
/*
* FreeLoader
*
* Copyright (C) 2001 Rex Jolliff
* Copyright (C) 2001 Eric Kohl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
#include <cmlib.h>
#include <debug.h>
/* FUNCTIONS ****************************************************************/
static PVOID
NTAPI
CmpAllocate (SIZE_T Size, BOOLEAN Paged)
{
return MmAllocateMemory(Size);
}
static VOID
NTAPI
CmpFree (PVOID Ptr)
{
return MmFreeMemory(Ptr);
}
static BOOLEAN
CmiAllocateHashTableCell (PHHIVE Hive,
PHCELL_INDEX HBOffset,
ULONG SubKeyCount)
{
PHASH_TABLE_CELL HashCell;
ULONG NewHashSize;
NewHashSize = sizeof(HASH_TABLE_CELL) +
(SubKeyCount * sizeof(HASH_RECORD));
*HBOffset = HvAllocateCell (Hive, NewHashSize, HvStable);
if (*HBOffset == HCELL_NULL)
{
return FALSE;
}
HashCell = HvGetCell (Hive, *HBOffset);
HashCell->Id = REG_HASH_TABLE_CELL_ID;
HashCell->HashTableSize = SubKeyCount;
return TRUE;
}
static BOOLEAN
CmiAddKeyToParentHashTable (PHHIVE Hive,
HCELL_INDEX Parent,
PCM_KEY_NODE NewKeyCell,
HCELL_INDEX NKBOffset)
{
PHASH_TABLE_CELL HashBlock;
PCM_KEY_NODE ParentKeyCell;
ULONG i;
ParentKeyCell = HvGetCell (Hive, Parent);
HashBlock = HvGetCell (Hive, ParentKeyCell->SubKeyLists[HvStable]);
for (i = 0; i < HashBlock->HashTableSize; i++)
{
if (HashBlock->Table[i].KeyOffset == 0)
{
HashBlock->Table[i].KeyOffset = NKBOffset;
memcpy (&HashBlock->Table[i].HashValue,
NewKeyCell->Name,
min(NewKeyCell->NameSize, sizeof(ULONG)));
ParentKeyCell->SubKeyCounts[HvStable]++;
return TRUE;
}
}
return FALSE;
}
static BOOLEAN
CmiAllocateValueListCell (PHHIVE Hive,
PHCELL_INDEX ValueListOffset,
ULONG ValueCount)
{
ULONG ValueListSize;
ValueListSize = sizeof(VALUE_LIST_CELL) +
(ValueCount * sizeof(HCELL_INDEX));
*ValueListOffset = HvAllocateCell (Hive, ValueListSize, HvStable);
if (*ValueListOffset == HCELL_NULL)
{
DbgPrint((DPRINT_REGISTRY, "HvAllocateCell() failed\n"));
return FALSE;
}
return TRUE;
}
static BOOLEAN
CmiAllocateValueCell(PHHIVE Hive,
PCM_KEY_VALUE *ValueCell,
HCELL_INDEX *ValueCellOffset,
PWCHAR ValueName)
{
PCM_KEY_VALUE NewValueCell;
ULONG NameSize;
BOOLEAN Packable = TRUE;
ULONG i;
NameSize = (ValueName == NULL) ? 0 : wcslen (ValueName);
for (i = 0; i < NameSize; i++)
{
if (ValueName[i] & 0xFF00)
{
NameSize *= sizeof(WCHAR);
Packable = FALSE;
break;
}
}
*ValueCellOffset = HvAllocateCell (Hive, sizeof(CM_KEY_VALUE) + NameSize, HvStable);
if (*ValueCellOffset == HCELL_NULL)
{
DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
return FALSE;
}
NewValueCell = (PCM_KEY_VALUE) HvGetCell (Hive, *ValueCellOffset);
NewValueCell->Id = REG_VALUE_CELL_ID;
NewValueCell->NameSize = NameSize;
NewValueCell->Flags = 0;
if (NameSize > 0)
{
if (Packable)
{
for (i = 0; i < NameSize; i++)
{
((PCHAR)NewValueCell->Name)[i] = (CHAR)ValueName[i];
}
NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
}
else
{
memcpy (NewValueCell->Name,
ValueName,
NameSize);
}
}
NewValueCell->DataType = 0;
NewValueCell->DataSize = 0;
NewValueCell->DataOffset = -1;
*ValueCell = NewValueCell;
return TRUE;
}
static BOOLEAN
CmiAddValueToKeyValueList(PHHIVE Hive,
HCELL_INDEX KeyCellOffset,
HCELL_INDEX ValueCellOffset)
{
PVALUE_LIST_CELL ValueListCell;
PCM_KEY_NODE KeyCell;
KeyCell = HvGetCell (Hive, KeyCellOffset);
if (KeyCell == NULL)
{
DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n"));
return FALSE;
}
ValueListCell = HvGetCell (Hive, KeyCell->ValueList.List);
if (ValueListCell == NULL)
{
DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n"));
return FALSE;
}
ValueListCell->ValueOffset[KeyCell->ValueList.Count] = ValueCellOffset;
KeyCell->ValueList.Count++;
return TRUE;
}
static BOOLEAN
CmiExportValue (PHHIVE Hive,
HCELL_INDEX KeyCellOffset,
FRLDRHKEY Key,
PVALUE Value)
{
HCELL_INDEX ValueCellOffset;
HCELL_INDEX DataCellOffset;
PCM_KEY_VALUE ValueCell;
PVOID DataCell;
ULONG DataSize;
ULONG DataType;
PCHAR Data;
DbgPrint((DPRINT_REGISTRY, "CmiExportValue('%S') called\n",
(Value == NULL) ? "<default>" : (PCHAR)Value->Name));
DbgPrint((DPRINT_REGISTRY, "DataSize %lu\n",
(Value == NULL) ? Key->DataSize : Value->DataSize));
/* Allocate value cell */
if (!CmiAllocateValueCell(Hive, &ValueCell, &ValueCellOffset, (Value == NULL) ? NULL : Value->Name))
{
return FALSE;
}
if (!CmiAddValueToKeyValueList(Hive, KeyCellOffset, ValueCellOffset))
{
return FALSE;
}
if (Value == NULL)
{
DataType = Key->DataType;
DataSize = Key->DataSize;
Data = Key->Data;
}
else
{
DataType = Value->DataType;
DataSize = Value->DataSize;
Data = Value->Data;
}
if (DataSize <= sizeof(HCELL_INDEX))
{
ValueCell->DataSize = DataSize | REG_DATA_IN_OFFSET;
ValueCell->DataType = DataType;
memcpy (&ValueCell->DataOffset,
&Data,
DataSize);
}
else
{
/* Allocate data cell */
DataCellOffset = HvAllocateCell (Hive, DataSize, HvStable);
if (DataCellOffset == HCELL_NULL)
{
return FALSE;
}
ValueCell->DataOffset = DataCellOffset;
ValueCell->DataSize = DataSize;
ValueCell->DataType = DataType;
DataCell = HvGetCell (Hive, DataCellOffset);
memcpy (DataCell,
Data,
DataSize);
}
return TRUE;
}
static BOOLEAN
CmiExportSubKey (PHHIVE Hive,
HCELL_INDEX Parent,
FRLDRHKEY ParentKey,
FRLDRHKEY Key)
{
HCELL_INDEX NKBOffset;
PCM_KEY_NODE NewKeyCell;
ULONG KeyCellSize;
ULONG SubKeyCount;
ULONG ValueCount;
PLIST_ENTRY Entry;
FRLDRHKEY SubKey;
PVALUE Value;
BOOLEAN Packable = TRUE;
ULONG i;
ULONG NameSize;
DbgPrint((DPRINT_REGISTRY, "CmiExportSubKey('%S') called\n", Key->Name));
/* Don't export links */
if (Key->DataType == REG_LINK)
return TRUE;
NameSize = (Key->NameSize - sizeof(WCHAR)) / sizeof(WCHAR);
for (i = 0; i < NameSize; i++)
{
if (Key->Name[i] & 0xFF00)
{
Packable = FALSE;
NameSize *= sizeof(WCHAR);
break;
}
}
/* Allocate key cell */
KeyCellSize = sizeof(CM_KEY_NODE) + NameSize;
NKBOffset = HvAllocateCell (Hive, KeyCellSize, HvStable);
if (NKBOffset == HCELL_NULL)
{
DbgPrint((DPRINT_REGISTRY, "HvAllocateCell() failed\n"));
return FALSE;
}
/* Initialize key cell */
NewKeyCell = (PCM_KEY_NODE) HvGetCell (Hive, NKBOffset);
NewKeyCell->Id = REG_KEY_CELL_ID;
NewKeyCell->Flags = 0;
NewKeyCell->LastWriteTime.QuadPart = 0ULL;
NewKeyCell->Parent = Parent;
NewKeyCell->SubKeyCounts[HvStable] = 0;
NewKeyCell->SubKeyLists[HvStable] = -1;
NewKeyCell->ValueList.Count = 0;
NewKeyCell->ValueList.List = -1;
NewKeyCell->SecurityKeyOffset = -1;
NewKeyCell->ClassNameOffset = -1;
NewKeyCell->NameSize = NameSize;
NewKeyCell->ClassSize = 0;
if (Packable)
{
for (i = 0; i < NameSize; i++)
{
((PCHAR)NewKeyCell->Name)[i] = (CHAR)Key->Name[i];
}
NewKeyCell->Flags |= REG_KEY_NAME_PACKED;
}
else
{
memcpy (NewKeyCell->Name,
Key->Name,
NameSize);
}
/* Add key cell to the parent key's hash table */
if (!CmiAddKeyToParentHashTable (Hive,
Parent,
NewKeyCell,
NKBOffset))
{
DbgPrint((DPRINT_REGISTRY, "CmiAddKeyToParentHashTable() failed\n"));
return FALSE;
}
ValueCount = RegGetValueCount (Key);
DbgPrint((DPRINT_REGISTRY, "ValueCount: %u\n", ValueCount));
if (ValueCount > 0)
{
/* Allocate value list cell */
if (!CmiAllocateValueListCell (Hive,
&NewKeyCell->ValueList.List,
ValueCount))
{
DbgPrint((DPRINT_REGISTRY, "CmiAllocateValueListCell() failed\n"));
return FALSE;
}
if (Key->DataSize != 0)
{
if (!CmiExportValue (Hive, NKBOffset, Key, NULL))
return FALSE;
}
/* Enumerate values */
Entry = Key->ValueList.Flink;
while (Entry != &Key->ValueList)
{
Value = CONTAINING_RECORD(Entry,
VALUE,
ValueList);
if (!CmiExportValue (Hive, NKBOffset, Key, Value))
return FALSE;
Entry = Entry->Flink;
}
}
SubKeyCount = RegGetSubKeyCount (Key);
DbgPrint((DPRINT_REGISTRY, "SubKeyCount: %u\n", SubKeyCount));
if (SubKeyCount > 0)
{
/* Allocate hash table cell */
if (!CmiAllocateHashTableCell (Hive,
&NewKeyCell->SubKeyLists[HvStable],
SubKeyCount))
{
DbgPrint((DPRINT_REGISTRY, "CmiAllocateHashTableCell() failed\n"));
return FALSE;
}
/* Enumerate subkeys */
Entry = Key->SubKeyList.Flink;
while (Entry != &Key->SubKeyList)
{
SubKey = CONTAINING_RECORD(Entry,
KEY,
KeyList);
if (!CmiExportSubKey (Hive, NKBOffset, Key, SubKey))
return FALSE;
Entry = Entry->Flink;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -