Thursday, 27 July 2017 13:33

The Case of Microsoft Edge Crash

Written by
Rate this item
(1 Vote)

image

This case unfolds with a customer piloting Windows 7 to Windows 10 in place upgrade. It’s a really interesting case because it highlights the use of Sysinternals Process Monitor and PowerShell to identify and fix an issue and also because it is actually two cases in one.

It all started with a user complaining that Microsoft Edge wouldn't start on his upgraded system. We chalked it up to random issue caused by the inplace upgrade. We moved on, but a few days later multiple users started experiencing the issue.

Mark Russinovich always advises "when in doubt, run Process Monitor", so this is exactly what I did. I downloaded a copy from Technet and captured a trace of the faulty Microsoft Edge start.

Wondering if perhaps the sequence of processes starting during the Microsoft Edge start might reveal something, I opened the Process Tree dialog from the Tools menu. Focusing my attention on MicrosoftEdge.exe, I noticed that Windows Error Reporting (WER) service started a process named WerFault.exe around the time I tried launching Microsoft Edge.

Instead of looking for clues in the trace, I thought I might find clues by comparing the trace of the failing Edge to another captured on a system where the Edge broser starts successfully.

A few minutes later I had a second trace to compare side-by-side. Instead of scanning the several million events that had been captured, which would have been like looking for a needle in a haystack, my next step was to set the Include filter to MicrosoftEdge.exe. I also made an assumption that the issue was somehow related to registry, so I excluded all other types of events, and proceeded through the events in the trace from the failing system, correlating them with corresponding events on the working one.

Both traces had references to HKU hive, but to my consternation on the problematic machine those registry queries failed with ACCESS DENIED.

This confirmed my suspicions that the issue was caused by faulty registry permissions.

Further investigation showed that the group ALL_APP_Packages group was not present in the HKU hive, which in turn lead to Microsoft Edge to stop working. Confident I’d solved the mystery, I right-clicked the corresponding HKU hive and added the ALL_APP_Packages group.

I ran Microsoft Edge to verify my fix and to my immense satisfaction, the Edge browser started without a hitch.

The case wasn't closed yet though!

Somehow the registry permissions had been corrupted, so we had to figure out what was causing modifications to HKU registry hives permissions. I collected Process Monitor log of the HKU hive activity overnight. When I viewed the log, there was a clear pattern: a legacy line of business application was messing around with registry permissions. Why the application would modify default registry permissions will remain forever a mystery, but the important thing now was fixing the underlying issue using a two pronged approach. A patch was issued which disabled permisisons alterations. We still had to fix a number of systems out there, that were experiencing the issue. To do so, I simply wrote a PowerShell script that would add ALL_APP_Packages to the HKCU hive with read permissions. In order to support non-English systems I had to query actual group name using well known SIDs.

<#
.Synopsis
    FixHKCUPermissions.ps1
.DESCRIPTION
    Fixes ALL_APP_PACKAGES HKCU permissions.
	In order to support non-English systems the script queries actual group name
	using well known SIDs: https://msdn.microsoft.com/en-us/library/cc980032.aspx
    SID: S-1-15-2-1, Name: ALL_APP_PACKAGES
    Description: All applications running in an app package context.
.EXAMPLE
    FixHKCUPermissions.ps1
.NOTES
    Created:	 2016-11-12
    Version:	 1.0
    Author - Anton Romanyuk
    Twitter: @admiraltolwyn
    Blog   : http://www.vacuumbreather.com
    Disclaimer:
    This script is provided 'AS IS' with no warranties, confers no rights and 
    is not supported by the author.
.LINK
    http://www.vacuumbreather.com
.NOTES
	This script has to run in the user context!
#>

# ---------------------------------------------------------------------------
# Global variables
# ---------------------------------------------------------------------------

# Detect language specific name of the ALL_APP_PACKAGES group
$SID= @("S-1-15-2-1")
$apps_sid = New-Object System.Security.Principal.SecurityIdentifier($SID) 
$apps_group = $apps_sid.Translate([System.Security.Principal.NTAccount]) -creplace '^[^\\]*\\', ''

# Find current user
$cur_user = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name

# HKEY_CURRENT_USER path
$paths = ("HKCU:","HKCU:SOFTWARE")

# ---------------------------------------------------------------------------
# Set-RegistryKeyPermission:  Sets registry key permissions
# ---------------------------------------------------------------------------

# https://stackoverflow.com/questions/24366162/set-acl-requested-registry-access-is-not-allowed/35844259#35844259

Function Set-RegistryKeyPermission{
    Param
    (
        [Parameter(Mandatory = $true)]
        [String]$Path,
        
        [ValidateSet("Add","Remove")]
        [Parameter(Mandatory=$true)]
        [String]$Type,
        
        [Parameter(Mandatory = $true)]
        [String]$Account,
        
        [Parameter(Mandatory=$true)]
        [ValidateSet("QueryValues","SetValue","CreateSubKey","EnumerateSubKeys","Notify","CreateLink","ExecuteKey","ReadKey","WriteKey",
            "Delete","ReadPermissions","ChangePermissions","TakeOwnership","FullControl")]
        [String]$RegistryRights,
        
        [ValidateSet("None","ContainerInherit","ObjectInherit","ContainerInherit,ObjectInherit")]
        [Parameter(Mandatory=$false)]
        [String]$InheritanceFlags = "ContainerInherit,ObjectInherit",
        
        [ValidateSet("None","NoPropagateInherit","InheritOnly","NoPropagateInherit,InheritOnly")]
        [Parameter(Mandatory=$false)]
        [String]$PropagationFlags = "None",
        
        [ValidateSet("Allow","Deny")]
        [Parameter(Mandatory=$true)]
        [String]$AccessControlType
    )
    
    $aclRegistry= Get-Acl -Path $Path   
    $aclRegistry.SetAccessRuleProtection($true, $true)
    $ruleRegistry =  New-Object System.Security.AccessControl.RegistryAccessRule($Account,$RegistryRights,$InheritanceFlags,$PropagationFlags,$AccessControlType)
    
    Try
    {
        If($Type -eq "Add")
        {
            $aclRegistry.AddAccessRule($ruleRegistry)
        }
        Else
        {
            If($Type -eq "Remove")
            {
                $aclRegistry.RemoveAccessRule($ruleRegistry) | Out-Null
            }
        }
    }
    Catch
    {
        Throw $_.Exception.Message
    }
    Write-Host "Setting $RegistryRights permissions for account $Account" -ForegroundColor DarkCyan
    Set-Acl -path $Path -AclObject $aclRegistry
}

# ---------------------------------------------------------------------------
# Main logic
# ---------------------------------------------------------------------------

ForEach ($path in $paths) {
    Write-Host "Settings READ permissions for account" $apps_group "on registry key" $path -ForegroundColor Green
    Set-RegistryKeyPermission -Path $path -Type "Add" -Account $apps_group -RegistryRights "ReadKey" -InheritanceFlags "None" -PropagationFlags "None" -AccessControlType "Allow"
	Write-Host "Settings FullControl permissions for account" $cur_user -ForegroundColor Green
}

The customer rolled out the script and the ongoing monitoring over the following week confirmed that the problem was gone.

With the help of Process Monitor, the case of the Microsoft Edge crashes was successfully closed.

Read 236 times Last modified on Friday, 28 July 2017 16:25
More in this category: The Case of 'Something Went Wrong' »

Leave a comment

Make sure you enter all the required information, indicated by an asterisk (*). HTML code is not allowed.

Recent Posts