# 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:

```c
#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 (começando em 0) | 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mentebinaria.gitbook.io/engenharia-reversa/05-o-formato-pe/cabecalhos/opcional.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
