Quais partes de um executável ELF são carregadas na memória e onde?

10

O que eu já sei:

Um executável do ELF possui várias seções, obviamente as seções .text e .data são carregadas na memória, pois essas são as partes principais do programa. Mas, para que um programa funcione, ele precisa de mais informações, especialmente quando vinculado dinamicamente.

Estou interessado em seções como .plt, .got, .dynamic, .dynsym, .dynstr etcetera. As partes do ELF responsáveis ​​pela vinculação de funções aos endereços.

Pelo que pude descobrir até agora, coisas como .symtab e .strtab não são carregadas (ou não ficam) na memória. Mas .dynsym ee .dynstr são usados ​​pelo vinculador? Eles ficam na memória? Posso acessá-los a partir do código do programa?

E existem partes de um executável que residem na memória do kernel?

Meu interesse nisso é forense, mas qualquer informação sobre esse tópico ajudará. Os recursos que li sobre essas tabelas e os vínculos dinâmicos são de alto nível; eles apenas explicam o funcionamento, nada prático sobre o conteúdo da memória.

Deixe-me saber se algo não está claro sobre a minha pergunta.

Dutchy
fonte

Respostas:

12

A seguir, é uma referência realmente boa: http://www.ibm.com/developerworks/linux/library/l-dynamic-libraries/ . Ele contém uma bibliografia no final de uma variedade de referências diferentes em diferentes níveis. Se você quiser conhecer todos os detalhes sangrentos, pode ir direto à fonte: http://www.akkadia.org/drepper/dsohowto.pdf . (Ulrich Drepper escreveu o vinculador dinâmico do Linux.)

Você pode obter uma visão geral muito boa de todas as seções do seu executável executando um comando como "objdump -h myexe" ou "readelf -S myexe".

A seção .interp contém o nome do carregador dinâmico que será usado para vincular dinamicamente os símbolos nesse objeto. A seção .dynamic é uma destilação do cabeçalho do programa formatada para facilitar a leitura do carregador dinâmico. (Portanto, ele tem ponteiros para todas as outras seções.)

O .got (Global Offset Table) e .plt (Procedure Linkage Table) são as duas estruturas principais que são manipuladas pelo vinculador dinâmico. O .got é uma tabela indireta para variáveis ​​e o .plt é uma tabela indireta para funções. Cada executável ou biblioteca (denominada "objetos compartilhados") possui seus próprios .got e .plt e são tabelas dos símbolos referenciados por esse objeto compartilhado que estão realmente contidos em algum outro objeto compartilhado.

O .dynsyn contém todas as informações sobre os símbolos no seu objeto compartilhado (os que você define e os externos que você precisa fazer referência.) O .dynsyn não contém os nomes dos símbolos reais. Esses estão contidos em .dynstr e .dynsyn possui ponteiros em .dynstr. .gnu.hash é uma tabela de hash usada para pesquisa rápida de símbolos por nome. Ele também contém apenas ponteiros (ponteiros para .dynstr e ponteiros usados ​​para fazer cadeias de balde).

Quando seu objeto compartilhado desreferencia algum símbolo "foo", o vinculador dinâmico deve procurar "foo" em todos os objetos dinâmicos aos quais você está vinculado para descobrir qual deles contém o "foo" que você está procurando (e depois qual o parente o endereço "foo" está dentro desse objeto compartilhado.) O vinculador dinâmico faz isso pesquisando a seção .gnu.hash de todos os objetos compartilhados vinculados (ou a seção .hash para objetos compartilhados antigos que não possuem um .gnu. hash.) Quando encontra o endereço correto no objeto compartilhado vinculado, coloca-o no .got ou no .plt do seu objeto compartilhado.

Lógica Errante
fonte
Obrigado, seus links me levam um passo adiante na descoberta dos mapeamentos virtuais das seções de que preciso. Como meu interesse nisso é forense, "carregado na DRAM" ainda é relevante para mim. Se uma seção é mapeado, mas nunca carregado, eu não será capaz de encontrá-lo em um despejo de memória :)
Dutchy
Você está certo. Quando você faz o despejo de memória, você obtém uma cópia de todas as páginas mapeadas, portanto minha distinção entre "mapeado na vm" e "carregado na DRAM" era irrelevante. Eu removi essa frase e a resposta foi melhorada. Obrigado!
Wandering Logic
Marcou sua resposta como a resposta, porque é o máximo de informações que eu vou conseguir :) terá que fazer o resto sozinha, é minha pesquisa, afinal.
Dutchy 02/04
Portanto, sim .dynsym e e .dynstr (e outros) são usados ​​pelo vinculador dinâmico e carregados na memória do programa (no segmento de texto) e podem ser usados ​​em tempo de execução pelo seu programa.
ysdx 2/09/2015