Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Ferramentas/GitHubGitHub/hwbp/clr-unhook
Ferramentas DefensivasExploraçãoPós-ExploraçãoTestes de PenetraçãoRed TeamingDesenvolvimento de Payloads
GitHubhwbp/clr-unhook

CLR-Unhook

Produtos de segurança modernos (CrowdStrike, Bitdefender, SentinelOne, etc.) fazem hook da função nLoadImage dentro de clr.dll para interceptar e verificar carregamentos de assemblies .NET em memória. Esta ferramenta remove o hook dessa função.

Ver Repositório
217221há 9 mesesRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Ferramenta de Remoção de Hooks do CLR

  • Nota: Para que isto tenha o efeito de um CLR limpo, você precisaria mapear manualmente a DLL do disco para a memória. Você não pode usar LoadLibraryA/W, porque as soluções antivírus detectarão o evento de carregamento da DLL e poderão aplicar hook imediatamente. Se você quiser esse comportamento, pode procurar mapeadores manuais existentes no GitHub e integrar um ao seu código. Não vou incluir um aqui, pois os fornecedores de antivírus geralmente não apreciam isso.

Um utilitário nativo em C++ que contorna hooks de EDR/AV no Common Language Runtime do .NET restaurando a implementação original da função nLoadImage.

Descrição Rápida

Esta ferramenta remove os hooks de produtos de segurança da função nLoadImage do CLR - o ponto de entrada nativo crítico que lida com todo o carregamento de assemblies .NET em memória. Ao ler o clr.dll limpo do disco e sobrescrever os bytes da função com hook na memória, ela restaura o comportamento original do CLR, permitindo que Assembly.Load(byte[]) seja executado sem inspeção ou varredura de EDR.

O Que Isso Faz?

Produtos de segurança modernos (BitDefender, CrowdStrike, SentinelOne, etc.) aplicam hook na função dentro de para interceptar e verificar carregamentos de assemblies .NET em memória. Esta ferramenta remove o hook dessa função ao:

nLoadImage
clr.dll
  1. Ler o clr.dll limpo do disco
  2. Encontrar os bytes originais de nLoadImage
  3. Sobrescrever a versão com hook na memória

Após a remoção do hook, Assembly.Load(byte[]) é executado sem inspeção de EDR.

Entendendo o nLoadImage

nLoadImage é a função nativa crítica que lida com todo o carregamento de assemblies em memória no runtime .NET. Ela é declarada como um InternalCall no código gerenciado, o que significa que não possui implementação em C# - em vez disso, é uma ponte direta para o código nativo do CLR.

A Cadeia de Chamadas:

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

Por Que É Crítico:

Quase todo carregamento de assembly em memória passa por nLoadImage. O método Assembly.Load(byte[]) e suas sobrecargas (incluindo o carregamento com bytes de símbolo) invocam nLoadImage internamente. Quando você chama Assembly.Load(byte[]), o código gerenciado em mscorlib.dll passa seu array de bytes através de RuntimeAssembly.nLoadImage(), que é marcado com [MethodImpl(MethodImplOptions.InternalCall)] - ou seja, seu corpo é vazio em C# e a execução salta imediatamente para o código nativo do CLR.

Até mesmo cenários de geração dinâmica de código - frameworks de serialização que emitem assemblies em tempo de execução, geração de serializadores XML e ferramentas de red team como execute-assembly do Cobalt Strike - todos passam por essa única função.

Implementação Nativa:

O stub de InternalCall de nLoadImage em mscorlib.dll aponta para a função nativa em C++ AssemblyNative::LoadImage dentro de clr.dll. Esta função:

  • Analisa os cabeçalhos PE do array de bytes
  • Valida os metadados e o código IL
  • Aloca memória para o assembly
  • Registra o assembly no AppDomain
  • Aciona eventos pós-carregamento (ETW, verificação AMSI no .NET 4.8+)
  • Lida com assemblies em modo misto (nativo + gerenciado)
  • Impõe a verificação de nome forte

