注册表修改项名

c++

Posted by YiMiTuMi on December 3, 2019

注册表修改项名

windows中并没有提供修改注册表项名的接口(可能有我没找到),就手动写了一下。

思路:

  1)利用注册表的备份功能先备份出要改名的文件。

  2)删除要改名的文件。

  3)建一个要改的新名的项。

  4)将当前备份还原到新项中。

导出导入注册表权限获取函数

BOOL GetPrivilege()
{
	BOOL bFlag = TRUE;

	do 
	{
		//设置权限导入导出注册表
		HANDLE hToken,hToken1,hToken2;
		TOKEN_PRIVILEGES tkp,tkp1,tkp2;

		if(!OpenProcessToken (GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken))
		{
			bFlag = FALSE;
			break;
		}

		if(!LookupPrivilegeValue( NULL, SE_BACKUP_NAME, &tkp.Privileges[0].Luid))
		{
			bFlag = FALSE;
			break;
		}

		tkp.PrivilegeCount = 1;
		tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

		if(!AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES),
			(PTOKEN_PRIVILEGES)NULL, PDWORD(NULL)))

		{
			bFlag = FALSE;
			break;
		}

		if(GetLastError () == ERROR_NOT_ALL_ASSIGNED || GetLastError () != ERROR_SUCCESS )
		{
			bFlag = FALSE;
			break;
		}

		if(!OpenProcessToken (GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken1))		
		{					
			bFlag = FALSE;			
			break;		
		}

		if(!LookupPrivilegeValue( NULL, SE_RESTORE_NAME, &tkp1.Privileges[0].Luid))		
		{						
			bFlag = FALSE;			
			break;		
		}

		tkp1.PrivilegeCount = 1;
		tkp1.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		if(!AdjustTokenPrivileges( hToken1, FALSE, &tkp1, sizeof(TOKEN_PRIVILEGES),	(PTOKEN_PRIVILEGES)NULL, PDWORD(NULL)))		
		{					
			bFlag = FALSE;			
			break;		
		}

		if(GetLastError () == ERROR_NOT_ALL_ASSIGNED || GetLastError () != ERROR_SUCCESS )		
		{						
			bFlag = FALSE;			
			break;		
		} 	

		if(!OpenProcessToken (GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken2))		
		{						
			bFlag = FALSE;			
			break;		
		}

		if(!LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &tkp2.Privileges[0].Luid))		
		{						
			bFlag = FALSE;			
			break;		
		}

		tkp2.PrivilegeCount = 1;	
		tkp2.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;		
		if(!AdjustTokenPrivileges( hToken2, FALSE, &tkp2, sizeof(TOKEN_PRIVILEGES),	(PTOKEN_PRIVILEGES)NULL, PDWORD(NULL)))		
		{						
			bFlag = FALSE;			
			break;		
		} 

		if(GetLastError () == ERROR_NOT_ALL_ASSIGNED || GetLastError () != ERROR_SUCCESS )		
		{					
			bFlag = FALSE;			
			break;		
		}

	} while (FALSE);
	return bFlag;
}

删除注册表项

删除注册表项我写了很多方法。

RegDeleteKey 函数删除的时候,删除的项下面不能有子项,所以要递归去删除。

BOOL DeleteReg(HKEY hPrimaryKey, wstring wstrRegPath)
{

 	BOOL bFlag = TRUE;
	HKEY hKey = NULL;
	long longReg = 0;
	DWORD dwDisposition;

	do 
	{

		EnablePriviledge(SE_BACKUP_NAME); //最后会给出EnablePriviledge函数实现
		EnablePriviledge(SE_RESTORE_NAME);
		
		//这个是重点,传入这个参数可以直接忽视KEY_ALL_ACCESS这个参数的作用,直接以备份/还原的特权去操作注册表
		longReg = RegCreateKeyExW(hPrimaryKey,
			wstrRegPath.c_str(),
			0,
			NULL,
			REG_OPTION_BACKUP_RESTORE,
			KEY_ALL_ACCESS,
			NULL,
			&hKey,
			&dwDisposition);
		int b = GetLastError();
		if (longReg != ERROR_SUCCESS)
		{
			bFlag = FALSE;
			break;
		}
		/*
		//打开注册表,这个也可以 上面那个测试权限用的
		longReg = RegOpenKeyEx(hPrimaryKey, wstrRegPath.c_str(), 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey);
		if (longReg != ERROR_SUCCESS)
		{
			bFlag = FALSE;
			break;
		}
		*/

		//获取注册表子键信息,判断是否有子键

		TCHAR szSubKey[240];	//子键名称
		DWORD dwName = 240;	//名称大小

		//是否有子键,如果有则递归查找,这里要注意,index不能自增,因为一旦删除了一个键,其余键的序号就会自己减一,所以不断删除0就可以了
		int index = 0;
		while (ERROR_SUCCESS == RegEnumKey(hKey, index, szSubKey, dwName))
		{
			wstring tmp = wstrRegPath + L"\\" + szSubKey;
			bFlag = DeleteReg(hPrimaryKey, tmp);
		}

		//递归结束条件
		if (!bFlag)
		{
			break;
		}

		//删除当前项
		longReg = RegDeleteKey(hPrimaryKey, wstrRegPath.c_str());
		int a = GetLastError();
		if (longReg != ERROR_SUCCESS)
		{
			bFlag = FALSE;
			break;
		}
		
	} while (FALSE);

	RegCloseKey(hKey);
	return bFlag;
}

