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

10

O que eu já sei:

Um executável ELF tem um número de seções, obviamente as seções .text e .data são carregadas na memória, pois são as partes principais do programa. Mas, para um programa funcionar, ele precisa de mais informações, especialmente quando vinculado dinamicamente.

O que me interessa são seções como .plt, .got, .dynamic, .dynsym, .dynstr etcetera. As partes do ELF que são responsáveis pela vinculação de funções aos endereços.

Pelo que consegui descobrir até agora, é que coisas como .symtab e .strtab não são carregadas (ou não permanecem) na memória. Mas são .dynsym e e .dynstr usados pelo linker? 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 é principalmente forense, mas qualquer informação sobre este tópico ajudará. Os recursos que eu li sobre essas tabelas e links dinâmicos são de mais alto nível, eles explicam apenas o funcionamento, e nada prático sobre o conteúdo na memória.

Deixe-me saber se tiver alguma dúvida sobre a minha pergunta.

    
por Dutchy 29.03.2013 / 13:55

1 resposta

12

O que se segue é uma boa referência: link . Ele contém uma bibliografia no final de uma variedade de referências diferentes em diferentes níveis. Se você quiser saber todos os detalhes, vá direto à fonte: link . (Ulrich Drepper escreveu o vinculador dinâmico do Linux.)

Você pode obter uma boa visão geral 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 neste objeto. A seção .dynamic é uma destilação do cabeçalho do programa formatado para facilitar a leitura do carregador dinâmico. (Por isso, tem ponteiros para todas as outras seções.)

O .got (Tabela Global de Compensação) e .plt (Tabela de Ligação de Procedimentos) 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 (que são chamados de "objetos compartilhados") tem seus próprios .got e .plt e são tabelas dos símbolos referenciados pelo objeto compartilhado que estão, na verdade, contidos em algum outro objeto compartilhado.

O dynsyn contém todas as informações sobre os símbolos em seu objeto compartilhado (tanto os que você define quanto os externos que você precisa referenciar). O dynsyn não contém os nomes dos símbolos reais. Esses estão contidos em .dynstr e .dynsyn tem ponteiros em .dynstr. .gnu.hash é uma tabela de hash usada para consulta rápida de símbolos por nome. Ele também contém apenas ponteiros (ponteiros para .dynstr e ponteiros usados para criar cadeias de blocos.)

Quando o objeto compartilhado cancela a referência a algum símbolo "foo", o vinculador dinâmico precisa pesquisar "foo" em todos os objetos dinâmicos com os quais você está vinculado para descobrir qual contém o "foo" que você está procurando (e qual é o endereço relativo de "foo" 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 têm Depois de encontrar o endereço correto no objeto compartilhado vinculado, ele o coloca no .got ou .plt do seu objeto compartilhado.

    
por 29.03.2013 / 14:47