注册表修改项名
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;
}