ShellEx.info

How to Verify If a Shell Extension DLL Is Digitally Signed: A Complete Windows Security Guide

Updated February 2026 — Windows 11 24H2

Every time you right-click a file, open File Properties, or browse a folder in Windows Explorer, dozens of DLL files execute inside explorer.exe. These Shell Extension DLLs come from Microsoft, third-party software vendors, and potentially from malware. The first line of defense against malicious or tampered shell extensions is digital signature verification.

A digitally signed DLL provides cryptographic proof that the file was created by the stated publisher and has not been modified since signing. An unsigned DLL — or one with an invalid signature — should be treated as suspicious until verified.

This guide shows you every method to verify DLL signatures on Windows, from simple GUI approaches to advanced PowerShell automation for auditing entire systems.


Why Digital Signatures Matter for Shell Extensions

Shell extensions are uniquely dangerous because they execute inside the Windows Explorer process (explorer.exe). Unlike standalone applications, they share memory and privileges with the shell. A malicious shell extension DLL can:

Digital signatures provide three critical assurances:

  1. Authenticity: The DLL was created by the publisher stated in the certificate
  2. Integrity: The DLL has not been modified since it was signed
  3. Non-repudiation: The publisher cannot deny having created the file

Method 1: File Properties (Quick Check)

The simplest way to check a DLL’s signature is through Windows itself.

Steps

  1. Navigate to the DLL file in File Explorer.
  2. Right-click → Properties.
  3. Click the Digital Signatures tab.

What to Look For

StatusMeaningAction
”Digital Signatures” tab exists with valid entriesFile is signed and not tamperedSafe (verify publisher name)
“Digital Signatures” tab is missingFile is unsignedInvestigate further
Signature present but “not valid”File has been modified after signingHigh risk — treat as potentially malicious
Certificate is expiredSigned with an old certificateUsually acceptable, but verify timestamp

Checking Signature Details

  1. In the Digital Signatures tab, select the signature and click Details.
  2. Click View Certificate.
  3. Verify:
    • Issued to: Should be the expected company (e.g., “NVIDIA Corporation”, “Dropbox, Inc.”)
    • Issued by: Should be a trusted CA (e.g., DigiCert, Sectigo, GlobalSign)
    • Valid from/to: Check if the certificate was valid when the file was signed

Method 2: Sigcheck (Sysinternals — Best for SSL Verification)

Sigcheck by Sysinternals is the professional choice for verifying DLL signatures. It provides far more detail than File Properties and supports batch scanning.

Installation

Download Sigcheck from the Microsoft website or via:

winget install Microsoft.Sysinternals.Sigcheck

Basic Usage

Check a single DLL:

sigcheck "C:\Windows\System32\nvcpl.dll"

Output example:

C:\Windows\System32\nvcpl.dll:
    Verified:       Signed
    Signing date:   10:23 AM 11/15/2025
    Publisher:      NVIDIA Corporation
    Company:        NVIDIA Corporation
    Description:    NVIDIA Display Properties Extension
    Product:        NVIDIA Display Properties
    Prod version:   8.1.940.0
    File version:   8.1.940.0
    MachineType:    64-bit

Scan All Shell Extension DLLs

To scan all DLLs in common shell extension directories:

sigcheck -u -e C:\Windows\System32\*.dll
sigcheck -u -e "C:\Program Files\*\*.dll"
sigcheck -u -e "C:\Program Files (x86)\*\*.dll"

The -u flag shows only unsigned files, making it easy to spot suspicious entries.

VirusTotal Integration

Sigcheck can submit file hashes to VirusTotal for multi-engine antivirus scanning:

sigcheck -vt "C:\path\to\suspicious.dll"

On first run, you must accept the VirusTotal Terms of Service. The output will show how many antivirus engines flagged the file.

Advanced: Verify Catalog Signatures

Some Windows system DLLs are signed via catalog files (.cat) rather than embedded signatures. Sigcheck handles this automatically, but you can force catalog checking:

sigcheck -c "C:\Windows\System32\shell32.dll"

Method 3: PowerShell (Automation and Bulk Auditing)

PowerShell provides cmdlets for digital signature verification, making it ideal for automated auditing.

Check a Single File

$sig = Get-AuthenticodeSignature "C:\Windows\System32\nvcpl.dll"
$sig | Format-List *

Key properties:

Audit All Shell Extension DLLs

This comprehensive script finds all registered shell extensions and checks their signatures:

# Enumerate all shell extension CLSIDs from the registry
$handlerPaths = @(
    "Registry::HKCR\*\shellex\ContextMenuHandlers",
    "Registry::HKCR\Directory\shellex\ContextMenuHandlers",
    "Registry::HKCR\Directory\Background\shellex\ContextMenuHandlers",
    "Registry::HKCR\Folder\shellex\ContextMenuHandlers"
)

$results = @()

