Ir para conteúdo
Faça parte da equipe! (2024) ×
Conheça nossa Beta Zone! Novas áreas a caminho! ×
  • Quem está por aqui   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.

Guia Assembly


- NOOB
 Compartilhar

Posts Recomendados

Olá pessoal estou aqui trazendo de um outro forum esse Guia de Assembly , eu não escrevi nada daqui, só estou formatando e deixando de um jeito mais legal para se compreender.

então primeiramente irei colocar os creditos :

Black-Hat [GH]

 

 

Então Vamos la , Bons Estudos!

 

 

 

Conhecendo a Linguagem

 

Assembly é uma linguagem de programação extremamente poderosa e relativamente de difícil implementação, pois seus comandos e suas estruturas são bem mais próximos da linguagem computacional. Raramente encontramos programas puramente feitos em Assembly, uma vez que tal linguagem exige tempo e muito raciocínio. Geralmente essa poderosa linguagem é implementada junto a alguma outra, funciona como auxiliar. Por exemplo, em programas que exigem uma interação mais profunda com o hardware de uma máquina, podemos implementar códigos Assembly junto ao código em C, C++ ou qualquer que seja a linguagem utilizada. Outro exemplo prático do uso de Assembly são os famosos ShellCodes presentes nos exploits. E ainda, como último exemplo, temos os nossos amigos “Reversers” (popularmente chamados de “crackers”, pois crackeiam programas) que usam muito o Assembly. Um bom “reverser” (“cracker”) sabe profundamente Assembly

 

Todos os processadores possuem uma "linguagem" própria embutida em cada um deles e cada instrução (comando) dessa linguagem produz um efeito diferente no processador, através de seus registradores. Essas instruções são representadas por números como, por exemplo, a famosa instrução MOV DL é representada pelo número B2 em hexadecimal (178 em decimal). Esses números, em Assembly, são trasnformados nos chamados mnemônicos para uma maior facilidade. Por exemplo, ao invés de você escrever B2 e ter de decorar o que é cada número, você vai escrever o mnemônico dele que, nesse caso, é o MOV DL. Onde MOV significa MOVer e DL é o chamado byte baixo de um outro registrador (DX).

 

"Meu Deus! Fiquei espantado com essa introdução!!! Assembly é difícil demais!!"

 

Tenha calma...Assembly não é aquele bicho de sete cabeças como todos dizem(e como parece ser também)...no começo parece que você não vai entender nada, mas depois as coisas começam clarear e você vai entendendo cada vez mais, até que começa a realmente utilizá-lo em seus projetos.

 

Bom...vamos em frente...temos bastante chão ainda

 

Registradores

 

Quem já deu uma fuçada nessa linguagem de programação, com certeza ouviu falar dos famosos Registradores...

 

Mas, Black-Hat, o que são os tais registradores??

 

Bom...uma das maneiras mais fáceis de explicar um registrador é compará-lo a uma variável, eles são como "espacinhos" reservados dentro do processador para guardar os códigos operacionais (MOV, JMP, NOP...), são uma espécie de "memória" temporária do processador.

Existem vários registradores, deles, os mais usados são 8, que são denominados Registradores de Uso Geral. Mas desses 8, os que realmente se utiliza bastante são apenas 4, são eles: AX, BX, CX e DX.

Um registrador armazena 16 bits, o que é correspondente a 2 bytes. Nas máquinas de 32 bits, temos o EAX, o EBX, o ECX e o EDX que são registradores que podem guardar 32 bits (segundo a matemática avançada, o equivalente a 4 bytes, pois 32/8 = 4 uahSIUHauhs).

Os nomes dos registradores sugerem pra que servem, o AX é o Acumulador, o BX é a Base, o CX é o Contador e o DX possui um D que deriva de Dados. Esses nomes surgiram devido ao uso mais comum deles, o AX é mais utilizado como acumulador, BX como base e etc...

 

"Aff Black-Hat, não aguento mais ler..." ... Calma, tá acabando (a parte de registradores ;P)

 

Bom...como eu havia dito, os registradores armazenam 2 bytes, que são chamados de Byte Alto e Byte Baixo, cada registrador possui o seu BA e o seu BB. Se quisermos acessar o byte alto do registrador AX, por exemplo, vamos utilizar o AH e observem que, mais uma vez o nome não está aí a toa...Alto em inglês é High e por isso AH. Se quisermos acessar o byte baixo de AX, utilizamos o AL (baixo em inglês é Low).

 

 

