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.837 ]

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


Primeiro programa



Caminhando em direção à linguagem propriamente dita, precisamos saber que existem duas principais sintaxes de Assembly, que são diferentes uma da outra. A Intel, utilizada principalmente em sistemas Windows, e a AT&T, utilizada em sistemas GNU/Linux.

E há diferenças bem importantes entre estas sintaxes. Diz-se que dificilmente alguém aprende a sintaxe AT&T primeiro, pois ela pode ser um pouco confusa para iniciantes. Mas depois que se aprende, torna-se uma poderosa ferramenta. Eu, pelo menos, sou adepto da sintaxe AT&T e é essa que vamos abordar neste artigo.

Por exemplo, na sintaxe Intel, uma instrução comum ficaria assim:

instrução destino, origem

Em AT&T é:

instrução origem, destino

Na sintaxe AT∓T, quando desejamos realizar algum tipo de endereçamento de memória, precisamos seguir a seguinte sintaxe de comando:

segmento:offset(base, indexador, escala)

Na Intel, um endereçamento ficaria assim:

[es:eax+ebx*4+100]

Já na AT∓T, a mesma linha ficaria assim:

%es:100(%eax, %ebx, 2)

Uma questão importante de se lembrar, é que na sintaxe AT∓T, todos os registradores devem ser prefixados pelo símbolo %, enquanto que o valores literais, pelo símbolo $. Portanto, 100 é diferente de $100, onde o primeiro é um endereço de memória, e o segundo é um valor numeral.

Outro símbolo importante, é o '$0x' utilizado para referenciar hexadecimais.

Vamos deixar a teoria um pouco de lado e vamos ao nosso primeiro programa. Ele fará pouca coisa por enquanto, apenas executará um 'exit', utilizando uma 'syscall' específica do sistema operacional GNU/Linux. Vejamos o código, que pode ser digitado utilizando o Vim/Vi, Nano, Emacs ou seja lá o que preferir:

 #OBJETIVO: Programa simples que executa um exit e retorna um código de status para o kernel Linux 
 #
 #ENTRADA: nenhuma
 #
 #OUTPUT: retorna um status código de status, que pode ser visto executando no terminal o comando:
 # 
 # echo $?
 #
 # após a execução do programa
 #
 #VARIÁVEIS:
 # %eax armazena o número da syscall
 # %ebx armazena o status retornado
 #

 .section .data

 .section .text

 .globl _start

 _start:

 movl $1, %eax       # esta é a syscall do kernel Linux para sair de um programa 
 movl $0, %ebx       # este é o status que retornaremos para o SO.
         # altere esse valor, e verá coisas diferentes ao executar o 
         # echo $?
 int $0x80       # isso chama o kernel para executar a syscall 1


Salve este código como 'exemplo1.s', compile e linkedite-o:

# as exemplo1.s -o exemplo1.o
# ld exemplo1.o -o exemplo1


Após este processo, para executar nosso primeiro programa, basta digitar no terminal:

# ./exemplo1

Executando o programa, você perceberá que a única coisa diferente que ocorrerá, é que seu cursor irá para a próxima linha. Isto ocorre porque nosso programa foi feito apenas para executar um 'exit'.

Para visualizarmos o código de status retornado para o SO, basta digitarmos no terminal:

# echo $?

Se tudo correr bem, você terá um "0" como saída. Este é o código de status necessário a ser passado para o kernel, avisando de que tudo está ok para sair do programa.
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

ARP Poisoning: compreenda os princípios e defenda-se

Resenha do livro: Praticando a Segurança da Informação

SELinux - Security Enhanced Linux

PNL para Hacking

Bypass de firewall com tunelamento por DNS

Leitura recomendada

MenuetOS - O extraordinário mini-sistema operacional

Configurando o Stardict com dicionário do Babylon

Servidor de rede (PDC - Proxy Transparente - DNS)

Usando OpenBSD como desktop

Multiboot pelo pendrive usando grub2: instalando várias distros a partir de uma unidade de armazenamento móvel

  
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