Windows代码实现禁用和启用安全模式

实现比较简单,是通过修改注册表:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/SafeBoot的子项Minimal和Network的名字实现的。

1、提权 

CAccessToken token;
token.GetProcessToken(TOKEN_ALL_ACCESS);
token.EnablePrivilege(SE_TAKE_OWNERSHIP_NAME);

2、修改注册表权限

调用TreeSetNamedSecurityInfo实现,这个函数可以设置注册表和子项的权限;网上很多教程调用的SetNameSecurityInfo,不能设置子项的权限,修改名字会失败。

3、修改注册表子项名字

RegRenameKey(hKey, NULL, newName);  // hKey为minimal或者network项,newName为新名字

完整代码如下:

#include "stdafx.h"
#include <Windows.h>
#include <WinSvc.h>
#include <WinIoCtl.h>
#include <minwindef.h>
#include <fltUser.h>
#include <malloc.h>
#include <tchar.h>
#include <Aclapi.h>
#include <atlsecurity.h>
#include <Winreg.h>

#define REG_SAFE_BOOT_PATH					_T("SYSTEM\\CurrentControlSet\\Control\\SafeBoot")

#define REG_SAFE_BOOT_MINIMAL_NAME			_T("Minimal")
#define REG_SAFE_BOOT_NETWORK_NAME			_T("Network")
#define REG_SAFE_BOOT_MINIMAL_RENAME		_T("Minimal_Bak")
#define REG_SAFE_BOOT_NETWORK_RENAME		_T("Network_Bak")

#define 

static LPCTSTR GetPrimaryKeyName(HKEY hKey)
{
	if (HKEY_LOCAL_MACHINE == hKey)
	{
		return _T("MACHINE");
	}
	else if (HKEY_CLASSES_ROOT == hKey)
	{
		return _T("CLASSES_ROOT");
	}
	else if (HKEY_USERS == hKey)
	{
		return _T("USERS");
	}
	else if (HKEY_CURRENT_USER == hKey)
	{
		return _T("CURRENT_USER");
	}

	return NULL;
}

static BOOL SetPrivilege(
	BOOL bEnablePrivilege
)
{
	CAccessToken token;
	token.GetProcessToken(TOKEN_ALL_ACCESS);
	token.EnablePrivilege(SE_TAKE_OWNERSHIP_NAME);

	return TRUE;
}

static BOOLEAN RenameRegistry(HKEY priKey, LPTCH parentPath, LPTCH subName, LPTCH newName)
{
	int ret;
	HKEY hKey;
	TCHAR regPath[MAX_PATH] = { 0 };

	_tcscpy_s(regPath, parentPath);
	_tcscat_s(regPath, _T("\\"));
	_tcscat_s(regPath, subName);

	ret = RegOpenKeyEx(priKey, regPath, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, &hKey);
	if (ret != ERROR_SUCCESS)
	{
		_tprintf(_T("MdmRenameReg: RegOpenKeyEx failed: name = %s, newname = %s, ret = %d, lasterr = %d\n"),
			subName, newName, ret, GetLastError());

		return FALSE;
	}

	ret = RegRenameKey(hKey, NULL, newName);
	if (ret != ERROR_SUCCESS)
	{
		_tprintf(_T("MdmRenameReg: RegRenameKey failed: name = %s, newname = %s, ret = %d, lasterr = %d\n"),
			subName, newName, ret, GetLastError());

		RegCloseKey(hKey);

		return FALSE;
	}

	RegCloseKey(hKey);

	return TRUE;
}

