* Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
O programa anterior tem **9 cabeçalhos de programa**, então, o **mapeamento de segmentos** indica em qual cabeçalho de programa (de 00 a 08) **cada seção está localizada**.
Esses cabeçalhos são usados para indicar **como carregar um binário na memória**.\
Cada cabeçalho **LOAD** indica uma região de **memória** (tamanho, permissões e alinhamento) e indica os bytes do ELF **binário a serem copiados lá dentro**.
Por exemplo, o segundo tem um tamanho de 0x1190, deve estar localizado em 0x1fc48 com permissões de leitura e escrita e será preenchido com 0x528 a partir do deslocamento 0xfc48 (não preenche todo o espaço reservado). Esta memória conterá as seções `.init_array .fini_array .dynamic .got .data .bss`.
Indica a configuração RELRO (Relocation Read-Only) do binário. Essa proteção marcará como somente leitura certas seções da memória (como o `GOT` ou as tabelas `init` e `fini`) após o programa ter sido carregado e antes de começar a ser executado.
No exemplo anterior, está copiando 0x3b8 bytes para 0x1fc48 como somente leitura afetando as seções `.init_array .fini_array .dynamic .got .data .bss`.
Observe que o RELRO pode ser parcial ou completo, a versão parcial não protege a seção **`.plt.got`**, que é usada para **ligação preguiçosa** e precisa que este espaço de memória tenha **permissões de escrita** para escrever o endereço das bibliotecas na primeira vez que sua localização é pesquisada.
* **Tabela de strings**: Contém todas as strings necessárias pelo arquivo ELF (mas não aquelas realmente usadas pelo programa). Por exemplo, contém nomes de seções como `.text` ou `.data`. E se `.text` estiver no offset 45 na tabela de strings, usará o número **45** no campo **name**.
* Para encontrar onde está a tabela de strings, o ELF contém um ponteiro para a tabela de strings.
* **Tabela de símbolos**: Contém informações sobre os símbolos como o nome (offset na tabela de strings), endereço, tamanho e mais metadados sobre o símbolo.
* **`.bss`**: Variáveis globais não inicializadas (ou inicializadas para zero). As variáveis aqui são automaticamente inicializadas para zero, evitando assim zeros inúteis de serem adicionados ao binário.
- **Atributos de ligação** (fraco, local ou global): Um símbolo local só pode ser acessado pelo programa em si, enquanto o símbolo global é compartilhado fora do programa. Um objeto fraco é, por exemplo, uma função que pode ser substituída por outra.
- **Tipo**: NOTYPE (nenhum tipo especificado), OBJECT (variável de dados global), FUNC (função), SECTION (seção), FILE (arquivo de código-fonte para depuradores), TLS (variável local de segmento), GNU_IFUNC (função indireta para realocação)
O diretório NEEDED indica que o programa **precisa carregar a biblioteca mencionada** para continuar. O diretório NEEDED é concluído uma vez que a **biblioteca compartilhada está totalmente operacional e pronta** para uso.
O carregador também deve realocar dependências após tê-las carregado. Essas realocações são indicadas na tabela de realocação nos formatos REL ou RELA e o número de realocações é fornecido nas seções dinâmicas RELSZ ou RELASZ.
Se o **programa for carregado em um local diferente** do endereço preferido (geralmente 0x400000) porque o endereço já está em uso ou por causa do **ASLR** ou qualquer outro motivo, uma relocação estática **corrige ponteiros** que tinham valores esperando que o binário fosse carregado no endereço preferido.
A relocação também pode fazer referência a um símbolo externo (como uma função de uma dependência). Como a função malloc da libC. Então, o carregador, ao carregar a libC em um endereço verificando onde a função malloc está carregada, escreverá este endereço na tabela GOT (Global Offset Table) (indicada na tabela de relocação) onde o endereço de malloc deve ser especificado.
A seção PLT permite realizar vinculação tardia, o que significa que a resolução da localização de uma função será realizada na primeira vez que ela for acessada.
Portanto, quando um programa chama malloc, na verdade chama a localização correspondente de `malloc` na PLT (`malloc@plt`). Na primeira vez que é chamado, ele resolve o endereço de `malloc` e o armazena para que na próxima vez que `malloc` for chamado, esse endereço seja usado em vez do código PLT.
Após o programa ter sido carregado, é hora de executá-lo. No entanto, o primeiro código que é executado **nem sempre é a função `main`**. Isso ocorre porque, por exemplo, em C++ se uma **variável global for um objeto de uma classe**, esse objeto deve ser **inicializado****antes** da execução do main, como em:
Note que essas variáveis globais estão localizadas em `.data` ou `.bss`, mas nas listas `__CTOR_LIST__` e `__DTOR_LIST__`, os objetos a serem inicializados e destruídos são armazenados para acompanhar sua ordem.
Do ponto de vista do compilador, para executar essas ações antes e depois da função `main` ser executada, é possível criar uma função `init` e uma função `fini` que seriam referenciadas na seção dinâmica como **`INIT`** e **`FIN`** e são colocadas nas seções `init` e `fini` do ELF.
A outra opção, como mencionado, é referenciar as listas **`__CTOR_LIST__`** e **`__DTOR_LIST__`** nas entradas **`INIT_ARRAY`** e **`FINI_ARRAY`** na seção dinâmica e o comprimento destas é indicado por **`INIT_ARRAYSZ`** e **`FINI_ARRAYSZ`**. Cada entrada é um ponteiro de função que será chamado sem argumentos.
Quando isso é usado, as seções **`.tdata`** e **`.tbss`** são usadas no ELF. Que são como `.data` (inicializado) e `.bss` (não inicializado) mas para TLS.
Cada variável terá uma entrada no cabeçalho TLS especificando o tamanho e o deslocamento TLS, que é o deslocamento que será usado na área de dados local da thread.
O `__TLS_MODULE_BASE` é um símbolo usado para se referir ao endereço base do armazenamento local de threads e aponta para a área na memória que contém todos os dados locais da thread de um módulo.