Skip to content

Commit

Permalink
Improved dependency compatiblity (#514)
Browse files Browse the repository at this point in the history
The module will not detect if there was a problem loading its dlls and if it was, reloads PowerShell with -NoProfile switch to fix it.

Also a new message will be shown when installing the AppControl Manager and there is an incompatible policy on the system.

Fixes this issue: #513
  • Loading branch information
HotCakeX authored Jan 7, 2025
1 parent 8df2ae0 commit bad0e85
Show file tree
Hide file tree
Showing 12 changed files with 45 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using Windows.ApplicationModel;
using Windows.Management.Deployment;

Expand Down Expand Up @@ -352,6 +353,36 @@ await Task.Run(() =>

Logger.LogMessage($"AppControl Manager installation has been successful.", LogTypeIntel.InformationInteractionRequired);

try
{
string registryPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
string registryName = "ValidateAdminCodeSignatures";

using (RegistryKey? key = Registry.LocalMachine.OpenSubKey(registryPath))
{
if (key is not null)
{
// Get the registry value
object? registryValue = key.GetValue(registryName);

if (registryValue is not null && string.Equals(registryValue.ToString(), "1", StringComparison.OrdinalIgnoreCase))
{

Logger.LogMessage("Warning: A policy named 'Only elevate executables that are signed and validated' " +
"is conflicting with the AppControl Manager app and won't let it start because it's self-signed " +
"with your on-device keys. Please disable the policy. It can be found in Group Policy Editor -> " +
"Computer Configuration -> Windows Settings -> Security Settings -> Local Policies -> Security Options -> " +
"'User Account Control: Only elevate executable files that are signed and validated'", LogTypeIntel.WarningInteractionRequired);

}
}
}
}
catch
{
Logger.LogMessage("Could not verify that 'Only Elevate signed' policy is not active.", LogTypeIntel.Warning);
}

});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ private void UpdateTotalCount(bool ShowNotification)
}