static BOOLEAN RequestPermissionAndRenameRegistry(HKEY priKey, LPTCH parentPath, LPTCH subName, LPTCH newName)
{
	DWORD ret;
	BOOLEAN status = TRUE;
	BOOLEAN renamed = FALSE;
	CDacl dacl;

	TCHAR regOldPath[MAX_PATH] = { 0 };
	TCHAR regNewPath[MAX_PATH] = { 0 };

	_tcscpy_s(regOldPath, GetPrimaryKeyName(priKey));
	_tcscat_s(regOldPath, _T("\\"));
	_tcscat_s(regOldPath, parentPath);
	_tcscat_s(regOldPath, _T("\\"));
	_tcscat_s(regOldPath, subName);

	_tcscpy_s(regNewPath, GetPrimaryKeyName(priKey));
	_tcscat_s(regNewPath, _T("\\"));
	_tcscat_s(regNewPath, parentPath);
	_tcscat_s(regNewPath, _T("\\"));
	_tcscat_s(regNewPath, newName);

	ret = TreeSetNamedSecurityInfo(regOldPath,
		SE_REGISTRY_KEY,
		OWNER_SECURITY_INFORMATION,
		(PSID)Sids::Admins().GetPSID(),
		NULL,
		NULL,
		NULL,
		TREE_SEC_INFO_SET,
		NULL,
		ProgressInvokeNever,
		NULL);

	if (ret != ERROR_SUCCESS)
	{
		_tprintf(_T("TreeSetNamedSecurityInfo: OWNER_SECURITY_INFORMATION Error: %d\n"), ret);
		status = FALSE;
		goto EXIT;
	}

	dacl.AddAllowedAce(Sids::Admins(), GENERIC_ALL);

	ret = TreeSetNamedSecurityInfo(regOldPath,
		SE_REGISTRY_KEY,
		DACL_SECURITY_INFORMATION,
		NULL,
		NULL,
		(PACL)dacl.GetPACL(),
		NULL,
		TREE_SEC_INFO_SET,
		NULL,
		ProgressInvokeNever,
		NULL);

	if (ret != ERROR_SUCCESS)
	{
		_tprintf(_T("TreeSetNamedSecurityInfo: DACL_SECURITY_INFORMATION Error: %d\n"), ret);
		status = FALSE;
		goto EXIT;
	}

	if (!(renamed = RenameRegistry(priKey, parentPath, subName, newName)))
	{
		status = FALSE;
		goto EXIT;
	}

EXIT:
	if (ret == ERROR_SUCCESS)
	{
		// TODO: 恢复DACL
		if (renamed)
		{
		}
		else
		{
		}
	}
	return status;
}

INT DLL_API EnableSafeBoot()
{
	INT status = SUCCESS;

	if (!SetPrivilege(TRUE))
	{
		_tprintf(_T("EnableSafeBoot: SetPrivilege failed\n"));

		return ERR_API_BASE;
	}

	if (!RequestPermissionAndRenameRegistry(HKEY_LOCAL_MACHINE, REG_SAFE_BOOT_PATH,
		REG_SAFE_BOOT_MINIMAL_RENAME, REG_SAFE_BOOT_MINIMAL_NAME))
	{
		_tprintf(_T("EnableSafeBoot: RequestPermissionAndRenameRegistry minimal failed\n"));

		return ERR_API_BASE;
	}

	if (!RequestPermissionAndRenameRegistry(HKEY_LOCAL_MACHINE, REG_SAFE_BOOT_PATH,
		REG_SAFE_BOOT_NETWORK_RENAME, REG_SAFE_BOOT_NETWORK_NAME))
	{
		_tprintf(_T("EnableSafeBoot: RequestPermissionAndRenameRegistry network failed\n"));

		return ERR_API_BASE;
	}

	return status;
}

INT DLL_API DisableSafeBoot()
{
	INT status = SUCCESS;

	if (!SetPrivilege(TRUE))
	{
		_tprintf(_T("DisableSafeBoot: SetPrivilege failed\n"));

		return ERR_API_BASE;
	}

	if (!RequestPermissionAndRenameRegistry(HKEY_LOCAL_MACHINE, REG_SAFE_BOOT_PATH,
		REG_SAFE_BOOT_MINIMAL_NAME, REG_SAFE_BOOT_MINIMAL_RENAME))
	{
		_tprintf(_T("DisableSafeBoot: RequestPermissionAndRenameRegistry minimal failed\n"));

		return ERR_API_BASE;
	}

	if (!RequestPermissionAndRenameRegistry(HKEY_LOCAL_MACHINE, REG_SAFE_BOOT_PATH,
		REG_SAFE_BOOT_NETWORK_NAME, REG_SAFE_BOOT_NETWORK_RENAME))
	{
		_tprintf(_T("DisableSafeBoot: RequestPermissionAndRenameRegistry network failed\n"));

		return ERR_API_BASE;
	}

	return status;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值