也可以用RegDeleteTree去删除。

删除函数

当时写的是测试参数传的也比较随意。

注册表的HKEY,注册表修改项的上一项的路径,需要修改项的名字,新名字,修改项的全路径(其实传3项就可以解决,但懒得去截字符串了)

BOOL RenameRegItem(HKEY hPrimaryKey, wstring wstrRegPath, wstring wstrOldName,wstring wstrNewName, wstring FullPath)
{
	BOOL bFlag = TRUE;
	HKEY hKey = NULL;
	long longReg = 0;
	wstring wstrFilePath = L"";
	do 
	{
		if (wstrRegPath.empty() || wstrNewName.empty() || wstrOldName.empty() || hPrimaryKey == NULL)
		{
			break;
			bFlag = FALSE;
		}
		
		if (!GetPrivilege())
		{
			bFlag = FALSE;
			break;
		}

		wstring wstrOldPath = wstrRegPath + L"\\" + wstrOldName;

		//打开注册表
		longReg = RegOpenKeyEx(hPrimaryKey, wstrOldPath.c_str(), 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey);
		
		if (longReg != ERROR_SUCCESS)
		{
			bFlag = FALSE;
			break;
		}
		
		//重命名
		wstrFilePath = L"C:\\Old_Name";

		//备份注册表键值
		longReg = RegSaveKey(hKey, wstrFilePath.c_str(), NULL);
		int a = GetLastError();
		if (longReg != ERROR_SUCCESS)
		{
			bFlag = FALSE;
			break;
		}
		
		//递归删除旧项
		if (0)
		{
			FullPath = L"cmd.exe /c reg delete " + FullPath + L" /F";
			ExeCmd(FullPath);
		}
		
		
		wstring wsrtOldPath = wstrRegPath + L"\\" + wstrOldName;
		
		
		if (!DeleteReg(hPrimaryKey, wsrtOldPath))
		{
			break;
		}
		
		//RegDeleteTree(hPrimaryKey, wsrtOldPath.c_str());

		//关闭旧主键
		RegCloseKey(hKey);

		//新主键
		//wstring wstrNewPath = wstrRegPath;

		//打开新注册表
		longReg = RegOpenKeyEx(hPrimaryKey, wstrRegPath.c_str(), 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey);
		if (longReg != ERROR_SUCCESS)
		{
			bFlag = FALSE;
			break;
		}
		
		HKEY newKey;
		//创建新项
		longReg = RegCreateKey(hKey, wstrNewName.c_str(), &newKey);
		if (longReg != ERROR_SUCCESS)
		{
			bFlag = FALSE;
			break;
		}
		
		//从文件中加载注册表键值
		RegRestoreKey(newKey, wstrFilePath.c_str(), REG_FORCE_RESTORE);
		if (longReg != ERROR_SUCCESS)
		{
			bFlag = FALSE;
			break;
		}
		RegCloseKey(newKey);
		

	} while (FALSE);
	
	//删除保存注册表的文件
	DeleteFile(wstrFilePath.c_str());

	RegCloseKey(hKey);
	return bFlag;
}

调用

int main()
{
	RenameRegItem(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot", L"999", L"321", L"HKEY_CURRENT_USER\\System\\999");

	return 0;
}

EnablePriviledge函数

BOOL EnablePriviledge(LPCTSTR lpSystemName)
{
	HANDLE hToken;
	TOKEN_PRIVILEGES tkp = {1};

	if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken))
	{
		if(LookupPrivilegeValue(NULL, lpSystemName, &tkp.Privileges[0].Luid))
		{
			tkp.PrivilegeCount = 1;
			tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
			AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); 
			if (GetLastError() != ERROR_SUCCESS)
			{
				CloseHandle(hToken);
				return false;
			}
		}
		CloseHandle(hToken);
	}
	return true;
}

兔尾草 – 尊贵杰出(被强烈科普,原来真有这个)