Import Table
Foi visto que no diretório de dados Import Table há um ponteiro para a IDT (Import Directory Table), apontado pelo valor do campo VirtualAddress. Vamos conhecer essa IDT de uma vez.
Import Directory Table
A IDT é um array de estruturas do tipo IMAGE_IMPORT_DESCRIPTOR definidas a seguir:
Não se deve confundir esta IDT (Import Descriptor Table) com outra IDT (Interrupt Descriptor Table). Esta última é uma estrutura que mapeia interrupções para seus devidos handlers, assunto que foge do escopo deste livro.
O número de elementos do array de estruturas IMAGE_IMPORT_DESCRIPTOR é igual ao número de bibliotecas que o executável PE depende, ou seja, o número de diferentes DLLs das quais o executável importa funções. Há ainda um elemento final, completamente zerado (preenchido com null bytes) para indicar o fim do array.
RvaImportLookupTable
O campo RvaImportLookupTable (antigamente conhecido por OriginalFirstThunk que era unido com Characteristics) aponta para uma tabela chamada de Import Lookup Table (ILT)
Import Lookup Table (ILT)
Essa tabela é um array de números de 64-bits (ou 32-bits para PE32). Para cada um desses números, seu bit mais significativo (MSB - Most Significant Bit), se ligado, define que a função será importada por número. Se desligado, a função é importada por nome. Os bits remanescentes guardam um endereço para uma estrutura que finalmente contém o nome da função. Essa estrutura é chamada de Hint/Name Table.
Hint/Name Table
Os elementos desta tabela obedecem a seguinte estrutura:
Onde Name possui tamanho variável pois contém o nome da função a ser importada.
Note que o número de entradas na ILT (número de elementos deste array) é igual ao número de funções importadas por uma DLL em particular definida na IDT.
Name
Este campo contém o endereço de uma string que é o nome da DLL importada. Por exemplo: SHELL32.dll. A string é terminada em null.
RvaImportAddressTable
Este campo aponta finalmente para o que chamamos de IAT (Import Address Table), muito conhecida por quem faz engenharia reversa. Essa tabela é em princípio idêntica à Import Lookup Table, mas no processo de carregamento do executável (load time, que estudaremos mais à frente no livro), ela é preenchida com os endereços reais das funções importadas. Isto porque um executável dinamicamente linkado não sabe, antes de ser carregado em memória, qual o endereço de cada função de cada DLL que ele precisa chamar.
É importante lembrar o conceito de biblioteca compartilhada aqui. A ideia é ter apenas uma cópia dela carregada em memória e todos os programas que a utilizam podem chamar suas funções. Esta é a razão para o longo esquema de preenchimento da IAT pelo loader.
Exercícios
Para fixar este conteúdo, é importante validar o que foi aprendido. Abra o executável da calculadora no DIE, marque a caixa Advanced se já não estiver marcada e clique no botão PE como a imagem a seguir mostra:
No menu da esquerda, vá em IMAGE_NT_HEADERS -> IMAGE_OPTIONAL_HEADER -> IMAGE_DIRECTORY_ENTRIES e copie o endereço (coluna Address) do segundo diretório, que é justamente o endereço da IDT, como a imagem a seguir ilustra:
Perceba que o DIE chama o campo VirtualAddress dos diretórios apenas de Address. Inconsistências assim podem ocorrer em várias ferramentas e literaturas, mas se você souber do que se trata, vai sempre se dar bem, mesmo que nomes diferentes sejam usados para se referir à mesma coisa.
Agora no HxD, abra o mesmo binário e vá até este offset da IDT com o Ctrl+G. No binário que usei aqui o endereço é 0x38f8.
Lá, os primeiros quatros bytes são o valor do campo RvaImportLookupTable do primeiro elemento do array. Se você seguir este offset, vai chegar na ILT. O primeiro elemento da ILT é um número de 64-bits, ou seja, de 8 bytes que aponta para a Hint/Name Table. Nesta tabela, o nome da função começa no terceiro byte conforme definição, logo após o campo Hint.
Como desafio adicional, descubra à qual DLL a função pertence apenas olhando para a imagem anterior. Dica: busque pelo campo Name da IDT e siga o valor que ele contém neste binário.
Last updated
Was this helpful?