
DLL em C++ que realiza hooking da Import Address Table analisando cabeçalhos PE e redirecionando endereços de funções importadas para um hook personalizado dentro de um processo alvo.
Hooking é uma técnica que permite a um usuário redirecionar o fluxo de execução de um programa. Na maioria das vezes usamos hooking de funções. Vamos substituir ou redirecionar uma função para a nossa própria, isso é muito útil e tem múltiplos casos de uso. Existem várias formas de hooking, aqui estamos olhando para IAT Hooking, que significa Import Address Table. Consiste em substituir o endereço de uma função pelo nosso próprio em uma grande tabela que é preenchida em tempo de execução. Como eu disse antes em outro repositório, recomendo que você leia mais sobre o PE Format para entender a parte de parsing da IAT deste código.
Aqui está um diagrama básico de como o IAT Hooking funciona. Neste exemplo, a função original está sendo chamada após o código malicioso ter sido executado. Neste exemplo vamos simplesmente chamar outra função em vez da original. A vantagem dessa técnica é que ela não requer modificar o corpo de uma função, ao contrário de um hook regular de patch .text com detours, que precisa alterar as instruções no início de uma função para colocar um jmp, por exemplo.
Na verdade é bem mais simples do que parece, vamos proceder internamente para facilitar as coisas, o que significa que este repositório irá compilar para uma DLL que pode ser injetada no processo alvo usando meus injetores LoadLibraryA ou Manual Mapping para injetar no processo alvo.
Primeiro fazemos o parsing dos PE Headers do processo alvo para localizar o Import Descriptor assim:
process_base + nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
Podemos então percorrer cada módulo importado, percorrer cada função neste módulo (motivo dos loops aninhados) e encontrar o endereço dessa função que foi preenchido em tempo de execução. Neste exemplo vamos fazer hook de TranslateMessage, que é usado pelo Windows para processar eventos em interfaces gráficas. Então, uma vez que encontramos o endereço dessa função, nós o substituímos pelo endereço da nossa própria função que definimos anteriormente e que existe no contexto do processo remoto, já que somos internos. Não esqueça de usar VirtualProtect para garantir que você tem permissão para escrever naquele local.
VirtualProtect(&firstThunk->u1.Function, sizeof(uint64_t), PAGE_READWRITE, &old_protection);
firstThunk->u1.Function = (uint64_t)hookfunction;
Como você pode ver, quando o notepad chama TranslateMessage (praticamente o tempo todo) ele irá executar nossa função de hook, que acaba exibindo uma caixa de mensagem!
image