foreach ($path in $handlerPaths) {
    if (!(Test-Path $path)) { continue }

    Get-ChildItem $path | ForEach-Object {
        $clsid = $_.GetValue("")
        if (!$clsid) { return }

        $inprocPath = "Registry::HKCR\CLSID\$clsid\InprocServer32"
        if (!(Test-Path $inprocPath)) { return }

        $dllPath = (Get-ItemProperty $inprocPath -ErrorAction SilentlyContinue)."(default)"
        if (!$dllPath -or !(Test-Path $dllPath)) { return }

        $sig = Get-AuthenticodeSignature $dllPath -ErrorAction SilentlyContinue

        $results += [PSCustomObject]@{
            Handler    = $_.PSChildName
            DllPath    = $dllPath
            Status     = $sig.Status
            Publisher  = $sig.SignerCertificate.Subject
            Issuer     = $sig.SignerCertificate.Issuer
            Expiry     = $sig.SignerCertificate.NotAfter
        }
    }
}

# Display results
$results | Format-Table -AutoSize

# Highlight unsigned or invalid
$suspicious = $results | Where-Object { $_.Status -ne "Valid" }
if ($suspicious) {
    Write-Host "`n⚠ SUSPICIOUS ENTRIES:" -ForegroundColor Red
    $suspicious | Format-Table -AutoSize
} else {
    Write-Host "`n✓ All shell extensions are properly signed!" -ForegroundColor Green
}

Export Results to CSV

For documentation and compliance:

$results | Export-Csv -Path "ShellExtensionAudit.csv" -NoTypeInformation
Write-Host "Audit exported to ShellExtensionAudit.csv"

Method 4: Windows Defender Application Control (WDAC)

In enterprise environments, you can enforce that only signed DLLs load as shell extensions using Windows Defender Application Control:

Create a Policy

# Create a base policy allowing only signed code
New-CIPolicy -Level Publisher -FilePath "BasePolicy.xml" -UserPEs

# Add specific DLL rules if needed
Add-SignerRule -FilePath "BasePolicy.xml" -CertificatePath "vendor_cert.cer" -Kernel -User

# Convert and deploy
ConvertFrom-CIPolicy -XmlFilePath "BasePolicy.xml" -BinaryFilePath "BasePolicy.p7b"

Test with Unsigned DLL

When WDAC is active, any unsigned shell extension DLL will be blocked from loading into explorer.exe. The block is logged in Event Viewer under:

Applications and Services Logs → Microsoft → Windows → CodeIntegrity → Operational

Understanding Certificate Chains

A valid digital signature relies on a chain of trust:

Root CA (DigiCert, GlobalSign, etc.)
    └── Intermediate CA
        └── Publisher Certificate (e.g., "NVIDIA Corporation")
            └── Signature on nvcpl.dll

Common Issues

IssueCauseSolution
”Certificate chain not trusted”Root CA not in Windows trust storeUpdate Windows root certificates via Windows Update
”Certificate has expired”Publisher’s code signing cert expiredCheck if the signature has a valid timestamp — timestamped sigs remain valid after cert expiry
”Signature is invalid”File was modified after signingCritical — do not load this DLL. Scan with antivirus immediately
”Cross-signed certificate”Publisher uses a cross-signing chainUsually legitimate — verify the root CA

Checking the Timestamp

A properly timestamped signature remains valid even after the certificate expires. Check with:

$sig = Get-AuthenticodeSignature "file.dll"
$sig.TimeStamperCertificate | Format-List Subject, Issuer, NotBefore, NotAfter

If TimeStamperCertificate is $null, the signature has no timestamp, and it will become invalid when the signing certificate expires.


Automated Monitoring with Task Scheduler

Set up a scheduled task to audit shell extension signatures weekly:

$script = @'
$results = @()
# ... (use the audit script from Method 3 above)
$suspicious = $results | Where-Object { $_.Status -ne "Valid" }
if ($suspicious) {
    $body = $suspicious | ConvertTo-Html | Out-String
    # Send alert (email, Teams webhook, Event Log, etc.)
    Write-EventLog -LogName Application -Source "ShellExtAudit" -EventId 1001 -EntryType Warning -Message "Unsigned shell extensions found: $body"
}
'@

$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -Command $script"
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At "9:00am"
Register-ScheduledTask -TaskName "ShellExtensionSignatureAudit" -Action $action -Trigger $trigger -RunLevel Highest

Red Flags: When to Be Concerned

Be especially cautious if you find a shell extension DLL that:

If any of these conditions are met, disable the extension immediately using ShellExView and scan the file with multiple antivirus engines.


Summary

Verifying shell extension DLL signatures is a critical security practice. Use:

  1. File Properties for quick one-off checks
  2. Sigcheck for professional verification with VirusTotal integration
  3. PowerShell for automated bulk auditing of all registered handlers
  4. WDAC for enterprise enforcement of signed-only policies
  5. Scheduled tasks for ongoing monitoring

Found an unsigned suspicious DLL?

Scan it immediately with Malwarebytes to check for rootkits, trojans, and zero-day exploits.

Get Malwarebytes Premium →