Uma pequena introdução ao Assembly para Linux

Paper publicado no zine Cogumelo Binário ( http://cogubin.leet.la/ ), sobre programação Assembly na sintaxe AT&T para Linux.

[ Hits: 36.885 ]

Por: Luiz Vieira em 19/12/2011 | Blog: http://hackproofing.blogspot.com/


Os registradores



Temos os registradores de uso geral e os registradores especiais, cada qual com suas funções e características bem definidas. Devemos lembrar também, que dependendo da geração e tecnologia empregada na fabricação daquele processador, isso influenciará diretamente na capacidade de armazenamento de dados pelo registrador bem como em seu nome.

Por exemplo, o registrador BP, na arquitetura de 16 bits, possui a mesma função que o EBP, de 32 bits, e o RBP, de 64 bits. Entretanto, sua capacidade de armazenamento muda de arquitetura para arquitetura.

Mas antes de falarmos de registradores, precisamos entender como funciona a CPU. A unidade central de processamento de um computador possui os seguintes elementos que permitem que o mesmo pegue dados da memória e processe-os:
  • Contador;
  • Decodificador de Instrução;
  • Barramento de dados;
  • Registradores de uso geral;
  • Unidade lógica e aritmética.

O contador é utilizado para dizer ao computador onde está localizada a próxima instrução a ser executada. Ao localizar tal instrução, através do endereço de memória armazenado no contador, tal função é transferida ao decodificador, que buscará entender o que a mesma significa. Isto inclui qual o tipo de processo será necessário (adição, subtração e etc) e em qual local da memória os dados necessários se encontram.

Após essas operações básicas, o barramento de dados (Data Bus) é utilizado para fazer a conexão entre a CPU e a memória. Além da memória externa ao processador, esse último tem alguns locais na memória chamado de registradores, como citado anteriormente.

Os registradores de uso geral são onde as principais ações ocorrem. Operações como adição, subtração, multiplicação, comparações lógicas e outras, utilizam os registradores de uso geral para o processamento dos dados.

Já os registradores especiais, que são a segunda categoria de registradores existentes, possuem propósitos bem específicos, que serão abordados mais a frente.

Após a CPU recuperar todos os dados necessários, ela os transfere, bem como as instruções decodificadas, para a unidade lógica e aritmética para o posterior processamento. É aqui que a instrução é executada.

Obviamente que essa é uma explicação bem simplória, mas já serve para compreendermos o funcionamento básico de uma CPU.

Para conhecermos os registradores, vamos separá-los pelas duas categorias citadas: uso geral e especiais. Alguns dos registradores de uso geral, onde podemos armazenar valores para serem utilizados em operações, são os seguinte:
  • EAX = Extended Acumullator (registrador acumulador extendido)
  • EBX = Extended Base (registrador de base extendido)
  • ECX = Extended Couter (registrador contador extendido)
  • EDX = Extended Data (registrador de dados extendido)
  • ESI = Extended Source Index (registrador de índice de origem extendido)
  • EDI = Extended Destination Index (registrador de índice de destino extendido)

Como havia comentado antes, os registradores de 16 bits possuíam nomes um pouco diferentes dos de 32 bits, por conta de sua capacidade de armazenamento. Por exemplo, o registrador EDX possui esse nome porque faz parte de uma CPU de arquitetura de 32bits de dados, quanto que se fossem apenas 16bits seu nome seria DX.

Um gráfico tosco para entender isso seria mais ou menos assim:

---------------------------------------------------------------------------------
|                EDX               |
---------------------------------------------------------------------------------
|               |          DX      |
---------------------------------------------------------------------------------
|               |    DH        |      DL   |
---------------------------------------------------------------------------------

  • EDX armazenaria, por exemplo, um valor fictício de 0x00000000.
  • DX, que é a parte alta de EDX, armazenaria 0x0000.
  • DH, é a parte alta de DX, enquanto DL é a parte baixa de DX (ambos são de arquitetura 8bits), e armazenam apenas 0x00 cada um.

Em adição aos registradores de uso geral, temos os registradores especiais, que são:
  • EBP = Extended Base Pointer (Ponteiro de Base)
  • ESP = Extended Stack Pointer (Ponteiro de Stack/Pilha)
  • EIP = Extended Instruction Pointer (Ponteiro de Instrução)
  • EFLAGS =

Uma coisa que precisamos ter sempre em mente, é que tanto como o EIP quanto o EFLAGS, só poderão ser acessados através de instruções especiais e bem específicas, diferente dos demais registradores.

O EBP sempre aponta para a base da pilha, e também é utilizado para acessar essa mesma pilha, apesar de também poder ser utilizado como um registrador comum (de uso geral). Já o ESP, aponta para a posição atual da stack (pilha) e é o 'offset' do SS (Stack Segment).

Agora, por que precisamos conhecer os registradores para aprender Assembly? Simplesmente porque todas as instruções desta linguagem, lida diretamente com tais registradores, assim como todos os programas.

A diferença, é que nas demais linguagens, não precisamos conhecer dessa estrutura de baixo nível. No entanto, todas elas após serem compiladas, ou interpretadas pela CPU, suas instruções vão trabalhar diretamente com essa estrutura de funcionamento.
Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Os registradores
   3. Primeiro programa
   4. Explicação e Segundo Programa
   5. Mais dois programas e conclusão
Outros artigos deste autor

Shellter Project - Ferramenta para bypass de AV

SELinux - Security Enhanced Linux

Rainbow Crack e Rainbow Tables

Distribuição CAINE Linux para forense digital: em Live-CD, pendrive, máquina virtual ou direto em seu Ubuntu 10.04

Armitage: a nova interface gráfica do Metasploit

Leitura recomendada

Wake-on-LAN (WOL) utilizando Netcat - Dissecando o protocolo

Colocando ícones e wallpapers no IceWM usando o DFM (desktop file manager)

IBQUOTA - Gerenciador de Impressão por Usuário

Instalação do Wonderland Server

Criando mirror do AVG 7.5 free

  
Comentários
[1] Comentário enviado por JJSantos em 19/12/2011 - 22:12h

Muito bom, mesmo....

[2] Comentário enviado por dimasdaros em 20/12/2011 - 16:35h

Ossa, eu aprendi assembly para PIC há uns 5 anos atrás, quando cursei um técnico em Eletrônica, não me lembro de quase nada, mas era meio diferente ainda hehe

Ótimo artigo.
Uma pergunta, não tive como ler o artigo ao todo, pois estou em horário de trabalho, mas existe alguma linguaguem de programação de baixo nível para web? Que os navegadores podem interpretar? Fiquei com essa dúvida agora, que estou estudando web.

Mas de qualquer forma excelente conteúdo, como todos os que você posta.
Parabéns

Abraço
dimasdaros.

[3] Comentário enviado por sacioz em 21/12/2011 - 13:25h

Sempre acompanho os artigos desse Senhor com interesse , éle é de dar medo de tanto que sabe.

[4] Comentário enviado por Lisandro em 22/12/2011 - 07:57h

Excelente artigo. Meus parabéns!

[5] Comentário enviado por firebits em 22/12/2011 - 14:47h

Faaaaaaala, Luiz. Brother, você usou o NASM para compilar os fontes dos programas?

[6] Comentário enviado por taiar em 22/12/2011 - 14:55h

Estranho é dizer algo como "Assembly para Linux" sendo que uma linguagem de montagem é algo utilizado para se controlar processadores e não sistemas.

Qual a plataforma desse código Assembly? Intel 8086? Sparc?????? Sem saber isso, esse artigo não tem nada haver...

[7] Comentário enviado por renan16 em 22/12/2011 - 15:28h

Muito bom

[8] Comentário enviado por 9u31220 em 24/12/2011 - 14:20h

Parabéns Luiz Vieira, o artigo está bom.

Na página 4 no comando de linkedição do programa leia foi usado #lf... ao invés de #ld...

Eu testei os programas aqui e o último não funcionou, ele não cria nenhum arquivo arquivo.txt.

Você poderia citar as fontes no final, posso estar enganado mas acho que tudo o que foi dito sobre a sintaxe AT&T, o ciclo de execução de instrução do processador e os registradores pode ser encontrado em http://download.savannah.gnu.org/releases/pgubook/

[9] Comentário enviado por luizvieira em 28/12/2011 - 18:50h

Valeu pessoal!

Rafael, além do Programming From the Ground Up, que inclusive indiquei em minha palestra sobre Exploits no Hack'n Rio, utilizei o livro abaixo como fonte:

The Art of Assembly Language - http://www.amazon.com/Art-Assembly-Language-Randall-Hyde/dp/1886411972/ref=cm_lmf_tit_9

E com relação a sintaxe AT&T e o ciclo de execução, confesso que sempre tenho em mente as explicações do livro citado (Programming From the Ground Up), mas o conteúdo não foi retirado ipsis literis do referido livro, posto que não há muito o que acrescentar nessas informações. Logo, o conteúdo deve estar bem parecido :-)

