Pular para o conteúdo principal

Introdução ao Assembly


Faz um bom tempo que não posto nada aqui. Bem, estou de volta. Tenho estudado Assembly e C com foco em (in)segurança.

Vamos começar com um programa simples em C e depois o escreveremos em Assembly. segue:

alacerda@labnix86:~/code/c$ cat hw.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
   char msg[] = "Programa em C\n";
   write(1,msg,sizeof(msg));
   exit(3);
}
alacerda@labnix86:~/code/c$ gcc hw.c -o hw
alacerda@labnix86:~/code/c$ ./hw
Programa em C

alacerda@labnix86:~/code/c$ echo $?
3
alacerda@labnix86:~/code/c$

O programa acima apenas exibe uma string na tela e sai com o código de retorno 3. Se queremos fazer o mesmo programa em Assembly vamos precisar:
  1. Definir uma string
  2. Escrever a String na tela
  3. Sair com o código 3
Vejamos o resultado e logo abaixo explicarei como chegamos a ele:

alacerda@labnix86:~/code/asm$ cat hw.s
.section .data
   msg: .string "Programa em Assembly\n"
   tam: .long . - msg

.globl _start

_start:
   mov $4,%eax
   mov $1,%ebx
   lea msg,%ecx
   mov tam,%edx
   int $0x80

   mov $1,%eax
   mov $3,%ebx
   int $0x80
alacerda@labnix86:~/code/asm$ as hw.s -o hw.o
alacerda@labnix86:~/code/asm$ ld hw.o -o hw
alacerda@labnix86:~/code/asm$ ./hw
Programa em Assembly
alacerda@labnix86:~/code/asm$ echo $?
3
alacerda@labnix86:~/code/asm$


Teste os dois programas acima e depois de ter sucesso na execução, vamos às explicações da parte em Assembly:

.section .data
Aqui podemos definir as variáveis que queremos usar. Então podemos resolver o ponto 1 citado acima: Definir uma string. Definimos uma variável chamada "msg" contendo a string que queremos exibir na tela. A segunda instrução dentro de .data é a criação de uma variável contendo o tamanho de nossa string (precisaremos dela na instrução de escrever na tela).

.globl _start
Aqui informamos qual a parte principal do programa, onde deve ser iniciada a execução do mesmo. E finalmente...

_start:
Aqui iniciamos o programa. Entenda que as funções em C têm seus equivalentes em Assembly. Em C usamos a função write() para escrever a string na tela e usamos a mesma em Assembly. O registrados %eax guarda a função que queremos executar e o número 4 que estamos passando par ao registrador eax significa exatamente a função write().


-- LEIA COM BASTANTE ATENÇÃO O QUE SE SEGUE!

Quais parâmetros precisamos passar para a função write? man 2 write nos informa:
         
 write(int fd, const void *buf, size_t count);
fd -> Onde escrever
   Com a instrução a seguir informamos onde escrever:
         mov $1,%ebx
   O número 1 significa saída padrão (monitor).
buf -> O que escrever
   Com a instrução a seguir informamos onde está o que escrever (a nossa string).
         lea msg, %ecx
   A instrução lea coloca o endereço da nossa string no local correto da função write().
cont -> Quantos bytes escrever
   Com a instrução a seguir informamos quantos bytes escrever no monitor.
         mov tam,%edx
   graças ao que fizemos em .data, essa variável contém exatamente a quantidade de bytes da nossa string. Assim toda ela será impressa na tela.

Finalmente chamamos a interrupção para que o sistema operacional execute toda a função que acabamos de organizar. Isso é feito com a instrução:
         int $0x80

-- Espero que tenha entendido até essa parte. Se não, releia esse bloco antes de prosseguir.


Ah! então você entendeu? Que bom. Agora podemos ver o último bloco de instruções de nosso programa:

     mov $1,%eax
     mov $3,%ebx
     int $0x80

Desta vez estamos movendo o número 1 para o registrador %eax... Para que serve mesmo o %eax? Lembra? 
   R. Para guarda a função que queremos executar

O número 1 representa a função exit(). Agora só nos resta saber qual parâmetro passar para essa função. Se olha a manpage verá que é apenas o código de retorno. Na linha 2 informamos que o código de retorno é 3. Daí finalmente podemos chamar a o sistema operacional mais uma vez para executar a função que acabamos de organizar.

Quando percebemos que em Assembly precisamos apenas popular as funções da mesma maneira que fazemos em C, a coisa fica mais fácil...

É isso ai,
Até mais!

Comentários

Postagens mais visitadas deste blog

[VMWare ESXi 6] - Suporte à placa de rede Realtek 8139

Essa placa não é suportada nativamente pelo ESXi. Para usar uma dessas placas precisei seguir os assoa abaixo:

Envie para o datastore o seguinte arquivo: https://www.dropbox.com/s/840jcwj93yed1wr/rtl8139.vib?dl=0

Execute essa sequência de comandos via SSH:

esxcli software acceptance set --level=CommunitySupported
esxcli software vib install -v /vmfs/volumes/datastore1/isos/rtl8139.vib

Reinicie o sistema e a placa deverá ser reconhecida.

:wq!

CentOS 7 + OMD (Open Monitoring Distribution )

yum install wget -y
wget https://labs.consol.de/repo/stable/rhel7/x86_64/labs-consol-stable-1.3-1.rhel7.noarch.rpm
yum localinstall labs-consol-stable-1.3-1.rhel7.noarch.rpm -y
yum install omd -y
Após a instalação ser concluída, crie e inicie a nova instância do OMD:

omd create nome_do_siteomd start nome_do_site
Para visualizar e alter algumas configurações :

omd config nome_do_site
== OBS
O firewall do CentOS não permite conexões às porta 5000 por padrão (A porta 5000 é a default para o primeiro site OMD). Uma solução rápida (apenas em laboratório):

iptables -F
== Acesse o servidor:
http://ip_do_servidor:5000/nome_do_site
Usuário: omdadmin
Senha: omd

== Main informações
Mais informações em: http://omdistro.org/

OpenVPN no CentOS

Oba oba!!! \0/
Estou de volta para guardar mais uma informação útil! A instalação do OpenVPN no CentOS. Vou mostrar aqui de maneira bem direta a instalação e configuração que já realizei em diversos ambientes.

STARTING...


1. Instale o repositório RPMForge:
wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.1-1.el5.rf.i386.rpm rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt rpm -K rpmforge-release-0.5.1-1.el5.rf.*.rpm rpm -i rpmforge-release-0.5.1-1.el5.rf.*.rpm

2. Verifique se o RPMForge aparece na lista de repositórios:
yum check-update
3. Instale o OpenVPN yum install openvpn -y
4. Iniciando a configuração: cp -pra /usr/share/openvpn/2.0/easy-rsa /etc/openvpn cd /etc/openvpn/easy-rsa . ./vars ./clean-all ./build-ca

5. Criando a chave para o servidor:
./build-key-server server

6. Criando a chave para o cliente:
./build-key cliente

7. Gerando um Diff Hellman (DH) no servidor:
./build-dh
dentro do diretório /etc/openvpn/ encontra-se um arquivo chamado server.conf (se não exist…