Pronto!! Agora SÓ falta vermos as instruções, as variáveis, saltos...e mais umas coisinhas biggrin.gif

Prepare-se psicologicamente, vá beber uma água ou namorar um pouco...porque agora começa a parte mais importante (e mais legal tbm xD).

 

 

Vamos falar sobre as instruções mais utilizadas: a MOV e a INT.

 

A Instrução MOV

 

A instrução MOV, uma das mais utilizadas, deriva da palavra MOVe, então, já da pra saber o que ela faz, né? Ela move dados de um lugar para outro(de um registrador para outro, por exemplo) ou insere dados nos registradores. Alguns exemplos de utilização da nossa querida instrução MOV:

 

É necessário se cadastrar para acessar o conteúdo.

A Instrução INT

 

A instrução INT chama uma interrupção de software(calma, não se desespere com o nome...vc não vai precisar desse nome).

Tá, mas, pra que serve isso afinal??

O DOS e a BIOS do seu computador e de todos têm várias funções interessantes que podemos acessar com interrupções de software.

Por exemplo:

É necessário se cadastrar para acessar o conteúdo.

Agora um programa BEMMMM básico(não chega nem a ser um Hello World):

 

É necessário se cadastrar para acessar o conteúdo.

O que esse programa faz? Bom...ele simplesmente termina (não, eu não estou bebado...ele nao faz nada alem de terminar)

 

Bom pessoal...vocês devem estar se perguntando porque eu chamei a interrupção 21 e não a 55, por exemplo. Bom...pra explicar isso vou precisar da ajuda de um "livrinho virtual", uma referência, que se chama HelpPC...

Vou deixar o link de download pra vcs baixarem, ok? (não vou anexar porque o limite maximo de anexo Zip é menor do que o tamanho do arquivo)

Assim podemos continuar...

 

Link:

É necessário se cadastrar para acessar o conteúdo.

 

 

Continuando....

 

 

Ao abrirmos o HelpPC, caimos em uma tela inicial, chamada de Main Topic Menu. Vá até o item "Interrupt Services DOS-BIOS-EMS-Mouse" e de um enter nele. Agora vá em "DOS Functions" e aperte enter novamente. Procure pela função que utilizamos acima, a "INT 21,4C".

Bom...agora estamos na tela que nos mostra informações detalhadas sobre tal função, podemos observar que essa função recebe o nome de "Terminate Process With Return Code", traduzindo: Terminar Processo Com Código de Retorno. Olhando melhor na tela, percebemos que o HelpPC nos indica que o byte alto de AX deve ter o valor 4C e que o valor baixo deve ter o código de retorno do nosso programa. Quem programa em C/C++ já sabe o que é o código de retorno do programa...é um código, um número, que o programa retorna ao ser finalizado. Observamos também qeu a função 21 não retorna nenhum valor (o que seria chamado de rotina em outras linguagens).

 

Resumindo...para usar essa função, basta você colocar os valores que são exijidos no registrador AX e depois disso é só chamar uma interrupção de software 21 (INT 0x21).

 

Caso você esteja super curioso pra ver o nosso "programa" funcionar, baixe o NASM e compile-o, como? simples...

Salve o código fonte dele como Terminator.asm no bloco de notas ou com qualquer outro nome que queira...

Depois vá no DOS e digite:

nasm -o Terminator.com Terminator.asm

e então você obterá o seu super programa compilado no arquivo Terminator.com =)

 

Tá...vamos fazer um programa um pouco melhorzinho...ele vai escrever um caractere na tela...

 

Se procurarmos no HelpPC a função que escreve um caractere na tela vamos achar a INT 21,2.

Observem que precisamos do valor 02 no byte alto de AX (AH) e precisamos que o caractere a ser mostrado esteja no byte baixo de DX (DL). Pronto! Agora é só fazer isso...Let's Go

 

 

 

É necessário se cadastrar para acessar o conteúdo.

Bom...nosso programa precisa terminar ... basta adicionar o código do programa anterior...Ficando assim:

 

É necessário se cadastrar para acessar o conteúdo.

Agora é só compilar e boa! =)

 

