Análise de Arquivos Binários no Linux com readelf

O utilitário readelf é uma ferramenta essencial no ecossistema Linux para engenheiros de sistemas e desenvolvedores que precisam inspecionar o conteúdo de arquivos no formato ELF (Executable and Linkable Format). Diferente de ferramentas como o objdump, o readelf não depende da BFD (Binary File Descriptor library), o que permite uma visualização direta das estruturas de dados conforme definidas na especificação ELF.

Extração Completa de Metadados

Para obter uma visão abrangente de todas as seções, cabeçalhos e tabelas contidas em um binário, utiliza-se a flag -a. Este comando consolida as informações mais relevantes do arquivo.

readelf -a modulo_sistema.so

A saída inicial apresenta o ELF Header, que contém a "certidão de nascimento" do binário:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64                                     # Arquivo de 64 bits
  Data:                              2's complement, little endian             # Formato Little Endian
  Version:                           1 (current)                               # Versão atual do ELF
  OS/ABI:                            UNIX - System V                           # Interface padrão UNIX
  ABI Version:                       0
  Type:                              DYN (Shared object file)                  # Biblioteca compartilhada (.so)
  Machine:                           Advanced Micro Devices X86-64             # Arquitetura Alvo
  Entry point address:               0x8ce0                                    # Endereço de entrada
  Start of program headers:          64 (bytes)
  Number of section headers:         35

Identificação da Versão do Compilador

Muitas vezes é necessário validar com qual versão do GCC ou Clang um binário foi gerado. O readelf permite extrair essas strings da seção .comment.

readelf -p .comment binario_executavel

O resultado revela informações sobre o ambiente de build:

String dump of section '.comment':
  [     0]  GCC: (GNU) 10.2.1 20210130 (Red Hat 10.2.1-11)

Análise de Dependências Dinâmicas

Para verificar quais bibliotecas externas o binário solicita em tempo de execução, bem como outras informações da seção dinâmica, utiliza-se a flag -d.

readelf -d libengine.so

As entradas marcadas como (NEEDED) indicam as dependências diretas de bibliotecas compartilhadas:

Dynamic section at offset 0x18d98 contains 30 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000c (INIT)               0x7e00
 0x000000000000001a (FINI_ARRAY)         0x218d50

Inspeção da Tabela de Símbolos

A tabela de símbolos contém os nomes de funções e variáveis manipuladas pelo binário. Para visualizar tanto os símbolos internos quanto os exportados, utiliza-se -s.

readelf -s aplicativo_core

Se o objetivo for filtrar apenas os símbolos dinâmicos (aqueles necessários para a linkagem em tempo de execução), o parâmetro --dyn-syms é o mais indicado:

readelf --dyn-syms aplicativo_core

Abaixo, um exemplo da estrutura de saída para símbolos dinâmicos:

Symbol table '.dynsym' contains 285 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND malloc@GLIBC_2.2.5
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND free@GLIBC_2.2.5
     3: 00000000000012a0    45 FUNC    GLOBAL DEFAULT   12 custom_init_func
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__

Nesta tabela, a coluna Ndx com o valor UND indica símbolos indefinidos que o binário espera encontrar em outras bibliotecas compartilhadas no momento da execução.

Tags: Linux ELF readelf binary-analysis gcc

Publicado em 6-26 05:15