📖
Introducao à segurança digital
  • Introdução à Segurança Digital
  • Introdução a Linux
  • Criptografia
    • Introdução
    • Definições e Objetivos
    • Criptografia Clássica
    • Criptografia Moderna
    • Guia de Python para criptografia
  • Redes
    • Ataques
      • Arp Cache Poisoning
      • DNS Cache Poisoning
      • Slow Loris
      • Syn Flood
      • WPA Cracking
      • Deauth
    • Ferramentas
      • Resumo das Ferramentas
      • Suíte Aircrack
      • Wireshark
      • Netcat
      • Nmap
      • Netstat
      • Kathará
    • Pacote & Protocolo
    • Camada de Rede
    • Camada de Transporte
    • IANA
    • Three-way Handshake
    • DHCP
    • DNS
    • NAT
    • Pentest
      • FTP
      • SMB
      • SSH
      • VPN
    • Avançado
  • Web
    • Semana 1
      • Introdução à Web
      • Entendendo as URLs
      • Introdução ao HTML e ao CSS
      • Directory Traversal
      • Introdução ao Javascript
      • Cross Site Scripting (XSS)
      • Cookies e sessões
      • Protocolo HTTP
      • Protocolo HTTPS
      • 2020 - XML External Entities (XML) Injection
    • Semana 2
      • Servidores Web
      • PHP (Programação server-side)
      • Command Injection
      • Cookie Poisoning
      • Bancos de Dados
      • SQL Injection
      • Insecure Direct Object Reference (IDOR)
      • 2020 - Portas e Serviços
      • 2020 - API's e Serviços Rest
  • CTF
  • Engenharia Reversa
    • Arquivos
    • Registradores e tipos de dados
    • Hello World em x86
    • Pilha
    • GDB
    • Ghidra
  • Pwning
    • Integer Overflow
    • Buffer Overflow
    • Pwntools
    • Shellcode
    • Proteções
  • Hardware
    • Introdução ao Hardware Hacking
    • Introdução ao Infravermelho
Powered by GitBook
On this page
  • Entendendo o código
  • Compilando e testando o código
  • Referências

Was this helpful?

  1. Engenharia Reversa

Hello World em x86

Explicação de um Hello World em Assembly x86

Usando códigos como exemplo, é recomendável antes de mais nada entender conceitos básicos do Assembly x86, como a instrução mov.

Usando por exemplo esse programa:

;; Programa Hello World
section .text
global _start

_start:
        mov     edx,len                             ;comprimento da mensagem
        mov     ecx,msg                             ;mensagem a ser escrita
        mov     ebx,1                               ;descritor de arquivo (stdout)
        mov     eax,4                               ;número da system call
; (sys_write)
        int     0x80                                ;call kernel

        mov     eax,1                               ;numero da syscall
; (sys_exit)
        int     0x80                                ;call kernel

section     .data
        msg     db  'Hello, world!',0xa                 ;nossa string lindona
        len     equ $ - msg                             ;comprimento da lindona

Entendendo o código

Inicia com um comentário, marcado a partir de um ; como você pode ver.

É necessário especificar seções do código. Uma vez que o Assembly vai ser carregado diretamente na memória, você precisa especificar o que é o fragmento text (instruções) e o que é o fragmento data (código não executável, usado para guardar strings e algumas variáveis, etc.). Como vocẽ pode ver, define-se um rótulo (label na forma culta) global _start. Isso é necessário para ser possível definir o ponto de entrada do código (É um rótulo padrão).

Vamos olhar agora a seção .data. Primeiramente ela declara um "define byte" (db) que nós chamamos de msg, com a string que queremos imprimir, juntamente com 0xa, que é o caractere de nova linha, (equivalente ao \n no C, por exemplo). Na próxima linha, definimos uma variável len que representa o comprimento da string, isto é, o endereço atual da memória onde está a instrução (representado por $) subtraído do começo da string (msg).

No final, o registrador eax terá o valor 1, significando a syscall "exit". Então será chamado através de int 0x80, saindo do programa.

No caso de nós quisermos colocar um return 0 no final do código, nós poderíamos colocar apenas mov ebx, 0 logo antes da syscall.

Compilando e testando o código

Supondo que temos um código hello.asm, podemos montá-lo com

nasm -f elf hello.asm

Fazendo isso nós especificamos que o formato do arquivo será um elf (32bits) e um novo objeto hello.o será produzido.

Ainda assim, esse não é nosso arquivo executável. Para fazer um ainda precisamos utilizar o comando ld (link-editor) para ligar o objeto com as bilbiotecas do sistema, o que pode ser feito facilmente:

ld -s -o hello hello.o -m elf_i386

Isso simplesmente liga o objeto gerado para um executável hello, que tem o formato elf_i386. No caso de qualquer erro acontecer, verifique se você tem 32bits glibc no seu sistema operacional.

Então, execute-o simplesmente usando

./hello

E é isso, temos nosso Hello World! OwO

Referências

PreviousRegistradores e tipos de dadosNextPilha

Last updated 5 years ago

Was this helpful?

Voltando agora para o rótulo _start (também chamado de função nesse caso), nas primeiras 4 linhas nós acabamos de armazenar as variáveis nos registradores edx e ecx, depois nós colocamos o valor 1 em ebx e 4 em eax. Isso significa que, uma vez que queremos escrever alguma coisa na stdout (ou saída padrão), nós usamos a syscall write, que pede o argumento fd (descritor de arquivo) passado no registrador ebx como uma convenção, como visto em . Então a interrupção 0x80 será chamada (isso é uma syscall), que irá imprimir "Hello, world!" no terminal.

Para montar códigos Assembly x86, uma boa maneira é usar o montador .

System Calls Reference
nasm
Linux System Calls Reference
x86 Hello World
nasm