No .NET Framework 4.8+, toda chamada a nLoadImage passa automaticamente os bytes do assembly para o AMSI do Windows Defender (AmsiScanBuffer) para verificação antes da execução, tornando-o um gargalo crítico para produtos de segurança.

Assinatura da Função (.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
);

Quando você chama Assembly.Load(byte[]), ele invoca nLoadImage com estes parâmetros típicos:

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

O parâmetro fIntrospection controla se o assembly é carregado para execução (false) ou apenas para inspeção via reflexão (true). O método Assembly.ReflectionOnlyLoad(byte[]) chama nLoadImage com fIntrospection=true, permitindo o exame de metadados sem execução de código.

Por Que o EDR Aplica Hook Nele:

Como nLoadImage é o ponto de entrada único para todos os carregamentos de assemblies em memória, os produtos de EDR aplicam hook nele no nível nativo em clr.dll. Isso permite que eles:

  • Inspecionem todo assembly antes de ser carregado
  • Verifiquem arrays de bytes em busca de padrões maliciosos
  • Bloqueiem a execução antes mesmo de o .NET processar o assembly
  • Contornem técnicas de evasão de AMSI/ETW (já que o hook está abaixo dessas camadas)

Bypasses tradicionais (patch de AMSI, desativação de ETW) não afetam os hooks no nível do CLR porque operam em um nível mais alto na pilha. O hook acontece dentro do próprio CLR, antes mesmo de o AMSI ser invocado.

Uso

Processo Local (Processo Atual)

root@kitploit:~
CLRUnhook.exe

Remove o hook do CLR no processo atual. Nota: Isso só funciona se o CLR já estiver carregado (ou seja, executando a partir de um aplicativo .NET ou após carregar o CLR manualmente).

Processo Remoto (Alvejar Outro Processo)

root@kitploit:~
CLRUnhook.exe powershell.exe

CLRUnhook.exe 1234

Remove o hook do CLR em um processo remoto.

Exemplo de Saída

Remoção de Hook Remota Bem-Sucedida

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

A Cadeia do Hook

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

O Processo de Remoção de Hook

  1. Localizar a função com hook - Encontra nLoadImage no clr.dll carregado (atualmente com hook)
  2. Carregar cópia limpa - Lê o clr.dll original de C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
  3. Extrair bytes limpos - Obtém os primeiros 30 bytes da função original, .net é JIT não queremos ter problemas.
  4. Sobrescrever o hook - Aplica patch na versão com hook usando os bytes limpos

Descoberta da Função

Usa varredura de padrões para localizar nLoadImage:

  1. Procurar a string nLoadImage na memória do módulo
  2. Encontrar o ponteiro para essa string
  3. Localizar o ponteiro de função adjacente ao ponteiro da string
  4. Validar se o endereço está dentro dos limites do módulo

Créditos

Pesquisa da Técnica:

  • Matthew Graeber (@mattifestation) - Engenharia reversa de métodos InternalCall e internals do CLR

Implementação:

  • HWBP - Remoção de hooks do CLR via restauração de memória
  • @Evilbytecode - Me ajudou com a remoção de hooks, eu tive alguns problemas com o .net sendo jit.

Aviso Legal

APENAS PARA FINS EDUCACIONAIS E PESQUISA DE SEGURANÇA AUTORIZADA.

O uso não autorizado desta ferramenta para contornar controles de segurança pode violar leis de fraude computacional (CFAA, estatutos equivalentes). Use apenas em sistemas que você possui ou para os quais tenha permissão explícita por escrito para testar.

Referências

  • Reverse Engineering InternalCall Methods - Matthew Graeber
  • Microsoft .NET Reference Source
  • Documentação do Pipeline de Carregamento de Assemblies do CLR
Baixar ferramenta