# Breakpoints

Um *breakpoint* nada mais é que um ponto no código onde o *debugger* vai parar para que você analise o que precisa. É o mesmo conceito dos *breakpoints* presentes em ambientes de desenvolvimento como Visual Studio, NetBeans ou CodeBlocks. A diferença é que nestes ambientes colocamos *breakpoints* em determinadas linhas do código-fonte. Já nos *debuggers* destinados à engenharia reversa, colocamos *breakpoints* em **endereços** (VAs), onde normalmente há instruções.

## Seu Primeiro *Breakpoint*

Há várias maneiras de se colocar um *breakpoint* em um endereço utilizando o x64dbg. Você pode selecionar a instrução e pressionar F2, usar um dos comandos SetBPX/bp/bpx, dar um duplo clique sobre os *bytes* da instrução (coluna 3 no disassembly) ou simplesmente clicar na bolinha cinza à esquerda do endereço (coluna 1 do disassembly). Ao fazê-lo, este ficará com um fundo vermelho, como mostra a imagem:

![Colocando um breakpoint na CALL](/files/Di36TjDfAwzQEVnu50WG)

Um segundo clique na bolinha desabilita o *breakpoint*, mas não o exclui da aba **Breakpoints** (Alt+B). Um terceiro clique o exclui totalmente.

Após colocar o *breakpoint* nesta CALL, rode o programa (F9). O que acontece? O *debugger* executa todas as instruções anteriores a este *breakpoint* e pára onde você pediu. Simples assim.

## Como *Breakpoints* são Implementados

Talvez você tenha notado que ao atingir um *breakpoint*, o x64dbg mostra na barra de status a palavra “Paused” e a frase **INT3 breakpoint at analyzeme00.0000000140001019!**. Este é um tipo de **breakpoint de software**. Para entender como ele funciona, acompanhe a explicação a seguir.

A instrução INT é uma instrução Assembly que gera uma interrupção. A interrupção número 3 é chamada de **Breakpoint Exception (#BP)** no manual da Intel. Seu *opcode* (0xcc) tem somente um *byte*, o que facilita sua implementação nos *debuggers*.

De forma resumida, para parar nesta CALL, o que o x64dbg faz é:

1. Substituir o primeiro *byte* do *opcode* da CALL (0xff, neste caso) por 0xcc e salvar o original numa memória.
2. Rodar o programa.
3. Restaurar o primeiro *byte* do *opcode* da CALL, substituindo o 0xcc por 0xff (neste caso).

Isso poderia ser feito manualmente, mas os *debuggers* facilitam o trabalho, bastando você pressionar F2 ou clicar na bolinha para que todo este trabalho seja executado em segundo plano, sem que o usuário perceba. Incrível, não é?

Você pode adicionar quantos *breakpoints* de software quiser numa sessão de *debugging*. Todos ficam acessíveis na aba **Breakpoints**, a não ser que você os exclua. Veja como eles ficam organizados:

![Lista de breakpoints](/files/KHG9xgzn69HfgePPQp3E)

Você também pode assistir a [aula do CERO](https://youtu.be/823KK-FYV9s), que trata sobre este assunto.

> Existem ainda os *breakpoints* de memória e de hardware, mas não trataremos deles neste livro.


---

# 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/09-depuracao/breakpoints.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.