>>> As Variáveis <<<

Bom...o conceito de variável em assembly é o mesmo das outras linguagens de programação, com pouca diferença, então acho que não teremos problemas com elas. Em Assembly, os dados são inseridos diretamente no programa e são rotulados com um nome que você quiser (semelhante às outras linguagens xD). Os tipos de variáveis são:

Byte(B) = 8 bits = 1 byte

Word(W) = 16 bits = 2 bytes

DWord(D) = 32 bits = 4 bytes

Agora vamos ver como "declarar" as variáveis. Iremos utilizar DB, DW e DD (Byte, Word e Double Word)

Alguns exemplos:

 

É necessário se cadastrar para acessar o conteúdo.

 

strg DB 'abcd' ; uma string de 4 bytes chamada "strg" é inserida

Não tem segredo smile.gif

 

Agora vamos ver como manipular nossas variáveis:

 

É necessário se cadastrar para acessar o conteúdo.

 

Quando quisermos pegar o valor das variáveis, tiramos os colchetes, assim:

 

É necessário se cadastrar para acessar o conteúdo.

 

 

--Vamos escrever uma string na tela--

 

Essa parte parece perda de tempo, mas não é, ela será essencial para a próxima parte....portanto, vamos escrever a nossa string na tela xD

Se procurarmos no HelpPC a função que imprime caracteres na tela, vamos encontrar a INT 21,9 (serviço 9 da interrupção 21).

Então, de repente, você olha pra tela e ve que o DSX tem que apontar para uma string terminada em $ (MEU DEUSSS!!! O QUE É ISSO??). Bom...vamos ignorar o tal do DSX por enquanto, nao se assuste, eu avisei que ia complicar um pouquinho...mas nada que um cérebro não resolva...

Bom...o DX precisa conter o endereço da string que vamos exibir(precisa ser um ponteiro para a string).

Bom...como vocês sabem...esse programa é um programa DOS, roda no "console" do windows...entao temos algumas coisas que devemos lembrar:

Todo programa DOS é carregado no endereço 0x100. O NASM precisa de um endereço para calcular o valor dos ponteiros no programa, entao temos que dizer ao NASM que o nosso endereço base (endereço onde o programa será carregado) é o 0x100, como? usando o comando ORG (derivado de ORiGem), assim:

 

É necessário se cadastrar para acessar o conteúdo.

pronto...agora o NASM sabe o endereço base e pode calcular o valor dos ponteiros =)

 

Então agora MÃO NA MASSA...

 

É necessário se cadastrar para acessar o conteúdo.

 

Uffa...acabamos variáveis =)

Tá começando a ficar mais interessante né? biggrin.gif

Então vamos complicar mais, para ficar mais interessante...

 

 

>>>Entrada do teclado<<<

Abrimos o HelpPC felizes e contentes, procuramos por uma funçao que pegue as teclas digitadas...e então encontramos a função DOS 21,A. Oba! vamos entrar nela...PELAS BARBAS DO PROFETA!!!(expressão de véio) O QUE SÃO ESSES "BAGULHOS" ESCRITOS AQUI???

Haha...contenha-se...eu sei seu sei...parece complicado, mas você é um hacker, você vai entender...

 

Bom...olhando para a tela de informações sobre a função, DSX deve ser um ponteiro para um buffer com 3 partes:

-MAX : o numero maximo de caracteres que devem ser lidos

-COUNT : o número de caracteres retornados

-BUFFER : a parte aonde os dados serão guardados

 

 

Dessa vez vai ser diferente, primeiro o código para ajudar-nos:

É necessário se cadastrar para acessar o conteúdo.

Calma...eu sei que parece uma coisa estranha...vou explicar smile.gif

 

Na área max definimos o número máximo de teclas que o buffer pode guardar, que no nosso caso é 20. E como colocamos 20 como tamanho máximo, colocamos também 20 zeros na área data. Para o programa parar, aperte Enter.

 

 

Ok...agora vamos ver mais uma coisa bem importante =)

 

 

>>> Os Jumps (Saltos) <<<

Os jumps, como o próprio nome diz, servem para fazer saltos de uma parte do código para outra (esse processo é conhecido como "devio da linha de execução"). Geralmente são condicionais, ou seja, funcionam mais ou menos como se fossem um comando "If", utilizado para checar se certas condições são verdadeiras ou falsas, mas também há o chamado salto incondicional, que não depende de nenhuma condição para ser tomado.

