Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
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.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
ExportHider — ExportHider: Gerando Tabela de Exportação durante o Tempo de Execução para Ocultar as Funções Exportadas do Arquivo DLL. | Kitploit
Ferramentas/GitHubGitHub/frkngksl/exporthider
Análise Dinâmica de Código (DAST)ExploraçãoEngenharia ReversaAnálise de MalwareAnálise de BináriosRed TeamingDesenvolvimento de Payloads
GitHubfrkngksl/exporthider

ExportHider

ExportHider: Gerando Tabela de Exportação durante o Tempo de Execução para Ocultar as Funções Exportadas do Arquivo DLL.

Ver Repositório
33221há 5 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

ExportHider

ExportHider gera um modelo de DLL em C++ que contém um stub de código que permite ocultar Funções Exportadas do Diretório de Exportação da DLL no sistema de arquivos. Após colocar as definições das funções e compilar o arquivo, você não verá as funções de exportação ocultas através de Visualizadores de Arquivos PE como o CFF Explorer. No entanto, como o stub de código no modelo recria o Diretório de Exportação durante a execução, chamadas legítimas de GetProcAddress seriam executadas com sucesso. Este método funciona apenas para carregamento dinâmico de DLL ou casos de carregador personalizado de DLL.

Como Funciona?

Normalmente, quando você deseja definir uma Função Exportada em arquivos DLL (em C ou C++), basta colocar a palavra-chave __declspec(dllexport) antes do nome da função, ou criar um arquivo .def. Após a compilação, o compilador cria uma tabela específica chamada Diretório de Exportação para armazenar as informações relacionadas às Funções Exportadas. A estrutura do Diretório de Exportação pode ser vista abaixo:

Quando um processo deseja usar uma função de um arquivo DLL, o Windows Loader simplesmente analisa essa estrutura e importa as funções solicitadas usando os arrays AddressOfFunctions, AddressOfNames, AddressOfNameOrdinals.

A rotina específica para importar uma função é explicada em detalhes no post do blog de ferreirasc, mas resumidamente, para uma função importada pelo nome, o Loader itera pelo array AddressOfNames (os valores desse array são apenas valores RVA) e busca o nome fornecido. Quando o loader encontra uma correspondência na posição “i”, ele se refere ao i-ésimo índice do array AddressOfNameOrdinals e obtém o ordinal associado a esta função. Tendo o ordinal, o loader se refere a AddressOfFunctions na posição do valor ordinal para finalmente obter o RVA associado à função importada.

O ponto crucial aqui é que todas essas operações de busca e acesso pelo Windows Loader, quando LoadLibrary é chamado, são feitas após a DLL ser mapeada no espaço de endereço do processo. Durante o mapeamento da DLL, todo o arquivo DLL, incluindo seus cabeçalhos PE, é escrito na memória, e o Loader analisa os cabeçalhos na memória para alcançar o Diretório de Exportação. Isso significa que se a própria DLL for capaz de sobrescrever seus cabeçalhos PE na memória para alterar o Endereço do Diretório de Exportação (simplesmente o índice 0 do DataDirectory) após se anexar ao processo, o loader pode procurar funções para importar em um Diretório de Exportação arbitrário, em vez do Diretório de Exportação adicionado pelo compilador.

Parâmetros da Linha de Comando


   __                       _          _     _
  /__\_  ___ __   ___  _ __| |_  /\  /(_) __| | ___ _ __
 /_\ \ \/ / '_ \ / _ \| '__| __|/ /_/ / |/ _` |/ _ \ '__|
//__  >  <| |_) | (_) | |  | |_/ __  /| | (_| |  __/ |
\__/ /_/\_\ .__/ \___/|_|   \__\/ /_/ |_|\__,_|\___|_|
          |_|
                     by @R0h1rr1m

Usage of C:\Users\Public\DLLDemo\ExportHider.exe:

    -h | --help                                 Show the help message.
    -i | --input <Input Path>                   Input path for the list of function names to be hidden. (Mandatory)
    -o | --output <Output Path>                 Output path for the DLL template. (Mandatory)
    -n | --name <DLL Name>                      Name of the DLL for the Export Directory. (Mandatory)
    -c | --count <Number of Other Functions>    Number of other exported functions that won't be hidden.

Em relação ao parâmetro -i | --input <Input Path>, você precisa especificar um caminho para o arquivo de entrada que armazena os nomes das funções a serem ocultados linha por linha. O conteúdo de um exemplo de arquivo de entrada seria:

TestFunction1
TestFunction2
TestFunction3

Em relação ao parâmetro -c | --count, se você não quiser ocultar todas as suas funções exportadas (ou seja, existem algumas funções exportadas com __declspec(dllexport) ou arquivo .def, e elas aparecem no Diretório de Exportação do arquivo DLL no sistema de arquivos através de Visualizadores de Arquivos PE), basta especificar quantas existem usando este parâmetro, porque a ferramenta precisa dessa informação ao fazer cálculos de memória.

Vídeo de Demonstração Rápida

Soluções Alternativas

Se você quiser brincar com a técnica, há dois pontos interessantes que encontrei durante o desenvolvimento do projeto. Você pode precisar conhecê-los antes de alterar o projeto:

  • O Windows Loader usa um algoritmo semelhante à Busca Binária para encontrar a função exportada se você chamar a função GetProcAddress com um nome. Por causa disso, os nomes de todas as funções exportadas, incluindo as ocultas, precisam estar ordenados no array AddressOfNames. Caso contrário, a função GetProcAddress retorna NULL. Portanto, usei o algoritmo Bubble Sort para ordenar os membros deste array.
  • Como disse acima, os arrays AddressOfNames, AddressOfFunctions, DataDirectory e alguns outros campos exigem valores em Endereços Virtuais Relativos (RVAs). Além disso, eles armazenam esses valores RVA em campos de tamanho DWORD. Quando você aloca uma região de memória para um novo diretório de exportação arbitrário usando funções de Alocação Dinâmica de Memória como VirtualAlloc ou HeapAlloc, os endereços fornecidos estarão longe da região mapeada da DLL, e os valores RVA não cabem nos campos de tamanho DWORD, resultando em estouro de inteiro. Foi por isso que usei variáveis globais do tipo array de bytes no modelo DLL para requisitos de memória.

Caso de DLL Importada Estaticamente (também conhecido como DLL Sideloading)

Meu primeiro objetivo ao criar este projeto foi gerar uma DLL que tivesse exportações ausentes (ou ausência completa de uma tabela de exportação), mas que ainda fosse carregada com sucesso pelo processo recém-criado. Pensei que esse comportamento poderia trazer um novo campo de exploração para os payloads de DLL sideloading. No entanto, não consegui encontrar nenhuma função ou maneira pela qual o stub de correção do diretório de exportação seja executado antes de o Windows Loader verificar as funções exportadas da DLL.

dll_timing_problem (1)

Mais tecnicamente, notei o seguinte fluxo e chamada de função para cada DLL nas seções de código relacionadas ao Windows Loader no NTDLL (coletado das minhas anotações antigas; pode haver alguns erros porque não sou um engenheiro reverso especialista):

Baixar ferramenta