Fundamentos de Engenharia Reversa
Apoie este trabalho
  • 🙌Apresentação
  • 👀Antes de Começar
  • 🥇Introdução
  • 🔢Números
    • Sistemas de Numeração
    • O Byte
    • Números Negativos
    • Cálculos com Binários
  • 🧵Cadeias de Texto
    • ASCII
    • Unicode
    • C Strings
  • 🗂️Arquivos
    • Formatos
  • 💼O formato PE
    • Cabeçalhos
      • MS-DOS
      • COFF
      • Opcional
      • Diretórios de Dados
      • Cabeçalhos das Seções
    • Seções
    • Import Table
    • Endereçamento
  • 🚗Execução de Programas
    • Executáveis
    • Bibliotecas
    • Processos
  • 🖼️Windows API
    • Caixas de Mensagens
    • Manipulação de Arquivos
    • Acesso ao Registro
  • ⚙️Assembly
    • Registradores
    • Instruções Básicas
    • Funções e Pilha
  • 🐞Depuração
    • O Debugger
    • Disassembly
    • Breakpoints
    • Manipulação do Fluxo
    • Patches
  • Apêndices
    • Tabela ASCII
    • Tabela ISO-8859-1/Latin-1
    • Exemplos de Código em Assembly
    • Funções da API do Windows
    • Ferramentas
    • Referências
  • Sobre o livro
    • 📝Registro de alterações
Powered by GitBook
On this page
  • e_magic
  • e_lfanew
  • Exercício

Was this helpful?

Edit on GitHub
Export as PDF
  1. O formato PE
  2. Cabeçalhos

MS-DOS

Não estranhe o nome deste cabeçalho. Ele é parte do que chamamos de stub do MS-DOS: um executável completo de MS-DOS presente no início de todo executável PE para fins de retrocompatibilidade.

Sendo assim, todo executável PE começa com este cabeçalho que é definido pela seguinte estrutura:

typedef struct {
    uint16_t e_magic;
    uint16_t e_cblp;
    uint16_t e_cp;
    uint16_t e_crlc;
    uint16_t e_cparhdr;
    uint16_t e_minalloc;
    uint16_t e_maxalloc;
    uint16_t e_ss;
    uint16_t e_sp;
    uint16_t e_csum;
    uint16_t e_ip;
    uint16_t e_cs;
    uint16_t e_lfarlc;
    uint16_t e_ovno;
    uint16_t e_res[4];
    uint16_t e_oemid;
    uint16_t e_oeminfo;
    uint16_t e_res2[10];
    uint32_t e_lfanew;
} IMAGE_DOS_HEADER;

Este cabeçalho possui 64 bytes de tamanho. Para chegar a esta conclusão basta somar o tamanho de cada campo, onde uint16_t é um tipo na linguagem C que define uma variável de 16 bits ou 2 bytes. Os seguintes campos variam deste tamanho:

  • uint16_t e_res[4] que é um array de 4 campos de 16 bits, totalizando em 64 bits ou 8 bytes.

  • uint16_t e_res2[10] que é um array de 10 campos de 16 bits, totalizando em 160 bits ou 20 bytes.

  • uint32_t e_lfanew que é um campo de 32 bits ou 4 bytes.

Os outros 16 campos possuem o tamanho de um uint16_t (16 bits ou 2 bytes). Então somando os tamanhos de todos os campos, temos 64 bytes.

Por ser um cabeçalho ainda presente no formato PE somente por questões de compatibilidade com o MS-DOS, não entraremos em muitos detalhes, mas estudaremos alguns de seus campos a seguir.

e_magic

Este campo de 2 bytes sempre contém os valores 0x4d e 0x5a, que são os caracteres 'M' e 'Z' na tabela ASCII. Portanto é comum verificar que todo arquivo executável do Windows que segue o formato PE começa com tais valores, que representam as iniciais de Mark Zbikowski, um dos criadores deste formato para o MS-DOS.

Podemos utilizar um editor hexadecimal como o HxD para verificar tal informação. Vamos abrir, em caráter de exemplo, o executável da calculadora no Windows, normalmente em C:\Windows\System32\calc.exe.

Perceba os bytes 0x4d e 0x5a logo no início do arquivo.

O HxD exibe um caractere de ponto (.) na coluna Decoded text quando o byte não está na faixa ASCII imprimível. Esta é uma decisão de quem programou o editor hexadecimal. Outras opções comum incluem exibir um caractere de espaço.

e_lfanew

O próximo campo importante para nós é o e_lfanew, um campo de 4 bytes cujo valor é a posição no arquivo do que é conhecido por assinatura PE, uma sequência fixa dos seguintes 4 bytes: 50 45 00 00.

Como o cabeçalho do DOS possui um tamanho fixo, seus campos estão sempre numa posição fixa no arquivo. No entanto, seus valores podem variar de arquivo para arquivo. No caso do e_lfanew, se fizermos as contas, veremos que ele sempre está na posição 0x3c (ou 60 em decimal), já que ele é o último campo de 4 bytes de um cabeçalho de 64 bytes.

Para ver o valor deste campo rapidamente podemos pedir ao HxD que vá para a posição 0x3c. Clique em Search -> Go to... ou aperte Ctrl+G. Certifique-se de que as opções "hex" e "begin" estão selecionadas e clique em OK.

No meu arquivo, assim como na imagem anterior, os quatro bytes nesta posição são 00 01 00 00. Sabendo que números são armazenados em little-endian, devemos ler este número como 00 00 01 00, ou seja, 0x0000100 ou simplesmente 0x100. Este é então o endereço da assinatura PE, que consiste numa sequência dos seguintes 4 bytes: 0x50 0x45 0x00 0x00.

Perceba que os dois primeiros bytes na assinatura PE possuem representação ASCII justamente das letras 'P' e 'E' maiúsculas. Sendo assim, essa assinatura pode ser escrita como "PE\0\0", no estilo C string.

Logo após o cabeçalho do DOS, há o código do programa que vai imprimir na tela uma mensagem de erro caso um usuário tente rodar este arquivo PE no MS-DOS. Normalmente o texto impresso na tela é:

This program cannot be run in DOS mode.

Depois disso o programa sai. Mas este pequeno programa de MS-DOS é adicionado pelo compilador (pelo linker mais especificamente) e seu conteúdo pode variar, pois não há um padrão rígido a ser seguido.

Exercício

Para por em prática a análise desta primeira parte do arquivo PE, abra o executável da calculadora do Windows (normalmente em C:\Windows\System32\calc.exe) no HxD.

Note que:

  • Logo no início do arquivo, há o número mágico "MZ".

  • Na posição 0x3c, ou seja, no campo e_lfanew, há o endereço da assinatura PE (0x100 no caso deste executável, mas pode ser diferente no seu ambiente).

  • Logo após os 4 bytes do campo e_lfanew, começa o código do stub do DOS, sempre no offset 0x40, com uma sequência de bytes que não fazem sentido para nós por enquanto (veja que o texto impresso na tela pelo programa é todavia bem visível).

  • Finalmente, na posição 0x100 encontra-se a assinatura PE\0\0. Aqui sim, começa o formato PE propriamente dito.

PreviousCabeçalhosNextCOFF

Last updated 4 days ago

Was this helpful?

💼
Conteúdo do binário da calculadora do Windows no HxD