Os mais utilizados:

 

É necessário se cadastrar para acessar o conteúdo.

Bom...para fazer as comparações, precisamos utilizar uma outra instrução, a instrução CMP (derivada de CoMPare). Nada como um exemplo para entendermos melhor a integração do CMP com o JMP.

É necessário se cadastrar para acessar o conteúdo.

 

msg DB 'BELEZA!',13,10,'$' ; A string contém o código 13,10, que faz com que o console passe para a próxima linha

Se você pensar e observar um pouco, você descobre o que o programa faz...Vamos analisar juntos...

Primeiramente o programa escreve a string msg na tela, em seguida adiciona 1 no valor do contador CX e então, compara o valor de CX com 5, caso não seja 5, escreve a string de novo e adiciona mais 1 ao contador CX...E assim vai até que isso tenha sido feito 5 vezes, daí o contador terá valor 5 e o salto não será executado, o programa continuará executando o código normalmente, que no caso, fecha o programa.

 

 

Legal né? Então agora vamos conversar um pouco sobre as Funções =)

 

 

>>> As Funções <<<

No exemplo acima, definimos uma parte do código chamada "Escreve", isso se chama marcador. As funções em Assembly são parecidas com marcadores, porém, têm instrução de retorno e não se utiliza jumps mas, sim, a chamamos no código. Uma função pode exigir parâmetros e é para isso que serve a famosa Pilha e também os Registradores, para passarmos os parâmetros exijidos na função. Funções são comumente usadas em tarefas repetitivas.

Aqui um breve exemplo de como usar este recurso:

 

É necessário se cadastrar para acessar o conteúdo.

 

funcao: ; Começo da função

; aqui colocamos o código que será executado

RETN ; Essa instrução indica o fim de uma função, dizendo ao programa para sair do código da função e retornar ao código principal do programa

Pode até parecer complicado, mas é fácil. Conforme você for praticando, você vai "pegando o jeito" de trabalhar com funções, comparações, saltos...

 

=)

 

Ei!! Está pensando o mesmo que eu?? Podemos melhorar aquele nosso programa que grava as teclas digitadas, utilizando jumps e comparações...

 

Vamos lá...vou colocar o código comentado aqui, analise-o com calma e entenda o que cada instrução faz, não será preciso eu ficar explicando pra que serve cada instrução...você já as conhece...

 

É necessário se cadastrar para acessar o conteúdo.

O código está bem comentado e acho que vocês não terão problemas em interpreta-lo...Vamos ao nosso próximo assunto...

 

 

>>> A Pilha <<<

A pilha é um lugar na memória do processador, que serve para guardar dados. Usamos a instrução PUSH para colocar dados na pilha e POP para retirar. Lembra daquela famosa frase: "Os últimos serão os primeiros" ?

Pois é...essa é a regra quando se usa a Pilha...os dados são retirados na ordem inversa que foram colocados.

Imagine que você tem 4 pratos, um laranja, um azul, um verde e um amarelo.

Você vai fazer uma pilha com esses pratos...então primeiro você coloca o amarelo, depois o verde, depois o azul e em cima de todos, o laranja. Agora você vai retirar de 1 em 1, quando você começar a retirar, o primeiro a ser retirado é o que está em cima, o laranja (o último que foi colocado). Assim funciona a pilha...

Lembra da instrução CALL? Aquela que chama uma função? Espero que sim...

Lembra também que toda função, no seu final, possui a instrução RETN?

Então...um exemplo de uso da pilha é o seguinte: quando você utiliza a função CALL, ela guarda na pilha o endereço de retorno, sendo assim, quando a instrução RETN for atingida, o programa saberá pra qual endereço deve voltar...

 

Como sempre, vamos a um exemplo básico:

 

É necessário se cadastrar para acessar o conteúdo.

Observe que colocamos o valor 456 e, em cima, colocamos o valor 789... na hora que retiramos da pilha, primeiro retiramos o valor 789(ques estava no topo da pilha) e dps tiramos o que estava embaixo, o 456, que havia sido o primeiro a ser colocado.

 

 

Super simples né? xD

