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
  • Magic
  • AddressOfEntryPoint
  • ImageBase
  • SubSystem
  • DllCharacteristics

Was this helpful?

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

Opcional

A julgar pelo seu nome, pode não parecer, mas este cabeçalho é muito importante. Ele é opcional para arquivos objeto, mas é obrigatório em arquivos executáveis, que são o nosso foco de estudo. Ao contrário dos outros cabeçalhos que vimos até agora, o tamanho deste cabeçalho não é fixo, mas sim definido pelo campo SizeOfOptionalHeader do cabeçalho COFF, que vimos anteriormente. Sua estrutura para arquivos PE de 64-bits, também chamados de PE32+ (ou de PE64 de forma não oficial), é a seguinte:

#define MAX_DIRECTORIES 16

typedef struct {
	uint16_t Magic;
	uint8_t MajorLinkerVersion;
	uint8_t MinorLinkerVersion;
	uint32_t SizeOfCode;
	uint32_t SizeOfInitializedData;
	uint32_t SizeOfUninitializedData;
	uint32_t AddressOfEntryPoint;
	uint32_t BaseOfCode;
	uint64_t ImageBase;
	uint32_t SectionAlignment;
	uint32_t FileAlignment;
	uint16_t MajorOperatingSystemVersion;
	uint16_t MinorOperatingSystemVersion;
	uint16_t MajorImageVersion;
	uint16_t MinorImageVersion;
	uint16_t MajorSubsystemVersion;
	uint16_t MinorSubsystemVersion;
	uint32_t Win32VersionValue;
	uint32_t SizeOfImage;
	uint32_t SizeOfHeaders;
	uint32_t CheckSum;
	uint16_t Subsystem;
	uint16_t DllCharacteristics;
	uint64_t SizeOfStackReserve;
	uint64_t SizeOfStackCommit;
	uint64_t SizeOfHeapReserve;
	uint64_t SizeOfHeapCommit;
	uint32_t LoaderFlags;
	uint32_t NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[MAX_DIRECTORIES];
} IMAGE_OPTIONAL_HEADER_64;

Vamos analisar agora os campos mais importantes para o nosso estudo:

Magic

O primeiro campo, de 2 bytes, é um outro número mágico que identifica o tipo de executável em questão. O valor 0x20b diz que é um PE32+ (executável PE de 64-bits), enquanto o valor 0x10b significa que o executável é um PE32 (executável PE de 32-bits).

A Microsoft chama os executáveis de PE de 64-bits de PE32+ e não de PE64 como alguns programas fazem. Já os de 32-bits são chamados de PE32 mesmo.

AddressOfEntryPoint

Este é talvez o campo mais importante do cabeçalho opcional. Nele está contido o endereço do ponto de entrada (entrypoint), abreviado EP, que é onde o código do programa deve começar. Para arquivos executáveis, este endereço é relativo à base da imagem (campo que veremos a seguir). Para bibliotecas, ele não é necessário e pode ser zero, já que as funções de bilbioteca podem ser chamadas arbitrariamente.

ImageBase

Imagem é como a Microsoft chama um arquivo executável (para diferenciar de um código-objeto) quando vai para a memória. Neste campo está o endereço de memória que é a base da imagem, ou seja, o endereço onde o programa será carregado em memória. É comum encontrar valores como 0x140000000 ou 0x400000 neste campo.

SubSystem

Este campo define o tipo de subsistema necessário para rodar o programa. Valores interessantes para nós são:

  • 0x002 - Windows GUI (Graphical User Interface) - para programas gráficos no Windows (que usam janelas, etc).

  • 0x003 - Windows CUI (Character User Interface) - para programas de linha de comando.

DllCharacteristics

Ao contrário do que o nome possa sugerir, este campo não é somente para DLLs. Ele está presente e é utilizado para arquivos executáveis também. Assim como o campo Characteristics do cabeçalho COFF visto anteriormente, este campo é uma máscara de bits com destaque para os possíveis valores:

Bit
Nome

5

IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE

7

IMAGE_DLLCHARACTERISTICS_NX_COMPAT

O estado bit 5 nos diz se a randomização de endereços de memória, também conhecida por ASLR (Address Space Layout Randomization), está ativada para este binário, enquanto o estado do bit 7 diz respeito à DEP (Data Execution Prevention), também conhecido pela sigla NX (No eXecute). O estudo aprofundado destes recursos foge do escopo deste livro, mas é importante que saibamos que podemos desabilitar tais recursos para um binário específico simplesmente desligando estes bits se quisermos.

O último campo importante para nós é o DataDirectory, que veremos a seguir.

PreviousCOFFNextDiretórios de Dados

Last updated 4 days ago

Was this helpful?

💼