binhive.c
来自「一个类似windows」· C语言 代码 · 共 1,660 行 · 第 1/3 页
C
1,660 行
static BOOL
CmiExportSubKey (PREGISTRY_HIVE Hive,
BLOCK_OFFSET ParentKeyOffset,
FRLDRHKEY ParentKey,
FRLDRHKEY Key)
{
BLOCK_OFFSET NKBOffset;
PKEY_CELL 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(KEY_CELL) + NameSize;
if (!CmiAllocateCell (Hive, KeyCellSize, (PVOID)&NewKeyCell, &NKBOffset))
{
DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
return FALSE;
}
/* Initialize key cell */
NewKeyCell->Id = REG_KEY_CELL_ID;
NewKeyCell->Flags = 0;
NewKeyCell->LastWriteTime = 0ULL;
NewKeyCell->ParentKeyOffset = ParentKeyOffset;
NewKeyCell->NumberOfSubKeys = 0;
NewKeyCell->HashTableOffset = -1;
NewKeyCell->NumberOfValues = 0;
NewKeyCell->ValueListOffset = -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,
ParentKeyOffset,
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->ValueListOffset,
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->HashTableOffset,
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;
}
}
return TRUE;
}
static VOID
CmiCalcHiveChecksum (PREGISTRY_HIVE Hive)
{
ULONG *Buffer;
ULONG Sum;
ULONG i;
Buffer = (ULONG*)Hive->HiveHeader;
Sum = 0;
for (i = 0; i < 127; i++)
Sum += Buffer[i];
Hive->HiveHeader->Checksum = Sum;
}
static BOOL
CmiExportHive (PREGISTRY_HIVE Hive,
PCWSTR KeyName)
{
PKEY_CELL KeyCell;
FRLDRHKEY Key;
ULONG SubKeyCount;
ULONG ValueCount;
PLIST_ENTRY Entry;
FRLDRHKEY SubKey;
PVALUE Value;
DbgPrint((DPRINT_REGISTRY, "CmiExportHive(%x, '%S') called\n", Hive, KeyName));
if (RegOpenKey (NULL, KeyName, &Key) != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegOpenKey() failed\n"));
return FALSE;
}
KeyCell = CmiGetCell (Hive, Hive->HiveHeader->RootKeyOffset);
if (KeyCell == NULL)
{
DbgPrint((DPRINT_REGISTRY, "CmiGetBlock() failed\n"));
return FALSE;
}
ValueCount = RegGetValueCount (Key);
DbgPrint((DPRINT_REGISTRY, "ValueCount: %u\n", ValueCount));
if (ValueCount > 0)
{
/* Allocate value list cell */
if (!CmiAllocateValueListCell (Hive,
&KeyCell->ValueListOffset,
ValueCount))
{
DbgPrint((DPRINT_REGISTRY, "CmiAllocateValueListCell() failed\n"));
return FALSE;
}
if (Key->DataSize != 0)
{
if (!CmiExportValue (Hive, Hive->HiveHeader->RootKeyOffset, Key, NULL))
return FALSE;
}
/* Enumerate values */
Entry = Key->ValueList.Flink;
while (Entry != &Key->ValueList)
{
Value = CONTAINING_RECORD(Entry,
VALUE,
ValueList);
if (!CmiExportValue (Hive, Hive->HiveHeader->RootKeyOffset, 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,
&KeyCell->HashTableOffset,
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, Hive->HiveHeader->RootKeyOffset, Key, SubKey))
return FALSE;
Entry = Entry->Flink;
}
}
CmiCalcHiveChecksum (Hive);
return TRUE;
}
static BOOL
RegImportValue (PHBIN RootBin,
PVALUE_CELL ValueCell,
FRLDRHKEY Key)
{
PDATA_CELL DataCell;
PWCHAR wName;
LONG Error;
ULONG DataSize;
ULONG i;
if (ValueCell->CellSize >= 0 || ValueCell->Id != REG_VALUE_CELL_ID)
{
DbgPrint((DPRINT_REGISTRY, "Invalid key cell!\n"));
return FALSE;
}
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
wName = MmAllocateMemory ((ValueCell->NameSize + 1)*sizeof(WCHAR));
for (i = 0; i < ValueCell->NameSize; i++)
{
wName[i] = ((PCHAR)ValueCell->Name)[i];
}
wName[ValueCell->NameSize] = 0;
}
else
{
wName = MmAllocateMemory (ValueCell->NameSize + sizeof(WCHAR));
memcpy (wName,
ValueCell->Name,
ValueCell->NameSize);
wName[ValueCell->NameSize / sizeof(WCHAR)] = 0;
}
DataSize = ValueCell->DataSize & REG_DATA_SIZE_MASK;
DbgPrint((DPRINT_REGISTRY, "ValueName: '%S'\n", wName));
DbgPrint((DPRINT_REGISTRY, "DataSize: %u\n", DataSize));
if (DataSize <= sizeof(BLOCK_OFFSET) && (ValueCell->DataSize & REG_DATA_IN_OFFSET))
{
Error = RegSetValue(Key,
wName,
ValueCell->DataType,
(PCHAR)&ValueCell->DataOffset,
DataSize);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegSetValue() failed!\n"));
MmFreeMemory (wName);
return FALSE;
}
}
else
{
DataCell = (PDATA_CELL)((PUCHAR)RootBin + ValueCell->DataOffset);
DbgPrint((DPRINT_REGISTRY, "DataCell: %x\n", DataCell));
if (DataCell->CellSize >= 0)
{
DbgPrint((DPRINT_REGISTRY, "Invalid data cell size!\n"));
MmFreeMemory (wName);
return FALSE;
}
Error = RegSetValue (Key,
wName,
ValueCell->DataType,
DataCell->Data,
DataSize);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegSetValue() failed!\n"));
MmFreeMemory (wName);
return FALSE;
}
}
MmFreeMemory (wName);
return TRUE;
}
static BOOL
RegImportSubKey(PHBIN RootBin,
PKEY_CELL KeyCell,
FRLDRHKEY ParentKey)
{
PHASH_TABLE_CELL HashCell;
PKEY_CELL SubKeyCell;
PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL ValueCell = NULL;
PWCHAR wName;
FRLDRHKEY SubKey;
LONG Error;
ULONG i;
DbgPrint((DPRINT_REGISTRY, "KeyCell: %x\n", KeyCell));
DbgPrint((DPRINT_REGISTRY, "KeyCell->CellSize: %x\n", KeyCell->CellSize));
DbgPrint((DPRINT_REGISTRY, "KeyCell->Id: %x\n", KeyCell->Id));
if (KeyCell->Id != REG_KEY_CELL_ID || KeyCell->CellSize >= 0)
{
DbgPrint((DPRINT_REGISTRY, "Invalid key cell id!\n"));
return FALSE;
}
if (KeyCell->Flags & REG_KEY_NAME_PACKED)
{
wName = MmAllocateMemory ((KeyCell->NameSize + 1) * sizeof(WCHAR));
for (i = 0; i < KeyCell->NameSize; i++)
{
wName[i] = ((PCHAR)KeyCell->Name)[i];
}
wName[KeyCell->NameSize] = 0;
}
else
{
wName = MmAllocateMemory (KeyCell->NameSize + sizeof(WCHAR));
memcpy (wName,
KeyCell->Name,
KeyCell->NameSize);
wName[KeyCell->NameSize/sizeof(WCHAR)] = 0;
}
DbgPrint((DPRINT_REGISTRY, "KeyName: '%S'\n", wName));
/* Create new sub key */
Error = RegCreateKey (ParentKey,
wName,
&SubKey);
MmFreeMemory (wName);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegCreateKey() failed!\n"));
return FALSE;
}
DbgPrint((DPRINT_REGISTRY, "Subkeys: %u\n", KeyCell->NumberOfSubKeys));
DbgPrint((DPRINT_REGISTRY, "Values: %u\n", KeyCell->NumberOfValues));
/* Enumerate and add values */
if (KeyCell->NumberOfValues > 0)
{
ValueListCell = (PVALUE_LIST_CELL)((PUCHAR)RootBin + KeyCell->ValueListOffset);
DbgPrint((DPRINT_REGISTRY, "ValueListCell: %x\n", ValueListCell));
for (i = 0; i < KeyCell->NumberOfValues; i++)
{
DbgPrint((DPRINT_REGISTRY, "ValueOffset[%d]: %x\n", i, ValueListCell->ValueOffset[i]));
ValueCell = (PVALUE_CELL)((PUCHAR)RootBin + ValueListCell->ValueOffset[i]);
DbgPrint((DPRINT_REGISTRY, "ValueCell[%d]: %x\n", i, ValueCell));
if (!RegImportValue(RootBin, ValueCell, SubKey))
return FALSE;
}
}
/* Enumerate and add subkeys */
if (KeyCell->NumberOfSubKeys > 0)
{
HashCell = (PHASH_TABLE_CELL)((PUCHAR)RootBin + KeyCell->HashTableOffset);
DbgPrint((DPRINT_REGISTRY, "HashCell: %x\n", HashCell));
for (i = 0; i < KeyCell->NumberOfSubKeys; i++)
{
DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset));
SubKeyCell = (PKEY_CELL)((PUCHAR)RootBin + HashCell->Table[i].KeyOffset);
DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell));
if (!RegImportSubKey(RootBin, SubKeyCell, SubKey))
return FALSE;
}
}
return TRUE;
}
BOOL
RegImportBinaryHive(PCHAR ChunkBase,
ULONG ChunkSize)
{
PHIVE_HEADER HiveHeader;
PHBIN RootBin;
PKEY_CELL KeyCell;
PHASH_TABLE_CELL HashCell;
PKEY_CELL SubKeyCell;
FRLDRHKEY SystemKey;
ULONG i;
LONG Error;
DbgPrint((DPRINT_REGISTRY, "RegImportBinaryHive(%x, %u) called\n",ChunkBase,ChunkSize));
HiveHeader = (PHIVE_HEADER)ChunkBase;
DbgPrint((DPRINT_REGISTRY, "HiveHeader: %x\n", HiveHeader));
if (HiveHeader->BlockId != REG_HIVE_ID)
{
DbgPrint((DPRINT_REGISTRY, "Invalid hive id!\n"));
return FALSE;
}
RootBin = (PHBIN)((ULONG)HiveHeader + REG_BLOCK_SIZE);
DbgPrint((DPRINT_REGISTRY, "RootBin: %x\n", RootBin));
if (RootBin->HeaderId != REG_BIN_ID || RootBin->BinSize == 0)
{
DbgPrint((DPRINT_REGISTRY, "Invalid bin id!\n"));
return FALSE;
}
KeyCell = (PKEY_CELL)((ULONG)RootBin + REG_HBIN_DATA_OFFSET);
DbgPrint((DPRINT_REGISTRY, "KeyCell: %x\n", KeyCell));
DbgPrint((DPRINT_REGISTRY, "KeyCell->CellSize: %x\n", KeyCell->CellSize));
DbgPrint((DPRINT_REGISTRY, "KeyCell->Id: %x\n", KeyCell->Id));
if (KeyCell->Id != REG_KEY_CELL_ID || KeyCell->CellSize >= 0)
{
DbgPrint((DPRINT_REGISTRY, "Invalid key cell id!\n"));
return FALSE;
}
DbgPrint((DPRINT_REGISTRY, "Subkeys: %u\n", KeyCell->NumberOfSubKeys));
DbgPrint((DPRINT_REGISTRY, "Values: %u\n", KeyCell->NumberOfValues));
/* Open 'System' key */
Error = RegOpenKey(NULL,
L"\\Registry\\Machine\\SYSTEM",
&SystemKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "Failed to open 'system' key!\n"));
return FALSE;
}
/* Enumerate and add subkeys */
if (KeyCell->NumberOfSubKeys > 0)
{
HashCell = (PHASH_TABLE_CELL)((ULONG)RootBin + KeyCell->HashTableOffset);
DbgPrint((DPRINT_REGISTRY, "HashCell: %x\n", HashCell));
for (i = 0; i < KeyCell->NumberOfSubKeys; i++)
{
DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset));
SubKeyCell = (PKEY_CELL)((ULONG)RootBin + HashCell->Table[i].KeyOffset);
DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell));
if (!RegImportSubKey(RootBin, SubKeyCell, SystemKey))
return FALSE;
}
}
return TRUE;
}
BOOL
RegExportBinaryHive(PCWSTR KeyName,
PCHAR ChunkBase,
ULONG* ChunkSize)
{
PREGISTRY_HIVE Hive;
DbgPrint((DPRINT_REGISTRY, "Creating binary hardware hive\n"));
*ChunkSize = 0;
InitMbMemory (ChunkBase);
Hive = CmiCreateHive (KeyName);
if (Hive == NULL)
return FALSE;
if (!CmiExportHive (Hive, KeyName))
{
CmiCleanupHive (Hive, TRUE);
return FALSE;
}
CmiCleanupHive (Hive, FALSE);
*ChunkSize = GetMbAllocatedSize ();
return TRUE;
}
/* EOF */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?