
Auf Hardware-Breakpoints (DR0-DR7) basierende, patch-lose User-Mode-Hooking- und Telemetrie-Instrumentierungs-Engine (AMSI, WLDP & ETW-PoC).
Ein Proof-of-Concept (POC) aus der Sicherheitsforschung, das auf Hardware-Breakpoints (CPU-Debug-Register) basierendes Funktions-Hooking als Alternative zum herkömmlichen In-Memory-Code-Patching demonstriert.
Zweck & Umfang
Dieses Repository wird ausschließlich für defensive Sicherheitsforschung, Red-/Purple-Team-Ausbildung, Detection Engineering und akademische Studien der Windows-Interna veröffentlicht. Es zeigt, wie ein Angreifer Prozessor-Debug-Register missbrauchen könnte, um benutzermodusseitige Sicherheitstelemetrie zu neutralisieren – und, ebenso wichtig, was Verteidiger überwachen sollten, um solche Techniken zu erkennen. Der Autor ist nicht für jeglichen Missbrauch dieses Codes verantwortlich. Die Verwendung dieser Technik gegen Systeme ohne ausdrückliche Genehmigung ist illegal und verstößt in den meisten Rechtsräumen gegen die einschlägigen Computerbetrugs- und Missbrauchsgesetze. Setzen Sie dies nicht in einer Umgebung ein, die Sie nicht besitzen oder für die Sie keine ausdrückliche schriftliche Genehmigung zum Testen haben.
mora_hwbp.c implementiert eine DLL, die nach dem Laden/Injizieren in einen Zielprozess (z. B. einen PowerShell-Host) vier Benutzermodus-Funktionen ausschließlich über CPU-Hardware-Breakpoints hookt, die in den architektonischen Debug-Registern (DR0–DR7) jedes Threads im Prozess gespeichert sind:
Ein prozessweiter Vectored Exception Handler (VEH) empfängt die von den Debug-Registern ausgelösten EXCEPTION_SINGLE_STEP-Fehler (0x80000004), simuliert den erfolgreichen Rückgabepfad der ursprünglichen Funktion, indem er den Ausnahmekontext umschreibt, und setzt die Ausführung fort – alles ohne ein einziges Byte ausführbaren Speichers zu verändern.
Das macht die Technik sowohl aus offensiver als auch aus defensiver Sicht besonders interessant:
.text-Abschnitten suchen (klassisches Inline-Hooking, EAT/IAT-Patching oder Etwp*-Stubbing).GetThreadContext/SetThreadContext-Syscall-Muster), die zur Erkennung genutzt werden können.Traditionelle Hooking-Ansätze im Benutzermodus – Inline-Detours (Überschreibungen von 5–14 Bytes), Import Address Table (IAT)-Hooking und Export Address Table (EAT)-Hooking – haben eine gemeinsame Schwäche: Sie verändern Speicher, den Integritätsscanner und ETW beobachten können.
Moderne AV/EDR-Produkte implementieren:
pageguard/guard-page-Tricks, VirtualProtect-Übergänge zu PAGE_EXECUTE_READWRITE und Abschnitts-Hash-Abweichungen erkennen.Hardware-Breakpoints umgehen all dies:
.text zu scannen.SetThreadContext gesetzt, was die klassischen „Speicher geändert“-Signale, die Integritätsscanner verwenden, nicht auslöst.Dieses POC untersucht die Wirksamkeit und Erkennbarkeit dieser Technik gegen AMSI (Antimalware Scan Interface), WLDP (Windows Lockdown Policy) und ETW (Event Tracing for Windows) – die drei am weitesten verbreiteten Sicherheitsprimitiven im Benutzermodus des modernen Windows-Sicherheitsstapels.
AMSI ist der Integrationspunkt der Windows-Plattform, der Anwendungen (PowerShell, Office, VBScript, .NET-Hosts usw.) ermöglicht, Inhalts-Scans bei registrierten Antimalware-Anbietern anzufordern. Zwei Einstiegspunkte sind von besonderem Interesse:
AmsiScanBuffer(HANDLE hamsiContext, PVOID buffer, ULONG length, LPCWSTR contentName, HANDLE hamsiSession, AMSI_RESULT *pResult)AmsiScanString(HANDLE hamsiContext, LPCWSTR string, LPCWSTR contentName, HANDLE hamsiSession, AMSI_RESULT *pResult)Indem das zurückgegebene AMSI_RESULT auf AMSI_RESULT_CLEAN (0) erzwungen wird, glaubt die Skript-Engine, dass der Inhalt geprüft und als gutartig befunden wurde, sodass die Ausführung ungehindert fortgesetzt wird.
WLDP implementiert die Richtlinienauswertung für Windows Defender Application Control (WDAC / Device Guard). WldpIsClassInApprovedList beantwortet, ob eine bestimmte COM-Klasse (identifiziert durch GUID) gemäß der aktuellen Richtlinie zulässig ist. AMSI fragt intern WLDP ab, um zu entscheiden, ob bestimmte Skript-/Inhaltsklassen „vertrauenswürdig“ sind (in der genehmigten Liste). Wenn die Funktion die Klasse als genehmigt meldet, kann AMSI auf eine zusätzliche Prüfung dieses Inhaltstyps verzichten.
Die DLL setzt den Ausgabeparameter isApproved (RDX) auf TRUE und gibt S_OK zurück, sodass die bewertete Klasse als vertrauenswürdig erscheint.
EtwEventWrite in ntdll.dll ist die zentrale Senke im Benutzermodus für praktisch alle ETW-Ereignisemissionen auf dem System. Das Unterdrücken hat weitreichende Nebenwirkungen, die für die Sicherheitsüberwachung relevant sind:
Microsoft-Windows-DotNETRuntime)Die DLL gibt einfach ERROR_SUCCESS (0) zurück, ohne die eigentliche Funktion auszuführen.
┌──────────────────────────────────────────────────────────────────────────┐ │ Target Process (e.g. powershell.exe) │ │ │ │ ┌──────────────────────────┐ ┌──────────────────────────────────┐│ │ │ mora_hwbp.dll │ │ CPU / Windows ││ │ │ │ │ ││ │ │ DllMain / InstallHook │ │ Thread A Thread B ││ │ │ │ │ │ ┌────────┐ ┌────────┐ ││ │ │ ▼ │ │ │ DR0..3 │ │ DR0..3 │ ││ │ │ Resolve exports │ │ └────────┘ └────────┘ ││ │ │ (amsi/wldp/ntdll) │ │ ││ │ │ │ │ │ #DB (single-step) ││ │ │ ▼ │ │ exception ──► Windows Dispatch ││ │ │ AddVectoredException │ │ │ ││ │ │ Handler(VEH) │ │ ▼ ││ │ │ │ │ │ ┌─────────────────────────────┐ ││ │ │ ▼ │ │ │ VectoredHandler (ours) │ ││ │ │ SetHwbpOnThread(ALL) │ │ │ • match #DB address │ ││ │ │ │ │ │ │ • rewrite context (RIP/RSP)│ ││ │ │ ▼ │ │ │ • spoof return value (RAX) │ ││ │ │ MonitorThread ◄──┐ │ │ │ • continue execution │ ││ │ │ (re-hook every │ │ │ └─────────────────────────────┘ ││ │ │ 500ms) └──────┘ │ ││ │ └──────────────────────────┘ └──────────────────────────────────┘│ └──────────────────────────────────────────────────────────────────────────┘
**High-level flow:**
1. Die DLL wird in den Zielprozess geladen (über beliebige Injektionstechniken — siehe [Verwendung](#injection--usage-example)).
2. Bei `DLL_PROCESS_ATTACH` (oder über den exportierten `InstallHook`) werden die Ziel-Exporte mit `GetProcAddress` aufgelöst (optional wird das Laden von Modulen über `LoadLibraryW` erzwungen).
3. Ein **Vectored Exception Handler** wird als **erster** Handler im Prozess registriert (`AddVectoredExceptionHandler(1, ...)`).
4. Der **aktuelle Thread** wird sofort gehookt, danach werden **alle vorhandenen Threads** im Prozess über `CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0)` aufgezählt und gehookt.
5. Ein **Monitor-Thread** wacht alle 500 ms auf und wendet die Breakpoints auf jeden Thread erneut an — einschließlich **neu erstellter Threads** — und gewährleistet so die Persistenz der Hooks, selbst wenn ein Thread nach dem Hooken erzeugt wird oder Breakpoints extern gelöscht werden.
6. Wenn eine gehookte Funktion in einem beliebigen Thread aufgerufen wird, löst die CPU eine `#DB`-Single-Step-Ausnahme aus; Windows leitet sie an den VEH weiter, der eine harmlose Rückkehr simuliert und die Ausführung fortsetzt.
### Beispiel-Debug-Ausgabe

*Abbildung 1 — Beispielhafte Diagnoseausgabe, erfasst mit Sysinternals DebugView. Jede Zeile meldet die aufgelöste Zieladresse und den laufenden Trefferzähler für das jeweilige Debug-Register.*
---
## Technischer Deep Dive
### 5.1 Hardware-Breakpoints auf x64
Auf x86/x64 stellt jede CPU **vier Hardware-Debug-Adressregister** (`DR0`–`DR3`) und ein Kontrollregister (`DR7`) bereit. Jeder Thread, der mit einem von Null verschiedenen Breakpoint in `DR0`–`DR3` ausgeführt wird, löst eine Ausnahme aus, sobald der Befehlszeiger diese Adresse erreicht (oder ein Datenzugriff den konfigurierten Bedingungen entspricht). Das Statusregister `DR6` zeichnet auf, welcher Breakpoint ausgelöst hat.
Hardware-Breakpoints sind **kontextsensitiv**: Sie werden in der `CONTEXT`-Struktur des Threads gespeichert und gelten nur für den Thread, auf dem sie gesetzt wurden. Aus diesem Grund muss eine robuste Implementierung die Breakpoints auf **jedem Thread** des Prozesses setzen (und sie für neue Threads kontinuierlich erneut anwenden).
### 5.2 Layout der Debug-Register (DR0–DR7)
`DR7` ist ein Bitfeld, das die Aktivierung und das Verhalten der Breakpoints steuert:
| Bits | Feld | Bedeutung |
|--------|--------|-----------------------------------------------------|
| `0` | `L0` | Lokale Aktivierung für Breakpoint 0 (DR0) |
| `2` | `L1` | Lokale Aktivierung für Breakpoint 1 (DR1) |
| `4` | `L2` | Lokale Aktivierung für Breakpoint 2 (DR2) |
| `6` | `L3` | Lokale Aktivierung für Breakpoint 3 (DR3) |
| `8` | `LE` | Legacy lokale Aktivierung (aus Kompatibilitätsgründen beibehalten) |
| `9` | `GE` | Legacy globale Aktivierung (aus Kompatibilitätsgründen beibehalten) |
| `16–17`| `R/W0` | Zugriffstyp für BP0 (`00` = Befehlsausführung) |
| `18–19`| `Len0` | Länge für BP0 (`00` = 1 Byte) |
| `20–21`| `R/W1` | Zugriffstyp für BP1 (`00` = Befehlsausführung) |
| `22–23`| `Len1` | Länge für BP1 (`00` = 1 Byte) |
| `24–25`| `R/W2` | Zugriffstyp für BP2 (`00` = Befehlsausführung) |
| `26–27`| `Len2` | Länge für BP2 (`00` = 1 Byte) |
| `28–29`| `R/W3` | Zugriffstyp für BP3 (`00` = Befehlsausführung) |
| `30–31`| `Len3` | Länge für BP3 (`00` = 1 Byte) |
Alle vier Breakpoints sind für die **Ausführung (Befehlsabruf) auf einem einzelnen Byte** konfiguriert, was die passende Bedingung für Funktions-Einstiegshooks darstellt.
### 5.3 Der Vectored Exception Handler (VEH)
Wenn ein Breakpoint ausgelöst wird, erzeugt der Prozessor eine `#DB`-Ausnahme. Unter x64-Windows leitet die Dispatch-Routine von `ntdll` diese über die prozessweite **VEH-Kette** weiter, bevor die Structured-Exception-Handler-Kette (SEH) des Threads durchlaufen wird. Der Handler in diesem Projekt:
1. **Filtert** — behandelt nur `EXCEPTION_SINGLE_STEP` (`0x80000004`); alles andere fällt auf `EXCEPTION_CONTINUE_SEARCH` zurück.
2. **Gleicht ab** — vergleicht `ExceptionAddress` mit den vier bekannten Funktionsadressen.
3. **Schreibt den Kontext neu**:
- `RIP = *(RSP)` → "return" zum ursprünglichen Aufrufer, indem die Rücksprungadresse vom Stack genommen wird.
- `RSP += 8` → simuliert ein `ret` (x64-Einzelinstruktions-Unwind).
- `RAX = 0` → täuscht `S_OK` / `ERROR_SUCCESS` vor (erfolgreicher Rückgabecode).
- `DR6 &= ~0xF` → löscht die Breakpoint-Statusbits, sodass die Anweisung später ohne unerwünschten Zustand erneut ausgeführt werden kann.
4. **Verändert Ausgabeparameter** (siehe [5.4](#54-per-component-interception-logic)).
5. **Gibt `EXCEPTION_CONTINUE_EXECUTION` zurück**, was Windows anweist, den Thread mit dem geänderten Kontext neu zu starten — d. h. die Ausführung wird beim *Aufrufer* fortgesetzt und die eigentliche Zielfunktion **läuft nie**.
Jede Interception-Stelle ist zusätzlich mit einem SEH-`__try/__except`-Guard umschlossen, sodass ein fehlerhaftes oder unerwartetes Stack-Layout den Prozess nicht zum Absturz bringen kann — ein Robustheitsgesichtspunkt für feindliche/gehärtete Ziele.
### 5.4 Interceptionslogik pro Komponente
**DR0 — `AmsiScanBuffer`** (x64, die ersten 6 Argumente in `RCX, RDX, R8, R9, [RSP+0x28], [RSP+0x30]`):```
HRESULT AmsiScanBuffer(HANDLE, PVOID, ULONG, LPCWSTR, HANDLE, AMSI_RESULT* pResult);
[RSP+0x28] [RSP+0x30]
AMSI_RESULT_CLEAN (0) in den sechsten Parameter (pResult, bei [RSP+0x30]).S_OK (0) in RAX zurück.DR1 — AmsiScanString (x64, die ersten 5 Argumente in RCX, RDX, R8, R9, [RSP+0x28]):```
HRESULT AmsiScanString(HANDLE, LPCWSTR, LPCWSTR, HANDLE, AMSI_RESULT* pResult);
[RSP+0x28]
- Schreibt `AMSI_RESULT_CLEAN (0)` in den 5. Parameter (`pResult`, bei `[RSP+0x28]`).
- Gibt `S_OK (0)` in `RAX` zurück.
**DR2 — `WldpIsClassInApprovedList`** (die ersten 3 Argumente in `RCX, RDX, R8`):```
HRESULT WldpIsClassInApprovedList(const GUID* classId, PBOOL isApproved, DWORD evalCriteria);
RCX RDX R8
TRUE in *isApproved (über RDX).S_OK (0) in RAX zurück.DR3 — EtwEventWrite (erste 4 Argumente in RCX, RDX, R8, R9):```
ULONG EtwEventWrite(HANDLE RegHandle, PCEVENT_DESCRIPTOR EventDescriptor,
ULONG UserDataCount, PEVENT_DATA_DESCRIPTOR UserData);
- Gibt `ERROR_SUCCESS (0)` in `RAX` zurück, ohne einen Ausgabeparameter zu berühren.
- Konsequenz: ETW-Anbieter erhalten **keine** Ereignisse vom gehookten Prozess, wodurch die Protokollierung von Skriptausführung, Modulladungen, Prozesserstellung und AMSI-Telemetrie unterdrückt wird.
### 5.5 Thread-Verwaltung & Hook-Persistenz
Da Debug-Register pro Thread gelten, muss die Engine die Hooks kontinuierlich aufrechterhalten:
1. **Sofortiges Hooken** — `DllMain` (oder `InstallHook`) hookt den aufrufenden Thread mit `SetHwbpOnThread(GetCurrentThread())`.
2. **Durchlauf über alle Threads** — `HookAllThreads()` listet jeden Thread im Prozess über einen `TH32CS_SNAPTHREAD`-Snapshot auf, unterbricht jeden fremden Thread (`SuspendThread`), setzt die Breakpoints (`SetHwbpOnThread`), setzt ihn fort und schließt das Handle. Das Unterbrechen verhindert einen Wettlauf, bei dem der Thread mitten im Kontextwechsel zwischen `GetThreadContext` und `SetThreadContext` einen Fehler auslöst.
3. **Persistenz-Monitor** — `MonitorThreadProc` läuft in einer Schleife mit `Sleep(500)` und ruft alle 500 ms `HookAllThreads()` auf. Dadurch werden **entfernte Breakpoints wieder gesetzt** (z. B. durch einen externen `SetThreadContext`-Aufruf, ein Debugging-Tool oder das Beenden/Erzeugen von Threads) und **nach dem initialen Hook erstellte Threads abgedeckt**.
4. **Synchronisierung** — `HookAllThreads` läuft unter einem `CRITICAL_SECTION` (`g_HookLock`), sodass der Monitor-Thread und die anfängliche Hook-Routine keine Kontextwechsel überlappen.
5. **Sauberes Entfernen** — `UninstallHook` stoppt den Monitor, löscht `DR0–DR7` auf jedem Thread und hebt die VEH-Registrierung auf.
> **Antwort auf die Frage zur „Hook-Persistenz“ explizit:** ja — wenn die Breakpoints von einem Thread entfernt werden (durch einen anderen Agenten, einen Debugger oder eine EDR), **setzt der Monitor-Thread sie innerhalb von 500 ms erneut**. Darüber hinaus wird jeder nach dem Laden der DLL erstellte Thread innerhalb eines Monitorzyklus gehooked. Der einzige zuverlässige Weg, diese spezifische Engine zu überwinden, besteht darin, den Monitor-Thread zu beenden *und* die VEH zu entfernen *und* die Register im selben Fenster zu löschen — oder Anti-Debugging einzusetzen, das `SetThreadContext` von vornherein verweigert.
---
## Exportierte API
| Export | Signature | Behavior |
|-------------------|------------------------------------|-----------------------------------------------------------------------|
| `InstallHook` | `BOOL WINAPI InstallHook(void)` | Ermittelt Zieladressen, registriert VEH, hookt alle Threads, startet den Monitor. |
| `UninstallHook` | `BOOL WINAPI UninstallHook(void)` | Stoppt Monitor, löscht Breakpoints auf allen Threads, entfernt VEH. |
| `GetStats` | `void WINAPI GetStats(void)` | Gibt aktuellen Hook-Status aus (über `OutputDebugStringA`) — Adresse, Trefferzähler. |
Die Trefferzähler (`g_HaveAmsiBuf`, `g_HaveAmsiStr`, `g_HaveWldp`, `g_HaveEtw`) werden mit `InterlockedIncrement` geführt und in der Debug-Ausgabe angezeigt, was nützlich ist, um zu validieren, dass die Interception in einer Laborumgebung tatsächlich stattfindet.
Beachten Sie, dass `DllMain` selbst die vollständige Hook-Sequenz bei `DLL_PROCESS_ATTACH` ausführt; die Exporte sind daher optionale Annehmlichkeiten für Szenarien, in denen die DLL zur Laufzeit geladen/entladen wird.
---
## Build-Anleitung
**Anforderungen:** Windows 10/11 x64, Visual Studio Build Tools (`icx.exe`), SDK.
DLL kompilieren (x64):```bat
icx.exe /nologo /O3 /MT /EHsc "mora_hwbp.c" /link /DLL /out:"mora_hwbp.dll" /LIBPATH:"C:\Program Files (x86)\Intel\oneAPI\compiler\latest\lib"
Flags explained:
| Flag | Purpose |
|---|
Das Ergebnis ist mora_hwbp.dll, die in einen Zielprozess geladen werden kann.
Die DLL muss in einen Prozess geladen werden, der AMSI/WLDP/ETW verwendet – ein PowerShell-Host ist das kanonische Testumfeld. Das Laden kann mit jeder gängigen DLL-Injection-Technik erfolgen. Eine minimale, eigenständige Demonstration mit Reflective/LoadLibrary-Injection kann mit einem kleinen C-Loader durchgeführt werden:```bat
rem Run from an x64 developer prompt (example with a generic loader)
loader.exe mora_hwbp.dll powershell.exe
Oder injizieren Sie für einen manuellen Labortest mit Ihren bevorzugten Tools und validieren Sie dann von PowerShell aus:```powershell
# 1. Inject mora_hwbp.dll into the PowerShell process (via external tool).
# 2. Verify that classic AMSI test vectors now return clean.
"AmsiTestSample:7e72c3ce-861b-4339-8740-0ac1484c1386"
Nur Laborvalidierung. Beobachten Sie mit einem Debugger oder
GetStats/OutputDebugString, dass alle vier Breakpoints Treffer melden, während Skriptinhalte ausgeführt werden.
Dieser POC dient einem doppelten Zweck: Genau die Eigenschaften, die ihn offensiv effektiv machen, sind das, wonach Verteidiger suchen sollten.
GetThreadContext(CONTEXT_DEBUG_REGISTERS) bei Prozessen mit hohem Wert abfragen und jeden Thread mit von Null verschiedenen DR0–DR3 außerhalb genehmigter Debugger-Profile prüfen.Microsoft-Windows-Kernel-Process + Thread-Ablaufverfolgung aktivieren und bei NtGetContextThread/NtSetContextThread warnen, die sicherheitsrelevante Prozesse betreffen.EtwEventWrite, Kernel-ETW, erneute Prüfung durch AMSI-Consumer) anstatt nur auf .text-Integrität.SetThreadContext pro Thread auf andere Prozesse als explizites Signal mit hoher Schwere behandelt werden.RCX/RDX/R8/R9, dann [RSP+0x20…]). Eine x86-Variante bräuchte eine Parameterrekonstruktion im Stil von [EBP+…].Sleep(500)-Iterationen; extrem schnelles Erzeugen von Threads in Kombination mit aggressivem Stripping könnte den Monitor theoretisch für ein paar hundert Millisekunden überholen.OutputDebugStringA – Die Diagnose ist auf einen Debug-Ausgabekanal angewiesen; in einer vollständig gestrippten/headless Umgebung sollten Sie einen Debugger anhängen oder die Ausgabe zur Laborbeobachtung umleiten.Dieses Projekt ist unter der MIT-Lizenz lizenziert – siehe LICENSE für Details.
Dieses Projekt wird ausschließlich für Bildungs- und Verteidigungsforschungszwecke veröffentlicht. Wenn Sie ein Sicherheitsanbieter, Blue Team oder Detection Engineer sind, werden Sie ermutigt, die Inhalte dieses Repositorys zu nutzen, um Ihre Erkennungsabdeckung für Evasion auf Basis von Hardware-Breakpoints zu verbessern. Wenn Sie feststellen, dass diese Technik in freier Wildbahn missbraucht wird, melden Sie dies über den Responsible-Disclosure-Prozess Ihres Unternehmens sowie über die entsprechenden Kanäle des Anbieters bzw. der Behörden.
Nutzung auf eigene Gefahr. Unautorisierte Nutzung dieser Technik kann geltendes Recht verletzen.
| Register | Gehookte Funktion | Modul | Zweck |
|---|
DR0 | AmsiScanBuffer | amsi.dll | AMSI-Inhaltsscans neutralisieren |
DR1 | AmsiScanString | amsi.dll | AMSI-Stringscans neutralisieren |
DR2 | WldpIsClassInApprovedList | wldp.dll | WLDP-Klassenfreigabe erzwingen (Device Guard / WDAC) |
DR3 | EtwEventWrite | ntdll.dll | ETW-Ereignisablaufverfolgung unterdrücken |
/O3 | Maximale Optimierung (Funktionscode, nicht erforderlich) |
/MT | Statische CRT-Verknüpfung (keine Runtime-DLL-Abhängigkeit) |
/EHsc | C++/SEH-Ausnahmebehandlung (für __try erforderlich) |
/DLL | Erzeugt eine DLL mit einer Exporttabelle |
| Artefakt | Beobachtbares Zeichen |
|---|
GetThreadContext / SetThreadContext-Aufrufe | Hochfrequente Kontextwechsel der Debug-Register bei anderen Prozessen/Threads (Kernel-ETW: Microsoft-Windows-Kernel-Process/Thread-APIs). |
Von Null verschiedene DR0–DR3 | Jeder Thread, dessen CONTEXT_DEBUG_REGISTERS eine Benutzermodus-Adresse außerhalb bekannter Debugger-Workflows enthält. |
DR7 lokale Aktivierungsbits (L0–L3) mit R/W = 00 | Nur-Ausführung-Breakpoints auf Threads, die nicht von einem Debugger verwaltet werden – eine starke Anomalie. |
EXCEPTION_SINGLE_STEP-Aufkommen | Hohe Raten von #DB-Ausnahmen (0x80000004), die aus dem VEH eines Prozesses stammen. |
| Erstchancen-VEH-Registrierung | Kürzlich hinzugefügter VEH (AddVectoredExceptionHandler) kurz vor einem #DB-Sturm. |
TH32CS_SNAPTHREAD + SuspendThread/ResumeThread | Wiederholte Thread-Aufzählungs- und -Unterbrechungsmuster (vom 500-ms-Monitor verwendet). |
Laden von wldp.dll/amsi.dll über LoadLibraryW, wenn diese nicht zuvor geladen waren | Anomale Modulladungen im Zielprozess. |
EtwEventWrite wird nie erreicht | Fehlen erwarteter ETW-Ereignisse (PowerShell-Operational-Logs bleiben stumm, während Skripte ausgeführt werden). |