Vamos continuar complicando mais as coisas então...só faltam mais 2 assuntos para acabarmos... smile.gif

 

 

>>> Os Segmentos <<<

Bom...como sabemos, os pentes de memória de hoje em dia conseguem armazenar até milhares de megabytes, um número estupendamente maior do que o que é possível com 16 bits...

Em 16 bits, temos 2 bytes e , cada byte é um conjunto de 8 números binários(8 bits), logo, o número máximo que conseguimos com 2 bytes em binário é: 1111 1111 1111 1111, este número é o 65535 em decimal, que corresponde a 64 Kb, muitas vezes inferior ao número de megabytes que as memórias de hoje possuem...

 

A memória tem suas posições, mas desde que as memórias melhoraram e ficaram capazes de armazenar muitos MB, surgiu um problema...como fazer com as posições que ficam acima dos 64 Kb, isto é, o que fazer com as posições acima da posição 65535?

A solução foi dividir a memória em "lotes" (segmentos) de 65536 bytes (de 0 a 65535).

 

Primeiramente os segmentos foram colocados um após o outro: o Segmento 1 começa na posição 0 e vai até a 65535, o Segmento 1 começa em 65536 e vai até a 131071...e assim por diante...

 

Quando quisessemos acessar uma posição, utilizariamos 2 números, um para indicarmos o segmento que iriamos acessar e o outro para indicarmos a posição dentro desse segmento...

Só que houve um segundo problema...ao colocarmos os segmentos um após o outro, haviam programas que quando utilizavam a memória, não utilizavam todo o segmento...então a memória ficava cheia de "buracos" sem dados gravados...

 

Foi aí que surgiu uma nova idéia...colocar os segmenos um em cima do outro, dando um espaço de 16 bits entre o começo de um e o começo do outro...

Então agora o Segmento 0 começa na posição 0 e vai até 65535, O Segmento 1 começa na posição 16 e vai até 65551...

 

O Segmento x começa na posição x*16 e vai até a posição x*16 + 65535 biggrin.gif

 

Pronto...agora você sabe(ou não IUaHSIUAHS) como a memória do seu pc é dividida...não é fantástico? ;P

 

 

Finalmente...chegamos ao último assunto... biggrin.gif

 

 

>>> Deslocamento <<<

O deslocamento, chamado de OffSet é um endereço que muda de acordo com o segmento e serve para indicar um byte dentro das 65536 posições disponíveis (lembre-se que as posições vão de 0 a 65535 e temos de incluir o 0, o que resulta em 65536 posições possíveis).

Mesmo depois da mudança na divisão da memória, ainda usamos dois endereços para definir uma posição na memória...

Vamos a um exemplo de como indicar posições na memória...

 

Endereço 2345:6789 --> Segmento 2345 , Deslocamento 6789

 

Ou seja, é a posição 6789 dentro do segmento 2345

 

O segmento começa na posição 37520 (2345*16) da memória e o nosso deslocamento dentro do segmento é de 6789, ou seja, 6789 posições à frente do começo do segmento. Se o segmento começa em 37520, a posição que queremos (6789 posições à frente) fica no endereço 44309 da memória... xDD

 

Bom...o seu processador, muito esperto, possui registradores especiais para lidar com os segmentos, o principais são: CS(Code Segment) , DS(Data Segment) , ES(Extra Segment)...O CS gerencia aonde está o código do programa, o DS gerencia aonde estão os dados do programa e o ES, como o nome diz, é um adicional.

Também há um registrador para gerenciar o deslocamento...o SI(Segment Index)

Quando queremos acessar um dado do programa, utilizamos a dupla DS:SI, onde DS diz o segmento que está o dado e o SI diz o deslocamento dentro do segmento em questão....

Não há instruções que alterem diretamente esses registradores...se um programador distraído bagunçar esses registradores ou se um programador inexperiente resolver "xeretar" eles e alterar de forma indevida, os resultados serão EXTREMAMENTE DANOSOS...entao é justamente por isso que, caso o programador queira altera-los, terá de fazer de forma indireta, oq eu certamente vai exigir mais atenção e evitar erros acidentais...

 

Vamos ao exemplo de como alterar os valores... (lembre-se: nunca brinque com assembly por conta própria, principalmente quando se trata de operações com memória)

 

É necessário se cadastrar para acessar o conteúdo.

 

