|
|
/*******************************************************************
* * Copyright (c) 1999 Microsoft Corporation * * DESCRIPTION: an extension to dump the contents of registry keys and values * * AUTHOR: * Based on Code by : danielwe (Dan Weisman) * ntsd addition by : kksharma (Kshitiz K. Sharma) * * DATE:4/20/1999 * *******************************************************************/
#ifndef KERNEL
#ifndef Print
#define Print dprintf
#endif
#define OFLAG(l) (1L << ((DWORD)#@l - (DWORD)'a'))
#define LINE_NUMBER 0
#define NUM_ASCII_CHARS 16
#define NUM_HEX_CHARS (NUM_ASCII_CHARS * 3)
#define SPACE 7
#define PB_BUFFER_SIZE (NUM_ASCII_CHARS * 50)
VOID dregHelp() { dprintf("!dreg -[d|w] <keyPath>[![<valueName> | *]] - Dumps registry information\n"); dprintf("!dreg -d ... - Prints binary values as DWORDs\n"); dprintf("!dreg -w ... - Prints binary values as WORDs\n"); dprintf("!dreg <keyPath>!* - Prints all values under <keyPath>\n"); dprintf("!dreg <keyPath> - Prints all subkeys of <keyPath>\n"); dprintf("\n"); dprintf("<keypath> can begin with any of the following:\n"); dprintf("\thklm - HKEY_LOCAL_MACHINE\n"); dprintf("\thkcu - HKEY_CURRENT_USER\n"); dprintf("\thkcr - HKEY_CLASSES_ROOT\n"); dprintf("\thku - HKEY_USERS\n"); dprintf("\tif absent, hklm is assumed\n"); dprintf("\n"); dprintf("Ex:\n"); dprintf("!dreg hkcu\\Software\\Microsoft\n"); dprintf("!dreg System\\CurrentControlSet\\Services\\Tcpip!*\n"); dprintf("!dreg System\\CurrentControlSet\\Services\\Tcpip!Start\n"); }
VOID PrintBinary(PBYTE pbData, DWORD cbData, USHORT uWidth) { CHAR line[80]; INT i; INT ascii = 0; PBYTE temp = pbData; BOOL fDone = FALSE; DWORD cbCount = 0;
CHAR hex_digits[] = "0123456789ABCDEF";
while (!fDone) { DWORD cb;
memset(line, 0x20, sizeof(line)); Print("%04X: ", cbCount); for (ascii = 0,i = LINE_NUMBER, cb = 0; ascii < NUM_ASCII_CHARS; ascii++, temp++) { if ((DWORD)(temp - pbData) >= cbData) { if (cbData < PB_BUFFER_SIZE) { fDone = TRUE; break; } else return; } line[i] = hex_digits[(*temp & 0xF0) >> 4]; line[i + 1] = hex_digits[(*temp & 0x0F)]; cb++; if ((ascii + 1) % uWidth == 0) { line[i + 2] = 0x20; i++; if (uWidth > 1) { line[i + 3] = 0x20; i++; } else if (uWidth == 1 && (!(cb % 4))) { line[i + 3] = 0x20; line[i + 4] = 0x20; i += 2; } } i += 2; line[ascii + NUM_HEX_CHARS + SPACE + LINE_NUMBER] = (isprint(*temp) ? *temp : '.'); cbCount++; }
line[79] = 0; Print("%s\n", line); } }
VOID PrintMultiSz(PBYTE pbData) { LPSTR sz = (LPSTR)pbData; DWORD csz = 0;
while (*sz) { Print("%d: \"%s\"\n", csz, *sz ? sz : "<empty>"); csz++; sz += lstrlenA(sz) + 1; } }
VOID PrintRegistryValue(DWORD dwType, PBYTE pbData, DWORD cbData, USHORT uWidth) { switch (dwType) { case REG_SZ: Print("REG_SZ: \"%s\"\n", *pbData ? pbData : "<empty>"); break;
case REG_EXPAND_SZ: { CHAR szExpanded[MAX_PATH + 1];
Print("REG_EXPAND_SZ: \"%s\"\n", pbData); ExpandEnvironmentStringsA((LPCSTR)pbData, (LPSTR)&szExpanded, MAX_PATH); Print("expanded = \"%s\"\n", szExpanded); break; }
case REG_DWORD: { DWORD dwData = * ((DWORD *)pbData);
Print("REG_DWORD: %lu = 0x%08X\n", dwData, dwData); break; }
case REG_BINARY: { Print("REG_BINARY:\n"); PrintBinary(pbData, cbData, uWidth); break; }
case REG_MULTI_SZ: { Print("REG_MULTI_SZ:\n"); PrintMultiSz(pbData); break; } } }
VOID EnumSubKeys(HKEY hkeyRoot, LPSTR szKey) { HKEY hkey; LONG l; BOOL fFound = FALSE;
l = RegOpenKeyExA(hkeyRoot, szKey, 0, KEY_READ, &hkey); if (ERROR_SUCCESS == l) { FILETIME ft; DWORD cbName; CHAR szName[MAX_PATH + 1]; DWORD dwIndex;
for (dwIndex = 0; l == ERROR_SUCCESS; dwIndex++) { cbName = MAX_PATH; l = RegEnumKeyExA(hkey, dwIndex, szName, &cbName, NULL, NULL, NULL,&ft); if (ERROR_SUCCESS == l) { Print("Subkey: %s\n", szName); fFound = TRUE; } }
RegCloseKey(hkey); } else { Print("Could not open subkey %s. Error (%d).\n", szKey, l); }
if (!fFound) { Print("No subkeys\n"); } }
VOID EnumValues(HKEY hkeyRoot, LPSTR szKey, USHORT uWidth) { HKEY hkey; LONG l; BOOL fFound = FALSE;
l = RegOpenKeyExA(hkeyRoot, szKey, 0, KEY_READ, &hkey); if (ERROR_SUCCESS == l) { DWORD cbMax;
l = RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cbMax, NULL, NULL); if (ERROR_SUCCESS == l) { DWORD cbName; CHAR szName[MAX_PATH + 1]; DWORD dwIndex; PBYTE pbData; DWORD dwType; DWORD cbData;
pbData = (PBYTE)LocalAlloc(LPTR, cbMax);
if (pbData) { for (dwIndex = 0; l == ERROR_SUCCESS; dwIndex++) { cbName = MAX_PATH; cbData = cbMax; l = RegEnumValueA(hkey, dwIndex, szName, &cbName, NULL, &dwType, pbData, &cbData); if (ERROR_SUCCESS == l) { Print("Value: \"%s\" - ", szName); PrintRegistryValue(dwType, pbData, cbData, uWidth); Print("------------------------------------------------------------------------\n"); fFound = TRUE; } }
LocalFree(pbData); } }
RegCloseKey(hkey); } else { Print("Could not open subkey %s. Error (%d).\n", szKey, l); }
if (!fFound) { Print("No values\n"); } }
/************************************************************************\
* Procedure: Idreg * * Description: Dumps registry value * * Returns: fSuccess * * 4/14/1999 Created DanielWe * \************************************************************************/ BOOL Idreg( DWORD opts, LPCSTR InString) { LONG l; HKEY hkey; DWORD cbData = 0; DWORD dwType; LPBYTE pbData = NULL; LPSTR szKey = NULL; LPSTR szValue = NULL; CHAR String[512]; LPTSTR lpas = String; LPTSTR lpasOrig = String; HKEY hkeyRoot;
strcpy(String, InString);
// Eat leading spaces first
while (*lpas && *lpas == ' ') { lpas++; }
while (*lpas && *lpas != '\\') { lpas++; }
if (!*lpas) { // Corner case.. no backslash at all. Assume HKLM and start over
hkeyRoot = HKEY_LOCAL_MACHINE; lpas = lpasOrig; } else { // Figure out which hive they want to open
*lpas = 0; if (!lstrcmpiA(lpasOrig, "hkcu")) { hkeyRoot = HKEY_CURRENT_USER; lpas++; } else if (!lstrcmpiA(lpasOrig, "hklm")) { hkeyRoot = HKEY_LOCAL_MACHINE; lpas++; } else if (!lstrcmpiA(lpasOrig, "hku")) { hkeyRoot = HKEY_USERS; lpas++; } else if (!lstrcmpiA(lpasOrig, "hkcr")) { hkeyRoot = HKEY_CLASSES_ROOT; lpas++; } else if (!lstrcmpiA(lpasOrig, "help")) { dregHelp(); return FALSE; } else { hkeyRoot = HKEY_LOCAL_MACHINE;
// Restore the backslash because we assume if they don't use these
// keywords, then they want HKLM
*lpas = '\\'; lpas = lpasOrig; } }
szKey = (LPSTR)lpas;
while (*lpas && *lpas != '!') { lpas++; }
if (*lpas) { // Null terminate the !
*lpas++ = 0;
// mark beginning of new string
szValue = (LPSTR)lpas; }
if (szKey == NULL || *szKey == 0) { Print("Expected subkey name\n"); dregHelp(); return FALSE; } if (szValue == NULL || *szValue == 0) { EnumSubKeys(hkeyRoot, szKey); } else if (!lstrcmpA(szValue, "*")) { EnumValues(hkeyRoot, szKey, (USHORT)opts); } else { l = RegOpenKeyExA(hkeyRoot, (LPCSTR)szKey, 0, KEY_READ, &hkey); if (ERROR_SUCCESS == l) { l = RegQueryValueExA(hkey, (LPCSTR)szValue, NULL, &dwType, NULL, &cbData); if (ERROR_SUCCESS == l) { pbData = (LPBYTE)LocalAlloc(LPTR, cbData); l = RegQueryValueExA(hkey, (LPCSTR)szValue, NULL, &dwType, pbData, &cbData); if (ERROR_SUCCESS == l) { PrintRegistryValue(dwType, pbData, cbData, (USHORT)opts); }
LocalFree(pbData); } else { Print("Could not query value %s!%s. Error (%d).\n", szKey, szValue, l); } RegCloseKey(hkey); } else { Print("Could not open subkey %s. Error (%d).\n", szKey, l); } }
return TRUE; }
#endif // !KERNEL
|