Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CLR-Unhook — Les produits de sécurité modernes (CrowdStrike, Bitdefender, SentinelOne, etc.) accrochent la fonction nLoadImage à l'intérieur de clr.dll pour intercepter et analyser les chargements d'assembly .NET en mémoire. Cet outil désaccroche cette fonction. | Kitploit
Outils/GitHubGitHub/hwbp/clr-unhook
Outils DéfensifsExploitationPost-ExploitationTests d'IntrusionRed TeamingDéveloppement de Charges Utiles
GitHubhwbp/clr-unhook

CLR-Unhook

Les produits de sécurité modernes (CrowdStrike, Bitdefender, SentinelOne, etc.) accrochent la fonction nLoadImage à l'intérieur de clr.dll pour intercepter et analyser les chargements d'assembly .NET en mémoire. Cet outil désaccroche cette fonction.

Voir le dépôt
217229il y a 9 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Outil de déshooking CLR

  • Note: Pour que cela ait l'effet d'un CLR propre, vous devez mapper manuellement la DLL depuis le disque en mémoire. Vous ne pouvez pas utiliser LoadLibraryA/W, car les solutions antivirus détecteront l'événement de chargement de la DLL et pourraient la hooker immédiatement. Si vous voulez ce comportement, vous pouvez rechercher des mappeurs manuels existants sur GitHub et en intégrer un dans votre code. Je n'en inclus pas ici, car les éditeurs d'AV n'apprécient généralement pas cela.

Un utilitaire C++ natif qui contourne les hooks EDR/AV dans le Common Language Runtime .NET en restaurant l'implémentation originale de la fonction nLoadImage.

Description rapide

Cet outil supprime les hooks des produits de sécurité de la fonction nLoadImage du CLR - le point d'entrée natif critique qui gère tout le chargement d'assembly .NET en mémoire. En lisant le clr.dll propre depuis le disque et en écrasant les octets de la fonction hookée en mémoire, il restaure le comportement original du CLR, permettant à Assembly.Load(byte[]) de s'exécuter sans inspection ni analyse EDR.

Que fait cet outil ?

Les produits de sécurité modernes (BitDefender, CrowdStrike, SentinelOne, etc.) hookent la fonction nLoadImage dans clr.dll pour intercepter et analyser les chargements d'assembly .NET en mémoire. Cet outil déshooke cette fonction en :

  1. Lisant le clr.dll propre depuis le disque
  2. Trouvant les octets originaux de nLoadImage
  3. Écrasant la version hookée en mémoire

Après le déshooking, Assembly.Load(byte[]) s'exécute sans inspection EDR.

Comprendre nLoadImage

nLoadImage est la fonction native critique qui gère tout le chargement d'assembly en mémoire dans le runtime .NET. Elle est déclarée comme un InternalCall dans le code managé, ce qui signifie qu'elle n'a pas d'implémentation C# - c'est plutôt un pont direct vers le code natif du CLR.

La chaîne d'appel :

Code managé (C#)
    ↓
Assembly.Load(byte[])
    ↓
RuntimeAssembly.nLoadImage(...) [InternalCall - pas de corps managé]
    ↓
clr.dll!AssemblyNative::LoadImage (Implémentation C++ native)
    ↓
Assembly chargé dans AppDomain

Pourquoi c'est critique :

Presque tous les chargements d'assembly en mémoire passent par nLoadImage. La méthode Assembly.Load(byte[]) et ses surcharges (y compris le chargement avec des octets de symboles) invoquent nLoadImage en interne. Lorsque vous appelez Assembly.Load(byte[]), le code managé dans mscorlib.dll passe votre tableau d'octets via RuntimeAssembly.nLoadImage(), qui est marqué avec [MethodImpl(MethodImplOptions.InternalCall)] - ce qui signifie que son corps est vide en C# et que l'exécution saute immédiatement vers le code natif du CLR.

Même les scénarios de génération de code dynamique - frameworks de sérialisation qui émettent des assemblies à l'exécution, génération de sérialiseurs XML, et outils de red team comme execute-assembly de Cobalt Strike - passent tous par cette seule fonction.

Implémentation native :

Le stub InternalCall de nLoadImage dans mscorlib.dll pointe vers la fonction C++ native AssemblyNative::LoadImage dans clr.dll. Cette fonction :

  • Parse les en-têtes PE du tableau d'octets
  • Valide les métadonnées et le code IL
  • Alloue de la mémoire pour l'assembly
  • Enregistre l'assembly dans l'AppDomain
  • Déclenche les événements post-chargement (ETW, analyse AMSI dans .NET 4.8+)
  • Gère les assemblies en mode mixte (natif + managé)
  • Applique la vérification de nom fort

Dans .NET Framework 4.8+, chaque appel nLoadImage passe automatiquement les octets de l'assembly à l'AMSI de Windows Defender (AmsiScanBuffer) pour analyse avant exécution, ce qui en fait un point d'étranglement critique pour les produits de sécurité.

Signature de la fonction (.NET Framework 4.7+) :

[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
);

Lorsque vous appelez Assembly.Load(byte[]), il invoque nLoadImage avec ces paramètres typiques :

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

Le paramètre fIntrospection contrôle si l'assembly est chargé pour exécution (false) ou pour inspection en lecture seule (true). La méthode Assembly.ReflectionOnlyLoad(byte[]) appelle nLoadImage avec fIntrospection=true, permettant l'examen des métadonnées sans exécution de code.

Pourquoi les EDR le hookent :

Étant donné que nLoadImage est le point d'entrée unique pour tous les chargements d'assembly en mémoire, les produits EDR le hookent au niveau natif dans clr.dll. Cela leur permet de :

  • Inspecter chaque assembly avant son chargement
  • Analyser les tableaux d'octets pour des motifs malveillants
  • Bloquer l'exécution avant même que .NET ne traite l'assembly
  • Contourner les techniques d'évasion AMSI/ETW (car le hook se trouve en dessous de ces couches)

Les contournements traditionnels (patching AMSI, désactivation ETW) n'affectent pas les hooks au niveau du CLR car ils opèrent à un niveau supérieur dans la pile. Le hook se produit à l'intérieur même du CLR, avant même que l'AMSI ne soit invoquée.

Utilisation

Processus local (processus actuel)

CLRUnhook.exe

Déshooke le CLR dans le processus actuel. Remarque : Cela fonctionne uniquement si le CLR est déjà chargé (c'est-à-dire exécuté depuis une application .NET ou après avoir chargé le CLR manuellement).

Processus distant (cibler un autre processus)

CLRUnhook.exe powershell.exe

CLRUnhook.exe 1234

Déshooke le CLR dans un processus distant.

Exemple de sortie

Déshooking réussi à distance

=== 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...

La chaîne de hook

Télécharger l’outil