コード例 #1
0
ファイル: RegHooks.cpp プロジェクト: EricSB/ConEmu
bool InitRegistryRoot(CESERVER_CONSOLE_MAPPING_HDR* pInfo)
{
	wchar_t szTitle[64];
	msprintf(szTitle, countof(szTitle), L"ConEmuHk, PID=%u", GetCurrentProcessId());

	if (!ghAdvapi32)
	{
		GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but ghAdvapi32 is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
		return false;
	}

	if (!RegOpenKeyEx_f)
	{
		_ASSERTE(RegOpenKeyEx_f!=NULL);
		RegOpenKeyEx_f = (RegOpenKeyEx_t)GetProcAddress(ghAdvapi32, "RegOpenKeyExW");
		if (!RegOpenKeyEx_f)
		{
			GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegOpenKeyExW) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
			return false;
		}
	}
	if (!RegCreateKeyEx_f)
	{
		_ASSERTE(RegCreateKeyEx_f!=NULL);
		RegCreateKeyEx_f = (RegCreateKeyEx_t)GetProcAddress(ghAdvapi32, "RegCreateKeyExW");
		if (!RegCreateKeyEx_f)
		{
			GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegCreateKeyExW) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
			return false;
		}
	}
	if (!RegCloseKey_f)
	{
		_ASSERTE(RegCloseKey_f!=NULL);
		RegCloseKey_f = (RegCloseKey_t)GetProcAddress(ghAdvapi32, "RegCloseKey");
		if (!RegCloseKey_f)
		{
			GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegCloseKey) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
			return false;
		}
	}

	if (ghNewKeyRoot == NULL)
	{
		//OSVERSIONINFO osv = {sizeof(OSVERSIONINFO)};
		//GetVersionEx(&osv);
		//if (osv.dwMajorVersion >= 6)
		if (!*pInfo->sMountKey)
		{
			// Vista+	
			typedef LONG (WINAPI* RegLoadAppKey_t)(LPCWSTR lpFile, PHKEY phkResult, REGSAM samDesired, DWORD dwOptions, DWORD Reserved);
			RegLoadAppKey_t RegLoadAppKey_f = (RegLoadAppKey_t)GetProcAddress(ghAdvapi32, "RegLoadAppKeyW");
			if (RegLoadAppKey_f)
			{
				LONG lRc = 0;
				if ((lRc = RegLoadAppKey_f(pInfo->sHiveFileName, &ghNewKeyRoot, KEY_ALL_ACCESS, 0, 0)) != 0)
				{
					if ((lRc = RegLoadAppKey_f(pInfo->sHiveFileName, &ghNewKeyRoot, KEY_READ, 0, 0)) != 0)
					{
						wchar_t szDbgMsg[128];
						msprintf(szDbgMsg, countof(szDbgMsg), L"ConEmuHk: RegLoadAppKey failed, code=0x%08X!\n", (DWORD)lRc);
						GuiMessageBox(ghConEmuWnd, szDbgMsg, szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
						ghNewKeyRoot = NULL;
					}
				}
			}
			else
			{
				GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegLoadAppKeyW) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
				ghNewKeyRoot = NULL;
			}				
		}
		else
		{
			// XP Only. т.к. для монтирования хайва требуются права админа
			HKEY hkRoot = pInfo->hMountRoot;
			if (hkRoot == HKEY_CURRENT_USER)
			{
				// Значит это "HKCU\Software\ConEmu Virtual Registry"
				if (RegOpenKeyEx_f(HKEY_CURRENT_USER, VIRTUAL_REGISTRY_ROOT, 0, KEY_ALL_ACCESS, &hkRoot))
				{
					GuiMessageBox(ghConEmuWnd, L"ConEmuHk: RegOpenKeyEx(" VIRTUAL_REGISTRY_ROOT L") failed!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
					ghNewKeyRoot = NULL;
					hkRoot = NULL;
				}
			}
			if (hkRoot && RegOpenKeyEx_f(hkRoot, pInfo->sMountKey, 0, KEY_ALL_ACCESS, &ghNewKeyRoot))
			{
				if (RegOpenKeyEx_f(hkRoot, pInfo->sMountKey, 0, KEY_READ, &ghNewKeyRoot))
				{
					wchar_t szErrMsg[512];
					msprintf(szErrMsg, countof(szErrMsg), 
						L"ConEmuHk: RegOpenKeyEx(0x%X,'%s') failed!\n",
						(DWORD)(LONG)(LONG_PTR)hkRoot, pInfo->sMountKey);
					GuiMessageBox(ghConEmuWnd, szErrMsg, szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
					ghNewKeyRoot = NULL;
				}
			}
		}

		if (!ghNewKeyRoot)
		{
			ghNewKeyRoot = (HKEY)-1;
		}
		else
		{
			LONG lRc = 0;
			LPCWSTR pszKeyName = NULL;
			if (!lRc)
				lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKCU", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKCU, 0);
			if (!lRc)
				lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKCU\\Software", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKCUSoftware, 0);
			if (!lRc)
				lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM32, 0);
			if (!lRc)
				lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM\\Software", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM32Software, 0);
			if (!lRc && IsWindows64())
			{
				// эта ветка не должна выполняться в 32битных ОС
				if (!lRc)
					lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM64", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM64, 0);
				if (!lRc)
					lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM64\\Software", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM64Software, 0);
			}
			if (lRc != 0)
			{
				CloseRootKeys();
				ghNewKeyRoot = (HKEY)-1; // чтобы не пытаться открыть повторно
				wchar_t szErrInfo[MAX_PATH];
				msprintf(szErrInfo, countof(szErrInfo), L"ConEmuHk: Virtual subkey (%s) creation failed! ErrCode=0x%08X\n",
					pszKeyName ? pszKeyName : L"<NULL>", (DWORD)lRc);
				GuiMessageBox(ghConEmuWnd, szErrInfo, szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
			}
			// Для консистентности
			if (!ghNewHKLM64)
				ghNewHKLM64 = ghNewHKLM32;
			if (!ghNewHKLM64Software)
				ghNewHKLM64Software = ghNewHKLM32Software;
		}
	}

	if ((ghNewKeyRoot == NULL) || (ghNewKeyRoot == (HKEY)-1))
	{
		DEBUGSTR(L"ConEmuHk: Registry virtualization failed!\n");
		return false;
	}
	else
	{
		DEBUGSTR(L"ConEmuHk: Registry virtualization succeeded\n");
	}

	return true;
}
コード例 #2
0
// 0 - SUCCEEDED, otherwise - error code
int WINAPI MountVirtualHive(LPCWSTR asHive, PHKEY phKey, LPCWSTR asXPMountName, wchar_t* pszErrInfo, int cchErrInfoMax, BOOL* pbKeyMounted)
{
	int lRc = -1;
	
	if (pszErrInfo && cchErrInfoMax)
		*pszErrInfo = 0; // если передали буфер для ошибки - сразу его почистить

	*pbKeyMounted = FALSE;

	OSVERSIONINFO osv = {sizeof(OSVERSIONINFO)};
	GetVersionEx(&osv);
	HMODULE hAdvapi32 = LoadLibrary(L"advapi32.dll");
	//LPCWSTR pszKeyName = NULL;
	LPCWSTR ppszKeys[] =
	{
		L"HKCU",
		L"HKCU\\Software",
		L"HKLM",
		L"HKLM\\Software",
		L"HKLM64",
		L"HKLM64\\Software"
	};
	size_t nRootKeys = IsWindows64() ? countof(ppszKeys) : (countof(ppszKeys) - 2);

	if (!hAdvapi32)
	{
		if (pszErrInfo && cchErrInfoMax)
			msprintf(pszErrInfo, cchErrInfoMax,
				L"LoadLibrary(advapi32.dll) failed, code=0x%08X!\n", GetLastError());
		lRc = -2;
		goto wrap;
	}
	
	if (osv.dwMajorVersion >= 6)
	{
		// Vista+
		typedef LONG (WINAPI* RegLoadAppKey_t)(LPCWSTR lpFile, PHKEY phkResult, REGSAM samDesired, DWORD dwOptions, DWORD Reserved);
		RegLoadAppKey_t RegLoadAppKey_f = (RegLoadAppKey_t)GetProcAddress(hAdvapi32, "RegLoadAppKeyW");
		if (!RegLoadAppKey_f)
		{
			if (pszErrInfo && cchErrInfoMax)
				msprintf(pszErrInfo, cchErrInfoMax,
					L"RegLoadAppKeyW not found, code=0x%08X!\n", GetLastError());
			lRc = -3;
			goto wrap;
		}
		else
		{
			if ((lRc = RegLoadAppKey_f(asHive, phKey, KEY_ALL_ACCESS, 0, 0)) != 0)
			{
				if ((lRc = RegLoadAppKey_f(asHive, phKey, KEY_READ, 0, 0)) != 0)
				{
					if (pszErrInfo && cchErrInfoMax)
						msprintf(pszErrInfo, cchErrInfoMax,
							L"RegLoadAppKey failed, code=0x%08X!", (DWORD)lRc);
					lRc = -4; //-V112
					goto wrap;
				}
			}
			*pbKeyMounted = TRUE;
		}
	}
	else if (!asXPMountName || !*asXPMountName)
	{
		lRc = -7;
		if (pszErrInfo && cchErrInfoMax)
			lstrcpyn(pszErrInfo, L"XPMountName is empty!", cchErrInfoMax);
		goto wrap;
	}
	else
	{
		CBackupPrivileges se;
		if (!se.BackupPrivilegesAcuire(TRUE))
		{
			if (pszErrInfo && cchErrInfoMax)
				msprintf(pszErrInfo, cchErrInfoMax,
					L"Aquiring SE_BACKUP_NAME/SE_RESTORE_NAME failed, code=0x%08X!\nYou must be Administrator or Backup operator", GetLastError());
			lRc = -5;
			goto wrap;
		}
		
		//_wcscpy_c(rsXPMountName, cchXPMountMax, VIRTUAL_REGISTRY_GUID);
		//WARNING("###: Докинуть в конец что-нть уникальное, например CRC пути к hive");
		
		// Hive уже мог быть подключен другой копией ConEmu.
		TODO("При выходе - может возникнуть конфликт? Кто первый сделает RegUnloadKey...");
		
		if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_ALL_ACCESS, phKey)) == 0)
		{
			goto wrap; // успешно - hive уже подключен
		}
		else if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_READ, phKey)) == 0)
		{
			goto wrap; // успешно - hive уже подключен (ReadOnly)
		}
		
		// Hive еще не был подключен
		if ((lRc = RegLoadKey(HKEY_USERS, asXPMountName, asHive)) != 0)
		{
			if (pszErrInfo && cchErrInfoMax)
				msprintf(pszErrInfo, cchErrInfoMax,
					L"RegLoadKey failed, code=0x%08X!", (DWORD)lRc);
			lRc = -6;
			goto wrap;
		}
		// Ключ смонтирован, нужно его будет демонтировать при выходе
		*pbKeyMounted = TRUE;

		if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_ALL_ACCESS, phKey)) == 0)
		{
			goto wrap; // успешно - hive уже подключен
		}
		else if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_READ, phKey)) == 0)
		{
			goto wrap; // успешно - hive уже подключен (ReadOnly)
		}
	}
	
	// Нужно проверить, можно ли создать/открыть необходимые ключи
	for (UINT i = 0; i < nRootKeys; i++)
	{
		HKEY hTest = NULL;
		LPCWSTR pszKeyName = ppszKeys[i];
		lRc = RegCreateKeyEx(*phKey, pszKeyName, 0,0,0, KEY_ALL_ACCESS, 0, &hTest, 0);
		if (lRc != 0)
			lRc = RegCreateKeyEx(*phKey, pszKeyName, 0,0,0, KEY_READ, 0, &hTest, 0);
		if (lRc != 0)
		{
			if (pszErrInfo && cchErrInfoMax)
				msprintf(pszErrInfo, cchErrInfoMax,
					L"RegCreateKeyEx(%s) failed, code=0x%08X!", pszKeyName, (DWORD)lRc);
			RegCloseKey(*phKey);
			*phKey = NULL;
			if (asXPMountName && *asXPMountName)
				UnMountVirtualHive(asXPMountName, NULL, 0);
			lRc = -8;
			goto wrap;
		}
	}

wrap:
	if (hAdvapi32)
		FreeLibrary(hAdvapi32); // Decrease counter
	return lRc;
}