Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CLR-Unhook — Moderne Sicherheitsprodukte (CrowdStrike, Bitdefender, SentinelOne usw.) haken die nLoadImage-Funktion in clr.dll ein, um das Laden von .NET-Assemblys im Speicher abzufangen und zu scannen. Dieses Tool entfernt den Hook dieser Funktion. | Kitploit
Tools/GitHubGitHub/hwbp/clr-unhook
DefensivwerkzeugeExploitationPost-ExploitationPenetrationstestsRed TeamingPayload-Entwicklung
GitHubhwbp/clr-unhook

CLR-Unhook

Moderne Sicherheitsprodukte (CrowdStrike, Bitdefender, SentinelOne usw.) haken die nLoadImage-Funktion in clr.dll ein, um das Laden von .NET-Assemblys im Speicher abzufangen und zu scannen. Dieses Tool entfernt den Hook dieser Funktion.

Repository anzeigen
21722vor 8 MonatenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CLR Unhooking Tool

  • Hinweis: Damit dies den Effekt einer sauberen CLR hat, müsstest du die DLL manuell von der Festplatte in den Speicher mappen. Du kannst LoadLibraryA/W nicht verwenden, da Antivirenlösungen das DLL-Ladeereignis erkennen und sie möglicherweise sofort hooken. Wenn du dieses Verhalten möchtest, kannst du vorhandene manuelle Mapper auf GitHub suchen und einen in deine Codebasis integrieren. Ich füge hier keinen hinzu, da AV-Anbieter das im Allgemeinen nicht schätzen.

Ein natives C++-Dienstprogramm, das EDR/AV-Hooks in der .NET Common Language Runtime umgeht, indem es die ursprüngliche Implementierung der nLoadImage-Funktion wiederherstellt.

Kurzbeschreibung

Dieses Tool entfernt Hooks von Sicherheitsprodukten aus der nLoadImage-Funktion der CLR – dem kritischen nativen Einstiegspunkt, der das gesamte In-Memory-Laden von .NET-Assemblies abwickelt. Indem es die saubere clr.dll von der Festplatte liest und die gehookten Funktionsbytes im Speicher überschreibt, stellt es das ursprüngliche CLR-Verhalten wieder her und ermöglicht es Assembly.Load(byte[]), ohne EDR-Überprüfung oder -Scanning ausgeführt zu werden.

Was macht dieses Tool?

Moderne Sicherheitsprodukte (BitDefender, CrowdStrike, SentinelOne usw.) hooken die nLoadImage-Funktion in clr.dll, um In-Memory-.NET-Assembly-Ladevorgänge abzufangen und zu scannen. Dieses Tool entfernt den Hook dieser Funktion, indem es:

  1. Die saubere clr.dll von der Festplatte liest
  2. Die ursprünglichen nLoadImage-Bytes findet
  3. Die gehookte Version im Speicher überschreibt

Nach dem Unhooking wird Assembly.Load(byte[]) ohne EDR-Überprüfung ausgeführt.

nLoadImage verstehen

nLoadImage ist die kritische native Funktion, die das gesamte In-Memory-Assembly-Laden in der .NET-Laufzeit abwickelt. Sie ist in verwaltetem Code als InternalCall deklariert, was bedeutet, dass sie keine C#-Implementierung hat – stattdessen ist sie eine direkte Brücke zum nativen CLR-Code.

Die Aufrufkette:

root@kitploit:~
Managed Code (C#)
    ↓
Assembly.Load(byte[])
    ↓
RuntimeAssembly.nLoadImage(...) [InternalCall - no managed body]
    ↓
clr.dll!AssemblyNative::LoadImage (Native C++ implementation)
    ↓
Assembly loaded into AppDomain

Warum es kritisch ist:

Nahezu jeder In-Memory-Assembly-Ladevorgang läuft über nLoadImage. Die Methode Assembly.Load(byte[]) und ihre Überladungen (einschließlich des Ladens mit Symbolbytes) rufen intern alle nLoadImage auf. Wenn du Assembly.Load(byte[]) aufrufst, übergibt der verwaltete Code in mscorlib.dll dein Byte-Array über RuntimeAssembly.nLoadImage(), das mit [MethodImpl(MethodImplOptions.InternalCall)] markiert ist – das bedeutet, dass sein Rumpf in C# leer ist und die Ausführung sofort zum nativen CLR-Code springt.

Selbst Szenarien mit dynamischer Codegenerierung – Serialisierungsframeworks, die zur Laufzeit Assemblies erzeugen, XML-Serializer-Generierung und Red-Team-Tools wie Cobalt Strikes execute-assembly – laufen alle über diese einzelne Funktion.

Native Implementierung:

Der nLoadImage-InternalCall-Stub in mscorlib.dll zeigt auf die native C++-Funktion AssemblyNative::LoadImage in clr.dll. Diese Funktion:

  • Parst die PE-Header aus dem Byte-Array
  • Validiert Metadaten und IL-Code
  • Allokiert Speicher für die Assembly
  • Registriert die Assembly in der AppDomain
  • Löst Post-Load-Ereignisse aus (ETW, AMSI-Scanning in .NET 4.8+)
  • Behandelt Mixed-Mode-Assemblies (nativ + verwaltet)
  • Erzwingt die Strong-Name-Validierung

In .NET Framework 4.8+ übergibt jeder nLoadImage-Aufruf die Assembly-Bytes automatisch an die AMSI von Windows Defender (AmsiScanBuffer) zum Scannen vor der Ausführung, was es zu einem kritischen Engpass für Sicherheitsprodukte macht.

Funktionssignatur (.NET Framework 4.7+):

root@kitploit:~
[MethodImpl(MethodImplOptions.InternalCall)]
static internal extern Assembly nLoadImage(
    byte[] rawAssembly,              // PE bytes
    byte[] rawSymbolStore,           // Optional PDB bytes
    Evidence evidence,               // CAS evidence (obsolete)
    ref StackCrawlMark stackMark,    // Security stack marker
    bool fIntrospection,             // Reflection-only flag
    bool fSkipIntegrityCheck,        // Skip integrity validation
    SecurityContextSource securityContextSource  // Security context
);

Wenn du Assembly.Load(byte[]) aufrufst, wird nLoadImage mit diesen typischen Parametern aufgerufen:

root@kitploit:~
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RuntimeAssembly.nLoadImage(
    rawAssembly,                            // Your byte array
    null,                                   // rawSymbolStore
    null,                                   // evidence
    ref stackMark,                          // LookForMyCaller
    false,                                  // fIntrospection
    SecurityContextSource.CurrentAssembly   // securityContextSource
);

Der Parameter fIntrospection steuert, ob die Assembly zur Ausführung geladen wird (false) oder nur zur Reflexionsprüfung (true). Die Methode Assembly.ReflectionOnlyLoad(byte[]) ruft nLoadImage mit fIntrospection=true auf, was die Untersuchung von Metadaten ohne Codeausführung ermöglicht.

Warum EDR es hookt:

Da nLoadImage der einzige Einstiegspunkt für alle In-Memory-Assembly-Ladevorgänge ist, hooken EDR-Produkte es auf nativer Ebene in clr.dll. Dadurch können sie:

  • Jede Assembly prüfen, bevor sie geladen wird
  • Byte-Arrays auf schädliche Muster scannen
  • Die Ausführung blockieren, bevor .NET die Assembly überhaupt verarbeitet
  • AMSI/ETW-Evasionstechniken umgehen (da der Hook unter diesen Ebenen liegt)

Traditionelle Bypasses (AMSI-Patching, ETW-Deaktivierung) beeinflussen Hooks auf CLR-Ebene nicht, da sie auf einer höheren Ebene im Stack agieren. Der Hook erfolgt innerhalb der CLR selbst, bevor AMSI überhaupt aufgerufen wird.

Verwendung

Lokaler Prozess (aktueller Prozess)

root@kitploit:~
CLRUnhook.exe

Entfernt den Hook der CLR im aktuellen Prozess. Hinweis: Dies funktioniert nur, wenn die CLR bereits geladen ist (d. h., wenn du eine .NET-Anwendung ausführst oder die CLR manuell geladen hast).

Remote-Prozess (einen anderen Prozess anvisieren)

root@kitploit:~
CLRUnhook.exe powershell.exe

CLRUnhook.exe 1234

Entfernt den Hook der CLR in einem Remote-Prozess.

Beispielausgabe

Erfolgreiches Remote-Unhooking

root@kitploit:~
=== CLR Unhooking Tool ===

[*] Mode -> Remote Process Unhooking
[*] Target -> PID 21436
[+] Found PID -> 21436
[*] Unhooking CLR->nLoadImage in remote process...
[DEBUG] Remote mode enabled
[DEBUG] Found clr.dll at 0x00007FFD38CB0000
[DEBUG] CLR path -> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
[DEBUG] CLR module size -> 10108928 bytes
[DEBUG] Read 10108928 bytes from remote process
[DEBUG] Searching for 'nLoadImage' in module (size: 10108928)
[DEBUG] Remote base address: 0x00007FFD38CB0000
[DEBUG] Scanning for string 'nLoadImage' (11 bytes)...
[DEBUG] Found string at RVA 0x7c12b8
[DEBUG] Searching for remote pointer: 0x7ffd394712b8
[DEBUG] Found pointer at offset 0x7a4340
[DEBUG] Valid function pointer found at RVA 0x5e4f30
[DEBUG] Found nLoadImage at RVA 0x00000000005E4F30
[DEBUG] Hooked function address -> 0x00007FFD39294F30
[DEBUG] Clean function at offset 0x00000000005E4F30 in disk file
[DEBUG] Reading hooked bytes before patch...
[DEBUG] First 16 bytes BEFORE unhook:
       4C 8B DC 49 89 5B 08 49 89 73 10 4D 89 4B 20 57
[DEBUG] Clean bytes from disk:
       8B 4B 78 E8 88 A9 EA FF C6 44 24 28 00 80 3D A4
[DEBUG] Wrote 30 bytes successfully
[DEBUG] First 16 bytes AFTER unhook:
       8B 4B 78 E8 88 A9 EA FF C6 44 24 28 00 80 3D A4
[DEBUG] VERIFICATION SUCCESS: Patched bytes match clean bytes!
[+] SUCCESS -> CLR nLoadImage unhooked in remote process!
[+] EDR/AV hooks bypassed

[*] Press Enter to exit...

Die Hook-Kette

root@kitploit:~
Managed Code (C#)
    ↓
Assembly.Load(byte[])
    ↓
RuntimeAssembly.nLoadImage(...) [InternalCall]
    ↓
clr.dll!AssemblyNative::LoadImage
    ↓
[EDR HOOK] ← We bypass this
    ↓
Original CLR Code

Der Unhooking-Prozess

  1. Gehookte Funktion lokalisieren – Findet nLoadImage in der geladenen clr.dll (aktuell gehooked)
  2. Saubere Kopie laden – Liest die ursprüngliche clr.dll aus C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
  3. Saubere Bytes extrahieren – Nimmt die ersten 30 Bytes der ursprünglichen Funktion. .NET ist JIT, wir wollen keine Probleme bekommen.
  4. Hook überschreiben – Patcht die gehookte Version mit den sauberen Bytes

Funktionserkennung

Verwendet Muster-Scanning, um nLoadImage zu lokalisieren:

  1. Suche nach der Zeichenfolge „nLoadImage“ im Modulspeicher
  2. Finde den Zeiger auf diese Zeichenfolge
  3. Lokalisiere den Funktionszeiger neben dem Zeichenfolgenzeiger
  4. Validiere, dass die Adresse innerhalb der Modulgrenzen liegt

Danksagungen

Technik-Recherche:

  • Matthew Graeber (@mattifestation) – Reverse Engineering von InternalCall-Methoden und CLR-Interna

Implementierung:

  • HWBP – CLR-Unhooking durch Speicherwiederherstellung
  • @Evilbytecode – Hat mir beim Unhooking geholfen, ich hatte einige Probleme damit, dass .NET JIT ist.

Haftungsausschluss

NUR FÜR BILDUNGSZWECKE UND AUTORISIERTE SICHERHEITSFORSCHUNG.

Die unbefugte Verwendung dieses Tools zur Umgehung von Sicherheitskontrollen kann gegen Gesetze zum Computerbetrug verstoßen (CFAA, entsprechende Gesetze). Verwende es nur auf Systemen, die dir gehören oder für die du eine ausdrückliche schriftliche Genehmigung zum Testen hast.

Referenzen

  • Reverse Engineering InternalCall Methods – Matthew Graeber
  • Microsoft .NET Reference Source
  • Dokumentation zur CLR-Assembly-Ladepipeline
Tool herunterladen