Sobre o comando, ld, valeu pela correção, devo ter deixado o dedo escorregar hehehe, mas percebi que o erro consta apenas na linkedição do segundo código.

Quanto ao último programa, darei uma olhada no que pode ser... O mesmo foi testado em um Ubuntu 11.10, com proc. Core i7 e funcionou bem. Inclusive acabei de testar e verifiquei que o funcionamento está ok.

[ ]'s

[10] Comentário enviado por luizvieira em 28/12/2011 - 18:59h

firebits, meu brother, utilizei o GNU Assembler, que é o padrão do Linux.

taiar, realmente o artigo não deve ter nada "haver" :-)

Mas para informar, a arquitetura é x86, como explicado na resposta acima dado ao 9u31220. E com relação ao título de Assembly para Linux, é apenas para frisar que o foco é a sintaxe AT&T, já que deve ter ficado bem claro no artigo que há duas sintaxes: Intel (Windows) e AT&T (Unix like).

[ ]'s

[11] Comentário enviado por 9u31220 em 28/12/2011 - 21:44h

@liuzvieira

vlw pelas fontes

Deculpe a minha preguiça em não depurar o que aconteceu que o último programa não funcionou aqui, eu estou usando um crunch bang 10 com proc intel atom.
O arquivo arquivo.txt foi aberto com modo de arquivo "O_RDWR" que é uma string (não deveria ser um número?). Bastou substituir a linha 37:

movl $perm, %ecx # modo do arquivo
por
movl $03101, %ecx

que funcionou.

[ ]'s


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts