Engenharia Reversa: Primeiro Contato - Parte 1
Tags: braziliandevs, tutorial, beginners, debugging
Published: 2024-03-17 15:22:02

Você vai praticar engenharia reversa pela primeira vez.
"Engenharia reversa", na área de T.I. refere-se à engenharia reversa de software, que, a grosso modo, é a prática de entender o funcionamento de um software alheio, "nos mínimos detalhes".

Esse tutorial é uma breve introdução ao uso do **debugger x64dbg**, que é pré-requisito para o próximo tutorial.

Esse tutorial foi escrito para os iniciantes, o intuito é lhe preparar para o próximo tutorial: Debugando um programa crackme; observe que um é complemento do outro.
Programas "crackme" são softwares com algum tipo de desafio, como, por exemplo, descobrir uma senha de acesso ao próprio crackme.

**O maior objetivo disso tudo, é mostrar um pouco desse mundo para pessoas que têm interesse em "baixo nível", mas não sabem se "isso é para elas".**
**Quero lhe ajudar a ter o "primeiro gostinho" desse mundo...**

## Lista de Conteúdo

- [O que é um Debugger](#o-que-é-um-debugger)

- [Sobre a Nomenclatura "x64dbg"](#sobre-a-nomenclatura-x64dbg)

- [Antes de começar](#antes-de-começar)

- [Baixando o x64dbg](#baixando-o-x64dbg)

- [Abrindo o x64dbg](#abrindo-o-x64dbg)

- [Mapeando as partes mais usadas da Interface Gráfica](#mapeando-as-partes-mais-usadas-da-interface-gráfica)
	- [Botões de controle do Debugger](#botões-de-controle-do-debugger)
	- [Atalhos para Funcionalidades](#atalhos-para-funcionalidades)
	- [Janelas mais usadas](#janelas-mais-usadas)
	- [Mapeando a janela CPU](#mapeando-a-janela-cpu) 
		- [Coluna de Endereços](#coluna-de-endereços)
		- [Coluna de Opcodes](#coluna-de-opcodes)
		- [Coluna de Instruções Assembly](#coluna-de-instruções-assembly)
		- [Coluna de Comentários](#coluna-de-comentários)
		- [Coluna de Registradores](#coluna-de-registradores)
		- [Stack](#stack)
		- [Dump de memória](#dump-de-memória)
		- [Status do programa Debugado](#status-do-programa-debugado)
- [Rodando Primeiro Programa no x64dbg](#rodando-primeiro-programa-no-x64dbg)
	 - [Encontrando Strings](#encontrando-strings)
	 - [Noções básicas sobre Funções em Assembly](#noções-básicas-sobre-funções-em-assembly)
	 - [Atalhos úteis](#atalhos-úteis)

- [Final: Considerações e Recomendações](#final-considerações-e-recomendações)
	- [Caso esteja procurando obter os fundamentos da computação, eu sugiro que você confira os links desta área](#links-para-iniciantes)

---

### O que é um Debugger

Debugger é um software que serve para "debugar" e testar programas.
"Debugar" é o processo de procurar bugs.
Bugs são erros ou problemas em um software.
E "testar", aqui, se define como "fazer oque quisermos com o software".

O Debugger lhe fornece acesso ao programa compilado. 
Em um debugger, você vai ter acesso aos seguintes recursos: 

* Valores das suas variáveis em memória - Mapa de memória
* Suas linhas de código transformadas em instruções Assembly
* Módulos (dll's e lib's) usados
* Threads e Handles

---

### Sobre a Nomenclatura "x64dbg"

Não se confunda: o nome do programa como um todo é **x64dbg**.
Ele possui dois APLICATIVOS que são chamados x64dbg e x32dbg.

Você sempre deve saber qual dos dois deve usar para debugar um programa em específico, dependendo da plataforma para a qual o programa foi compilado:

* o aplicativo chamado **x64dbg** serve para debugar programas de 64 bits.
* o aplicativo chamado **x32dbg** serve para debugar programas de 32 bits.

Caso você não saiba se o seu programa é de 32-bits ou se é de 64-bits, abra o link:
[Como saber se um programa é 32 ou 64 bits no windows](https://www.tecwhite.net/2018/09/como-saber-se-um-programa-e-32-ou-64-bits-no-windows.html).


**No tutorial a seguir, quando eu disser "x64dbg", eu estarei me referindo ao programa como um todo, e não ao aplicativo específico.**

---

### Antes de começar


* Vou trabalhar apenas com **Assembly de x86_x64**:<br>
<blockquote>
      Assembly não é uma linguagem de programação comum, como <strong>C</strong>, que
      você aprende e sai criando programas para "qualquer coisa":
      há diversos processadores, e cada um possui uma arquitetura,
      que vai dizer como as instruções são nomeadas e como vão 
      funcionar, que dita o nome e funcionamento dos
      registradores, etc.<br>
Mais sobre: <a href="https://www.arm.com/glossary/isa#:%7E:text=An%20Instruction%20Set%20Architecture%20(ISA,as%20how%20it%20gets%20done)" target="_blank">ISA-Instruction Set Architecture</a>
</blockquote>

* Não é esperado nenhum conhecimento prévio sobre debuggers ou Assembly. 
* É esperado conhecimento básico em programação, e processo de compilação.

* Conhecimento sobre fundamentos da computação lhe ajudarão a entender melhor o que se passa aqui. (Nota: Você pode usar um debugger para reforçar os estudos dos fundamentos da computação, já que, dessa forma, irá ver as coisas acontecendo na prática).

* O básico sobre sistemas numéricos é esperado.

Espero lhe dar um overview de como é usar um debugger, mas tenha em mente que tópicos extremamente importantes estão sendo deixados de lado para não lhe "inundar" de informações no início. Entenda isso como um "Quick Overview".

Se estiver procurando obter os fundamentos da computação, confira os links deixados na parte final.

---

### Baixando o x64dbg
<blockquote>
   <ul>
      <li>Vá ao site oficial: <a href="https://x64dbg.com/" target="_blank">x64dbg.com</a></li>
      <li>Clique em <strong>Download</strong></li>
      <li>Você será redirecionado ao site da Sourceforge. Clique em <strong>Download Latest Version</strong></li>
</blockquote>

### "Instalando" o x64dbg

<blockquote>
   <ul>
      <li>Extraia o arquivo zip. Você pode criar uma pasta em qualquer lugar para armazená-lo.</li>
      <li>Abra a pasta extraída</li>
      <li>Vá em: <strong>release/x32</strong>, ache o aplicativo <strong>x32dbg</strong> e crie um atalho na área de trabalho</li>
      <li>Vá em: <strong>release/x64</strong>, ache o aplicativo <strong>x64dbg</strong> e crie um atalho na área de trabalho</li>
   </ul>
</blockquote>

----

### Abrindo o x64dbg

Para abrir qualquer programa no x64dbg: 
* Abra o x64dbg
* Clique em **Arquivo -> Abrir** (ou clique em **F3**)
* Alternativa: Arraste o programa para um dos atalhos do x64dbg
* Para abrir um programa que está rodando, abra o debuger, clique em **Arquivo -> Anexar/Attach** e escolha o programa.

---

### Mapeando as partes mais usadas da Interface Gráfica


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wok6e4zas0brdc3vc7yx.PNG)
*\* Guie-se pelas cores*.

### Botões de controle do Debugger


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o6dbcglt6xkwg2ooqq3h.PNG)Área com os botões de controle do Debugger. Clique em **Debug** (ao lado de **Exibir**) para ver todos os nomes e atalhos dos botões nessa seção. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71u93hk5luwwtasjx1wz.PNG)

* Ícones, da esquerda para a direita:
	1. Abrir Arquivo
	2. Recarregar programa
	3. Fechar programa que está carregado
	4. Rodar programa carregado
	5. Pausar programa carregado
	6. Step Into: anda, de instrução em instrução, e entra nas instruções ``call``: instruções ``call`` chamam outras funções. "Entrar nelas" quer dizer ir até a função.
	7. Step Over: anda, de instrução em instrução, e NÃO entra nas instruções ``call``

Não vou comentar sobre os outros botões, para saber sobre eles: 
	https://help.x64dbg.com/en/latest/gui/views/Trace.html
	https://help.x64dbg.com/en/latest/introduction/ConditionalTracing.html

---

### Atalhos para Funcionalidades


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gisze7uuod0u5xrercy2.PNG)Atalhos para algumas funcionalidades do x64dbg (não entrarei em detalhes).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x6eblrafe900zk8630zb.PNG)
 
Vou mencionar apenas o quinto, da esquerda para a direita, que é o ícone de favoritos.
Quando você quiser salvar alguma localização de instrução, use **CTRL+D**, que a instrução selecionada será salva nos favoritos. Clique no atalho mencionado para ser direcionado aos favoritos.

---

### Janelas mais usadas


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oj4hrbt2qgzh65mezp9h.png)Nessa parte do x64dbg, você tem todas as janelas de funcionalidades do programa.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/02whk8xmuo1373kovgg6.PNG)
 
Só marquei na caixa amarela as que eu vou estar comentando. Para você começar a usar o programa, acredito que só precisa dessas janelas. Mas não deixe de aprender todas, caso queira prosseguir nos estudos.

Clicando em **exibir** (ao lado de Arquivo, canto superior esquerdo) você pode habilitar as janelas que não estiverem aparecendo, e também pode ver os atalhos para cada uma delas.
Na imagem acima, se encontra a janela **CPU**, que será comentada no final desta parte sobre janelas.

<blockquote>
   <ul>
      <li><strong>Janela Breakpoints</strong>: breakpoints são 
          pontos de parada, locais em que o programa vai parar 
          obrigatoriamente. Logo falaremos mais sobre breakpoints. 
          E nessa janela você tem acesso aos breakpoints que estão 
          setados no programa todo. Aqui você pode manipular 
          breakpoints, habilitando-os, desabilitando-os, ou mesmo 
          removendo-os, e é até possível editá-los. Clicando em um 
          deles, você será direcionado até o local em que ele está 
          setado, na janela CPU.
  <li><strong>Janela de Símbolos (Modules)</strong>: essa é 
          uma janela de extrema importância para algumas 
          atividades, já que ela nos mostra os módulos importados 
          pelo programa, inclusive o módulo do próprio programa.  
     

      <li><strong>Janela Referências</strong>: Aqui temos as 
          referências, que procuramos da seguinte maneira: Dentro 
          da janela CPU, clique com o botão direito do mouse, bem 
          no final você vai encontrar "Pesquisar por" e "Encontrar 
          referência aos":  
          
      <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abgzv6pirlgpdbhybqlb.PNG" alt="Descrição da imagem">
      <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ntq6rheu41z1fc6gg3p4.PNG" alt="Descrição da imagem">
Os resultados das pesquisas feitas por essas opções serão mostrados na janela **Referências**.

      <li><strong>Janela Mapa de Memória</strong>: Como o nome 
          diz, é um mapa da memória do programa todo. 
          Você pode ver onde um determinado endereço se  
          encontra da seguinte maneira:
          <ul>
             <li>Dentro da janela CPU, selecione um endereço 
                 desejado (sobre endereços, comentarei mais a  
                 frente)
             <li>Dentro da janela CPU, clique com o botão direito  
                 do mouse em cima do endereço desejado
             <li>Clique em "Seguir no Mapa da Memória":

             <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5a2wjcof5shlspd3r5fd.PNG" alt="Descrição da imagem">
             <p>Você verá as informações a respeito do endereço  
                selecionado no mapa de memória.</p>
          </ul>

      <li><strong>Janela CPU</strong>: Nos mostra tudo o que  
          estamos vendo na imagem "mapeada" acima, e por essa ser  
          a janela principal, todos os comentários às marcações  
          com cores a seguir, serão sobre ela.
   </ul>
</blockquote>

---

## Mapeando a janela CPU 

Vamos passar a maior parte do tempo nessa janela, ela é a janela principal do x64dbg.

### Coluna de Endereços


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bw2jeh9hwpeb7bfpxwix.png)![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6uwircwtamzdam80nof.PNG)

Na primeira coluna da grande área, nós temos os endereços de memória (endereços de memória virtual, **Virtual Address - VA**).
A marcação verde nos mostra qual a próxima instrução a ser executada. O destaque em dourado é uma instrução marcada como "favoritos" usando CTRL+D.
Para saber mais sobre endereços de memória: https://learn.microsoft.com/pt-br/windows/win32/memory/virtual-address-space

---

### Coluna de Opcodes


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdrx3k3xqaydebqgha4i.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e29d25yatmesm1jqzecp.PNG)

Na segunda coluna da grande área, nós temos os Opcodes, que são códigos de operação, eles ditam uma operação a ser executada pelo processador (por isso do nome **OPeration Code**);
Aqui estão em hexadecimal. Cada opcode é usado para formar uma **instrução** Assembly. Os opcodes também são chamados de Código de Máquina, e isso é oque chamamos de Assembly. 

Por exemplo, temos a instrução chamada ``add``, que soma dois operandos. 
Em Opcode ela é equivalente a um dos seguintes, dependendo do contexto (na imagem, coluna Opcode, lado esquerdo):


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/piwfyezess685vb2uj8d.PNG)Isso é a tabela que nos mostra como a instrução ``add`` é montada em arquitetura Intel x86_x64.
Repare as colunas **64-bit Mode**, para programas de 64 bits e **Compat/Leg Mode** para programas de 32 bits. Para saber mais, clique no link: 
<a href="https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html" target="_blank">Manual da Intel para desenvolvedores.</a>

Vamos ver qual opcode obtemos compilando um programa para um sistema de 64 bits:

```
// Programa em C
int main(){
   int primeiro_numero = 3;
   int segundo_numero = 2;
   int resultado_da_soma;

   resultado_da_soma = primeiro_numero + segundo_numero;

   return 0;
}
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gobgya5sd705d4fao1m0.PNG)Repare na linha selecionada: o programa está com o opcode ``03 /r``.

---

### Coluna de Instruções Assembly


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvrl96zwmnt3skr1p3r9.png)Na terceira coluna da grande área, nós vemos as instruções Assembly. Falamos sobre elas anteriormente, na coluna dos Opcodes.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v844ewkms9vnu0ne6s1y.PNG)

---

### Coluna de Comentários


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ka82lc94oa38d1os9f8o.png)Na quarta coluna da grande área, temos a seção de comentários.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l36eankrops1azoj7zp2.PNG)

Podemos ter comentários automáticos, por exemplo, no caso de instruções que estão carregando uma string, vamos ter a própria string como comentário. Também podemos adicionar nossos comentários, basta clicar na tecla ``;`` e escrever algo, ao terminar é só dar ``enter``.

---

### Coluna de Registradores


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ny8b53ktc2hkhrl79ih4.png) Aqui, no lado extremo direito, temos os registradores e seus conteúdos.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/88kuzd60rk1vlwc1zmqd.PNG)

Os registradores são espaços de memória dentro do processador, e funcionam como variáveis temporárias.

Há **registradores de propósito geral**, que sempre vão ser usados para coisas diversas:

**Registradores de Propósito Geral x64:** 
* RAX
* RBX
* RCX
* RDX
* RSI
* RDI
* R8, R9, R10, R11, R12, R13, R14 e R15. Em x64 temos esses oito registradores a mais.

**Registradores de Propósito Geral x86:** 
* EAX
* EBX
* ECX
* EDX
* ESI
* EDI

Em teoria esses registradores podem ser usados para qualquer coisa, mas há situações em que RDI/EDI e RSI/ESI são usados de forma exclusiva por certas instruções.

Também há registradores que servem para armazenar coisas específicas.
Vou mencionar apenas os que considero mais importantes para o momento. 
Para saber mais, não deixe de ler: 
<a href="https://blog.yossarian.net/2020/11/30/How-many-registers-does-an-x86-64-cpu-have" target="_blank">How many registers does an x86-64 cpu have</a>

<a href="https://asm.lucasteske.dev/registers/x86" target="_blank">Registradores x86 (32 e 64)</a>

**Alguns Registradores de uso específico (na ordem: x64/x86):**
* RSP/ESP - Ponteiro para o **topo** da stack/pilha
* RBP/EBP - Ponteiro para a **base** da stack/pilha
* RIP - Ponteiro para a próxima instrução a ser executada. **IP** - Instruction Pointer (vai ser mostrado como **RIP** em x64, e **EIP** em x86). É por esse registrador que nós sabemos onde estamos dentro do programa, durante o fluxo de execução.
Como ele tem o valor da próxima instrução a ser executada, estamos exatamente "um passo" atrás dele.

*\*Também deixei de mencionar os registradores que lidam com float's.* Mais sobre: https://my.eng.utah.edu/~cs4400/sse-fp.pdf

---

### Stack


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7zxh0mk3fb61wuhyn2h.png)Abaixo dos registradores, nós temos a Stack, também chamada de pilha (em pt-br).
A stack/pilha é um segmento de memória que opera com uma estrutura de dados de pilha (stack), por isso do nome. 
Aqui nós temos os valores de nossas variáveis locais. Enquanto você estiver dentro de uma função, seus dados locais vão estar ali.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yw5ul9f130nnbc4ii90j.PNG)A coluna da esquerda representa o endereço da stack/pilha, e a coluna da direita nos mostra o valor armazenado naquele endereço.

A stack/pilha é uma estrutura de dados do tipo **LIFO** - Last In First Out, ou último a entrar, primeiro a sair. Todo mundo costuma usar o exemplo de uma pilha de pratos para explicar a stack: em uma pilha de pratos, qual prato você tira PRIMEIRO? O último empilhado, ou o primeiro, que deu início a pilha?
É lógico que, primeiro, você tira o que está no topo, **LIFO**...

Lembra dos registradores RSP e RBP? Então, é aqui que eles entram: RSP aponta para o topo da pilha, e RBP aponta para a base da pilha.
É assim que o layout de memória de uma função é delimitado e manipulado, através desses registradores.

E isso é que é chamado "stackframe", é o espaço de memória reservado para uma função.
Veremos um pouco mais sobre isso em "Noções básicas sobre funções em Assembly".

---

### Dump de Memória


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/erafzbmmr0cyomfj4yvs.PNG)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ax80rbv4jn0himx3on91.png)Ao lado esquerdo dos registradores, nós encontramos um dump da memória em hexadecimal.
Você pode clicar com o botão direito do mouse em qualquer instrução, e seguir tanto o endereço dela, quanto algum endereço que ela esteja operando. Também é possível fazer o mesmo nos registradores.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zgehgc8jglqu1rzgg5p.PNG)Voltando a imagem do Dump, a coluna mais a esquerda mostra o endereço respectivo aos dados hexadecimais nas quatro colunas seguintes (quatro colunas na configuração padrão).
Na última coluna, mais a direita, temos a representação ASCII dos dados em memória.

Também podemos alterar a visualização dos dados do dump: além de hexadecimal, ele nos mostra os dados como Inteiros e Floats. Basta clicar com o botão direito do mouse na área de dump e clicar em "Integers" ou em "Floats".

Na parte de cima nós temos vários dumps, para os quais você pode direcionar a visualização de algo que lhe interessar. Também temos outras funções, mas não vou mencioná-las aqui. Para saber mais, leia: <a href="https://help.x64dbg.com/en/latest/commands/watch-control/index.html" target="_blank">Watch Control
</a>

---

### Status do programa debugado


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fktp9e6r3vq49jmsa9ih.png)Aqui, no canto inferior esquerdo, nos é mostrado em que situação o programa debugado se encontra, como, por exemplo, se ele está em execução, ou pausado, e se estiver pausado, o motivo.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j8uwbdiac4r8it6ybowt.PNG)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rd1ihcytdtfn1gmqme93.PNG)

---

### Rodando primeiro programa no x64dbg

Bom, agora que você já sabe como abrir o seu programa no x64dbg, vamos aprender mais algumas coisas antes de seguirmos para o próximo tutorial.
Abra qualquer programa com o x64dbg, de preferência um feito por você mesmo.

Em seguida, abra a janela (em vermelho) da seguinte maneira: Clique em **Options -> Preferências**
E aí desmarque a caixinha apontada pela seta, **System Breakpoint**. Assim você desativa alguns breakpoints "desnecessários" para nós agora (para saber mais sobre System Breakpoints: https://www.youtube.com/watch?v=vdyyg72tc2w). 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vffr716nsrhyla7bezr.PNG)

Ao abrir o programa, ele vai ser mostrado na barra de tarefas somente quando for carregado. Eu estou abrindo um programa simples, ele já carrega a janela de primeira. 

Se for um programa mais complexo, ele vai carregar outras coisas antes de poder desenhar a janela. Basta clicar em **RUN** (**F9**) até parar em um breakpoint: entry breakpoint, que você vê ao lado do status do programa:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4dj8y368cbr7nrz3pe7j.PNG)
Sempre acompanhe o status do programa na barra inferior, ao lado do **PAUSE**.

Vamos tentar encontrar nossas funções. Se o programa não foi "cuidadosamente estripado", achar a função principal, **main**, não é tão difícil. 

Vá até a janela **Símbolos**, que possui nossos módulos, encontre o módulo principal (que possui o nome do próprio programa rodando), clique nela e seja direcionado para o início desse módulo:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9pr4g4chw7cn83jcob8m.PNG)Assim , se o programa não for extremamente complexo, você vai encontrar a main.

**Dica**: os programas compilados para x86, geralmente mantêm a função **main** no topo, então assim que o programa parar no entry breakpoint, vá ao topo das instruções que você encontrará a **main**.

---

#### Encontrando Strings

Outro modo de encontrar a main, é quando ela chama alguma string.
Para encontrar as strings dentro do programa é fácil:

   na janela CPU, clique com o botão direito do mouse no meio da janela, vá até
    **Pesquisar Por -> All User Modules -> Referências String**.

Carregando as strings na janela de referências, procure pela que você sabe que é usada na main, e aí clique nela. Você será redirecionado para o local em que ela aparece no programa, na janela CPU. O início da função, é o início da main, a nossa função principal, que o programador escreveu.

---

### Noções básicas sobre funções em Assembly

Toda função em Assembly possui um **prólogo** e um **epílogo**.

Normalmente as funções possuem as seguintes instruções no início (o prólogo):
	
	push ebp
	mov ebp, esp
	
E a seguinte instrução no final (o epílogo):
	
	ret 
*Lembre-se que as instruções em x64 utilizam os registradores ``rsp`` e ``rbp``*

No início, o programa salva o valor que está no registrador **EBP/RBP** com ``push ebp``. Esse valor é o endereço da base da stack/pilha da função anterior; lembre-se que a stack/pilha possui os valores das variáveis locais, e que as variáveis locais são variáveis declaradas e/ou definidas dentro das funções (somente as variáveis definidas, isto é, variáveis com valores, vão ser colocadas na stack/pilha).

Após salvar o valor de **EBP**, um novo stackframe é iniciado; em outras palavras, um novo local ("local" se refere a um bloco de memória na stack) para guardar as variáveis dessa nova função é "delimitado". Isso é feito com ``mov ebp, esp``.

Tenha em mente que, para cada nova função, um novo stackframe é mapeado e alocado para ela, assim, cada função lida somente com os valores das suas próprias variáveis.

Você vai precisar saber sobre calling conventions para entender como os argumentos são passados para as funções, eu não irei explicar isso aqui, então se quiser saber mais, não deixe de ler:
https://en.wikipedia.org/wiki/X86_calling_conventions
<a href="https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/linux-x64-calling-convention-stack-frame" target="_blank">Calling Convention Stack Frame</a>

---

### Atalhos úteis

Clicando com o botão direito do mouse no meio da janela CPU, vá até "**Ir Para**", lá você terá acesso as seguintes funcionalidades (decore os atalhos):


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7dw7kj4d4xwv6egrshdi.PNG)Os atalho mais úteis de todos são o primeiro e o segundo: 
1. RIP ``*``: ele te direciona para onde o seu programa está no momento, seguindo o **RIP**.
2. Anterior ``-``: Volta para a instrução executada anteriormente.

---

### Final: Considerações e Recomendações

Não deixe de fazer o tutorial prático com o x64dbg [COLOCAR LINK QUANDO PRONTO].

Os debuggers são poderosos e úteis para as mais diversas atividades na área da computação. O x64dbg faz muitas coisas, várias delas eu deixei de mencionar aqui, como, por exemplo, alterar as instruções de um programa, para modificar sua funcionalidade.
Quanto mais você for estudando sobre tópicos de engenharia reversa, mais os debuggers se mostrarão úteis. Você irá se aprofundar nas diversas funcionalidades conforme a sua necessidade.

Um site muito bom para continuar praticando a leitura de Assembly é o seguinte: <a href="https://godbolt.org/" target="_blank">godbolt.org</a> Selecione uma linguagem, como C ou C++, escolha um compilador, e comece os testes.

#### Caso esteja procurando obter os fundamentos da computação, eu sugiro que você confira os links desta área:

**Guia de estudos:** https://www.mentebinaria.com.br/studying-materials/basico-para-computacao/

**Tutorial Gratuito de Assembly pt-br:** https://github.com/andreluispy/assembly4noobs

**Livro Gratuito de Assembly em pt-br**: https://mentebinaria.gitbook.io/assembly/

**Fundamentos da Engenharia Reversa pt-br:** https://mentebinaria.gitbook.io/engenharia-reversa/

**Curso de Engenharia Reversa Online (vídeo pt-br)**: https://www.youtube.com/playlist?list=PLIfZMtpPYFP6zLKlnyAeWY1I85VpyshAA

**Livro Em Inglês para iniciantes em Engenharia Reversa en**: https://beginners.re/