# 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](https://2831222458-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L8zFFHkPxQb-_1XSGR9%2Fuploads%2Fgit-blob-6a2b625b1ed034fc56347abc4a0176383772f0b2%2Fx64dbg_breakpoint.png?alt=media)

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](https://2831222458-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L8zFFHkPxQb-_1XSGR9%2Fuploads%2Fgit-blob-01f642ff50165513831ecf422a204e42e208b8ba%2Fx64dbg_breakpoints.png?alt=media)

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.