// Display a notification if it's allowed to do so, and ShowNotification is set to true
if (GlobalVars.UseNewNotificationsExp && ShowNotification)
if (ShowNotification)
{
ToastNotification.Show(ToastNotification.Type.EndOfConfirmation, CompliantItemsCount, NonCompliantItemsCount, null, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -723,10 +723,7 @@ await Task.Run(() =>
}
}

if (GlobalVars.UseNewNotificationsExp)
{
ToastNotification.Show(ToastNotification.Type.EndOfProtection, null, null, null, null);
}
ToastNotification.Show(ToastNotification.Type.EndOfProtection, null, null, null, null);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal static void Show(string Message, string? Title = "An Error Occurred")
{
Title = Title,
Width = 450,
Height = 300,
Height = 350,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
ResizeMode = ResizeMode.NoResize

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ public static class GlobalVars
// The path to the LGPO.exe utility
internal static string? LGPOExe;

// A flag to determine whether the new notifications experience should be used or not
// It won't be used if there is an interferences detected with DLL load due to other addons being loaded in the PowerShell session
// Such as PowerToys' CommandNotFound or WinGet's PowerShell module
public static bool UseNewNotificationsExp = true;

// Initialize the RegistryCSVItems list so that the HardeningRegistryKeys.ReadCsv() method can write to it
internal static readonly List<HardeningRegistryKeys.CsvRecord> RegistryCSVItems = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ public enum Type

/// <summary>
/// Displays modern toast notification on Windows
/// The caller must check for GlobalVars.UseNewNotificationsExp and if it's true then use this method
/// So that it will only display the notifications if the required DLLs have been loaded in the PowerShell session via Add-Type
/// That is different than the DLLs being made available to the Add-Type during C# code compilation
/// </summary>
/// <param name="Type">The type of the toast notification to use</param>
public static void Show(Type Type, string? TotalCompliantValues, string? TotalNonCompliantValues, string? UnprotectCategory, string? BitLockerEncryptionTab)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ function Confirm-SystemCompliance {
if (-NOT ([HardenWindowsSecurity.UserPrivCheck]::IsAdmin())) {
Throw [System.Security.AccessControl.PrivilegeNotHeldException] 'Administrator'
}
try { LoadHardenWindowsSecurityNecessaryDLLsInternal } catch { Write-Verbose $global:ReRunText; ReRunTheModuleAgain $MyInvocation.Statement }
[HardenWindowsSecurity.Initializer]::Initialize($VerbosePreference)

if (-NOT $Offline) {
[HardenWindowsSecurity.Logger]::LogMessage('Checking for updates...', [HardenWindowsSecurity.LogTypeIntel]::Information)
Update-HardenWindowsSecurity -InvocationStatement $MyInvocation.Statement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ Function Protect-WindowsSecurity {
}
}
begin {
try { LoadHardenWindowsSecurityNecessaryDLLsInternal } catch { Write-Verbose $global:ReRunText; ReRunTheModuleAgain -C $MyInvocation.Statement }
$script:ErrorActionPreference = 'Stop'
[HardenWindowsSecurity.Initializer]::Initialize($VerbosePreference)
[System.Boolean]$ErrorsOccurred = $false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Function Unprotect-WindowsSecurity {
if (-NOT ([HardenWindowsSecurity.UserPrivCheck]::IsAdmin())) {
Throw [System.Security.AccessControl.PrivilegeNotHeldException] 'Administrator'
}
try { LoadHardenWindowsSecurityNecessaryDLLsInternal } catch { Write-Verbose $global:ReRunText; ReRunTheModuleAgain $MyInvocation.Statement }
$script:ErrorActionPreference = 'Stop'
[HardenWindowsSecurity.Initializer]::Initialize($VerbosePreference)
[HardenWindowsSecurity.Logger]::LogMessage('Checking for updates...', [HardenWindowsSecurity.LogTypeIntel]::Information)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
PowerShellVersion = '7.4.5'
RequiredAssemblies = @()
NestedModules = @('Core\Confirm-SystemCompliance.psm1', 'Core\Protect-WindowsSecurity.psm1', 'Core\Unprotect-WindowsSecurity.psm1')
FunctionsToExport = @('Confirm-SystemCompliance', 'Protect-WindowsSecurity', 'Unprotect-WindowsSecurity', 'Update-HardenWindowsSecurity')
FunctionsToExport = @('Confirm-SystemCompliance', 'Protect-WindowsSecurity', 'Unprotect-WindowsSecurity', 'Update-HardenWindowsSecurity', 'LoadHardenWindowsSecurityNecessaryDLLsInternal', 'ReRunTheModuleAgain')
CmdletsToExport = @()
VariablesToExport = '*'
AliasesToExport = @()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,12 @@ function Update-HardenWindowsSecurity {
}
}
}

try {
$PSStyle.Progress.UseOSCIndicator = $true
# Set PSReadline tab completion to complete menu for easier access to available parameters - Only for the current session
Set-PSReadLineKeyHandler -Key 'Tab' -Function 'MenuComplete'
}
catch {}

$ToastNotificationDLLs = [System.Collections.Generic.List[System.String]]::new()
$ToastNotificationDLLs.Add([System.IO.Path]::Combine($PSScriptRoot, 'DLLs', 'Toast Notifications', 'Microsoft.Toolkit.Uwp.Notifications.dll'))
$ToastNotificationDLLs.Add([System.IO.Path]::Combine($PSScriptRoot, 'DLLs', 'Toast Notifications', 'Microsoft.Win32.SystemEvents.dll'))
Expand All @@ -96,20 +94,14 @@ $ToastNotificationDLLs.Add([System.IO.Path]::Combine($PSScriptRoot, 'DLLs', 'Toa
# https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/
Add-Type -Path ([System.IO.Directory]::GetFiles("$PSScriptRoot\C#", '*.*', [System.IO.SearchOption]::AllDirectories)) -ReferencedAssemblies @((Get-Content -Path "$PSScriptRoot\.NETAssembliesToLoad.txt") + "$($PSHOME)\WindowsBase.dll" + $ToastNotificationDLLs) -CompilerOptions '/langversion:preview', '/nowarn:1701', '/nullable:enable', '/checked'

try {
Function LoadHardenWindowsSecurityNecessaryDLLsInternal {
# when we use the -ReferencedAssemblies parameter of Add-Type, The DLLs are only added and made available to the C# compilation, not the PowerShell host itself
# In order to display the toast notifications, they needed to be added to the PowerShell itself as well
# In order to display the toast notifications and other codes that rely on them, they needed to be added to the PowerShell itself as well
foreach ($DLLPath in $ToastNotificationDLLs) {
Add-Type -Path $DLLPath
}
}
catch {
[HardenWindowsSecurity.GlobalVars]::UseNewNotificationsExp = $false
}
try {
[HardenWindowsSecurity.GlobalVars]::Host = $HOST
}
catch {
[HardenWindowsSecurity.GlobalVars]::Host = $null
}
[HardenWindowsSecurity.GlobalVars]::path = $PSScriptRoot
try { [HardenWindowsSecurity.GlobalVars]::Host = $HOST }catch { [HardenWindowsSecurity.GlobalVars]::Host = $null }
[HardenWindowsSecurity.GlobalVars]::path = $PSScriptRoot
Function ReRunTheModuleAgain($C) { pwsh.exe -NoProfile -NoLogo -NoExit -command $C }
$global:ReRunText = 'Re-running the module because of a possible dependency conflict with other modules such as CommandNotFound in PowerToys'
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<TextBlock Grid.Row="0" Text="Use this page to install the AppControl Manager. Since AppControl Manager uses on-device generated self-signed certificate, the 'Only Elevate Signed' policy and Smart App Control must not be enabled. Smart App Control must be off either way if you intend to take full control of Applicaton Control in your system using the AppControl Manager."
<TextBlock Grid.Row="0" Text="Use this page to install the AppControl Manager. Since it uses certificate generated on your device, Smart App Control might not let it run. Smart App Control must be off either way if you intend to take full control of Applicaton Control in your system using the AppControl Manager."
Foreground="Black"
FontSize="14"
Margin="20,10,20,15"
Expand Down

0 comments on commit bad0e85

Please sign in to comment.