FINALMENTE!!! Chegamos ao fim do nosso artigo...

 

 

Gostaria de deixar claro que este artigo é de exclusiva autoria MINHA para o Guia do Hacker, tudo o que está aí saiu da minha cabeça...portanto não tenho créditos a colocar.

Se você for copiar, coloque os créditos... =)

Você vai encontrar outros artigos e referências que seguem a mesma sequencia que este, assim como utiliza exemplos bem parecidos. A razão disso é clara, existe uma sequencia mais didática para se fazer um artigo qualquer...por exemplo, eu não poderia falar sobre a instrução INT antes de lhe falar o que e pra que serve um registrador...quanto aos exemplos...é claro que alguem que nem conheço em algum outro artigo deve ter feito exemplos parecidos...isso é normal...nao tem muito o que variar nesses exemplos básicos... smile.gif

 

 

Bom...acho que depois de ter tido paciência (e muita!) e lido esse artigo, você agora viu que Assembly não é algo de outro mundo...obviamente é uma linguagem difícil, mas não é impossível de se aprender.

Aqui coloquei as coisas básicas de Assembly, o necessário para você começar...a partir de agora a responsabilidade de aprender mais é sua, tente fazer programas com outras funções, para isso use SEMPRE o HelpPC...

Depois que você dominar BEM esses conceitos básicos, passe para uma parte mais avançada da linguagem, com intruções e interrupções mais complicadas e até tente aprender a programar ShellCodes...Mas tenha calma, o segredo de um bom programador é fazer as coisas em passos para alcançar seus objetivos...não se atropele, siga o seu ritmo e chegue aonde você quer!

 

 

 

Espero que gostem do meu artigo, deu um trabalho legal para escrever ele, mas espero que seja de grande utilidade para vocês. biggrin.gif

 

 

 

 

 

 

 

 

Lembrando que eu não criei exatamente nada desse Guia somente trouxe para a wc , espero que gostem dele :]

Abraços!

Link para o comentário
Compartilhar em outros sites

Mui Bueno Noobeta / Deve ta errado ;S

Dei uma pequena lida bem rápida e achei bem interessante, vai ser bom ter conteúdo de ASM aqui no fórum.

Depois quando a preguiça sair desse corpo que não pertence a ela eu leio tudo =)

Obrigado por compartilhar.

 

Abraços!

Link para o comentário
Compartilhar em outros sites

Não perca tempo aprendendo Assembly 16bits a não ser que queira programar microchips ou a programar para o DOS, porque esse tutorial ensina a programar para o DOS que é totalmente diferente do windows.

 

1º Porque usa 16bits e não 32 como no Windows.

2º DOS usa estilo de Memória Real o Windows usa Memória Protegida (memória real você pode acessar qualquer parte da memória a qualquer hora de 0 a FFFFh, você pode acessar a memoria de outros programas a qualquer hora só mudar o CS consequência CRASH direto se não souber o que está fazendo, já a memória protegida cada programa tem o seu próprio espaço na memória, e para acessa-la só com APIs especificas em 32bits os endereços vão de 0 a FFFFFFFFh)

 

A unica coisa que você pode tirar desse tutorial são as instruções tipo MOV, ADD, INC etc os registradores em 32bits é só você adicionar o E na frente ex: AX(16bits) fica EAX(32bits)

Link para o comentário
Compartilhar em outros sites

Adorei a criação de uma área só para assembly pôs agora vejo guias e tutos... Vai ajudar bastante gente iniciante ( Eu por exemplo)... Quando os caras ficavam falando de assembly eu boiava tanto que nem comentava os topics...

@ Topic: Gostei dele... É muito grande então depois lerei tudo com calma... bem formatado, os devidos créditos colocados e tudo mais... tá show

Link para o comentário
Compartilhar em outros sites

  • 1 mês depois...

Muito bom o tutorial, organizado,

ira ajudar muitos membros novos nesta area, alem da linguagem assembly ser simples e facil de aprender

obrigado por compartilha. abraços1

Link para o comentário
Compartilhar em outros sites

Este tópico está impedido de receber novos posts.
 Compartilhar

×
×
  • Criar Novo...

Informação Importante

Nós fazemos uso de cookies no seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies , caso contrário, vamos supor que você está bem para continuar.