OficinaAssembly para Linux      Por Luiz Vieira      @HackProofing
Quem sou eu?
Organização do Sistema                  CPURegistradores                 Execução       Controle    Flags        I/O     B...
Registradores• Uso geral:  – EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP• Segmento:  – CS, DS, ES, SS, FS, GS• Instrução:  – EI...
Registradores• EAX = Extended Acumullator (registrador acumulador extendido)• EBX = Extended Base (registrador de base ext...
Registradores• Uma coisa que precisamos ter sempre em mente, é que  tanto como o EIP quanto o EFLAGS, só poderão ser  aces...
Organização de um registrador        para uso geral                                    EAX31                              ...
AT&T x Intel• Intel =• AT&T =
AT&T x Intel• Na sintaxe Intel, uma instrução comum ficaria assim:    – instrução destino, origem• Em AT&T é:    – instruç...
Primeiro programa#OBJETIVO: Programa simples que executa um exit e retorna um código de status para o kernel Linux#ENTRADA...
Execução• Salve este código como exemplo1.s, compile e  linkedite-o:  # as exemplo1.s -o exemplo1.o  # ld exemplo1.o -o ex...
Explicação•   .section .data = cria a seção "data", onde listamos quaisquer containers de memória.•   .section .text = seç...
Segundo programa.dataHelloWorldString:    .ascii "Hello Worldn".text.globl _start_start:    movl $4, %eax                 ...
Passagem de syscalls e           argumentos• De que maneira podemos passar os  valores de syscall e seus argumentos?  – EA...
Execução• Salve este código como exemplo2.s, compile e  linkedite-o:  # as exemplo2.s -o exemplo2.o  # ld exemplo2.o -o ex...
Tipos de dados• Espaço reservado em tempo de compilação (em .data):   –   .byte = 1 byte   –   .ascii = string   –   .asci...
Terceiro programa.data    HelloWorld:           .ascii "Hello World!"    ByteLocation:           .byte 10    Int32:       ...
Execução• Salve este código como exemplo3.s, compile e  linkedite-o:  # as –gstabs exemplo3.s -o exemplo3.o  # ld exemplo3...
Execução•   (gdb) list•   (gdb) break *_start+1•   (gdb) run•   (gdb) info variables•   (gdb) help x•   (gdb) x/12cb [ende...
MOVx• É uma das instruções mais utilizadas em Assembly• Sua utilização é basicamente a seguinte:   – movx origem, destino ...
Movendo dados• Entre registradores:  movl %eax, %ebx• Entre registradores e memória:     local:           .int 10     movl...
Movendo dados• Valor direto no registrador:     movl $10, %ebx• Valor direto na memória:     local:          .byte 0     m...
Movendo dados• Em um endereço indexado da memória:    IntegerArray:          .int 10, 20, 30, 40, 50• Para selecionar o 3º...
Quarto programa.section .datastring: .string "Digite algo:n"tam: .long . - string.section .text.globl _start_start:movl $4...
Execução• Salve como leia.s.• Compile, linkedite e execute: # as leia.s -o leia.o # lf leia.o -o leia # ./leia
Quinto programa.section .datastring1: .string "Criar um arquivo e inserir conteúdo n"tam1: .long . - string1string2: .stri...
Quinto programamovl %eax, %esi      # Move o retorno da funcao open para ESImovl $4, %eax        #   syscall write, para e...
Execução• Salve como ‘escreva.s.• Compile, linkedite e execute: # as escreva.s -o escreva.o # lf escreva.o -o escreva # ./...
Comparação – Sexto programa.section .datadata_items: .long 3,67,34,222,45,75,54,34,44,33,22,11,66,0.section .text.globl _s...
Execução• Salve como ‘maximo.s.• Compile, linkedite e execute: # as maximo.s -o maximo.o # lf maximo.o -o maximo # ./maxim...
Condicionais•   je     – Pula (Jump) se os valores são iguais•   jg     – Pula se o segundo valor for maior que o primeiro...
Contatos         Luiz Vieirahttp://hackproofing.blogspot.com       http://www.oys.com.br         luizwt@gmail.com      lui...
Cool 3   assembly para linux
Cool 3   assembly para linux
Próximos SlideShares
Carregando em…5
×

Cool 3 assembly para linux

4.312 visualizações

Publicada em

Presented in BSIDES Conf COOL in Garoa Hacker Clube

Publicada em: Tecnologia
1 comentário
3 gostaram
Estatísticas
Notas
Sem downloads
Visualizações
Visualizações totais
4.312
No SlideShare
0
A partir de incorporações
0
Número de incorporações
2.911
Ações
Compartilhamentos
0
Downloads
70
Comentários
1
Gostaram
3
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Cool 3 assembly para linux

  1. 1. OficinaAssembly para Linux Por Luiz Vieira @HackProofing
  2. 2. Quem sou eu?
  3. 3. Organização do Sistema CPURegistradores Execução Controle Flags I/O Barramentos Memória
  4. 4. Registradores• Uso geral: – EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP• Segmento: – CS, DS, ES, SS, FS, GS• Instrução: – EIP• Controle: – CR0, CR1, CR2, CR3, CR4
  5. 5. Registradores• 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)• 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
  6. 6. Registradores• 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).
  7. 7. Organização de um registrador para uso geral EAX31 0 AX31 16 15 0 AH AL 15 8 7 0 •EAX armazenaria, por exemplo, um valor fictício de 0x00000000. •AX, que é a parte alta de EAX, armazenaria 0x0000. •AH, é a parte alta de AX, enquanto AL é a parte baixa de AX (ambos são de arquitetura 8bits), e armazenam apenas 0x00 cada um.
  8. 8. AT&T x Intel• Intel =• AT&T =
  9. 9. AT&T x Intel• Na sintaxe Intel, uma instrução comum ficaria assim: – instrução destino, origem• Em AT&T é: – instrução origem, destino• 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.
  10. 10. Primeiro programa#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 programamovl $0, %ebx # este é o status que retornaremos para o SO. # altere esse valor, e verá coisas diferentes ao executar # echo $?int $0x80 # isso chama o kernel para executar a syscall 1
  11. 11. Execução• 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
  12. 12. Explicação• .section .data = cria a seção "data", onde listamos quaisquer containers de memória.• .section .text = seção onde inserimos as instruções a serem executadas.• .globl _start = .globl é uma instrução que diz que o símbolo _start não deve ser descartado após a compilação e linkedição do código.• _start: = é onde definimos o valor do label _start, que terá vinculado à si, o conjunto de instruções que seguem logo abaixo.• movl $1, %eax = aqui temos a instrução movl, seguido de dois operadores. Nesse caso, inserimos o valor 1 no registrador EAX. Esse número é o valor de uma syscall específica (exit - para conhecer os valores das demais syscall, execute o comando "cat /usr/include/asm- i386/unistd.h" no terminal Linux*).• movl $0, %ebx = inserimos o valor "0" no registrador EBX. Isso é o que dirá para o kernel que está tudo ok para o exit ser executado.• int $0x80 = int é o mesmo que interrupt. Uma interrupção corta o fluxo de funcionamento de um programa e passa o comando para o Linux, o que em nosso caso, fará com que o kernel execute a syscall 1 (exit). E o valor $0x80 é o número de interrupção utilizado para que essa passagem de controle para o Linux aconteça. * No Ubuntu, o arquivo está em: /usr/include/asm/unistd.h
  13. 13. Segundo programa.dataHelloWorldString: .ascii "Hello Worldn".text.globl _start_start: movl $4, %eax # syscall write()* movl $1, %ebx # parâmetro da syscall para definir STDOUT (fd) movl $HelloWorldString, %ecx # local da mem. onde se encontra o container com a string (Buf) movl $12, %edx # tamanho da string (count) int $0x80 movl $1, %eax # syscall exit() movl $0, %ebx int $0x80 * Syscall write() = ssize_t write(int fd, const void *Buf, size_t count);
  14. 14. Passagem de syscalls e argumentos• De que maneira podemos passar os valores de syscall e seus argumentos? – EAX – número da system call – EBX – primeiro argumento – ECX – segundo argumento – EDX – terceiro argumento – ESI – quarto argumento – EDI – quinto argumento
  15. 15. Execução• Salve este código como exemplo2.s, compile e linkedite-o: # as exemplo2.s -o exemplo2.o # ld exemplo2.o -o exemplo2 Após este processo, para executar nosso primeiro programa, basta digitar no terminal: # ./exemplo2
  16. 16. Tipos de dados• Espaço reservado em tempo de compilação (em .data): – .byte = 1 byte – .ascii = string – .asciz = string terminada em null – .int = integer de 32 bits – .short = integer de 16 bits – .float = número single com ponto flutuante – .double = número double com ponto flutuante• Espaço criado em tempo de execução (em .bss): – .comm = declara área comum da memória – .lcomm = declara área local comum da memória
  17. 17. Terceiro programa.data HelloWorld: .ascii "Hello World!" ByteLocation: .byte 10 Int32: .int 2 Int16: .short 3 Float: .float 10.23 IntegerArray: .int 10,20,30,40,50.bss .comm LargeBuffer, 10000.text .globl _start _start: nop movl $1, %eax movl $0, %ebx int $0x80
  18. 18. Execução• Salve este código como exemplo3.s, compile e linkedite-o: # as –gstabs exemplo3.s -o exemplo3.o # ld exemplo3.o -o exemplo3 Após este processo, para executar nosso primeiro programa, basta digitar no terminal: # ./exemplo3• # gdb ./exemplo3
  19. 19. Execução• (gdb) list• (gdb) break *_start+1• (gdb) run• (gdb) info variables• (gdb) help x• (gdb) x/12cb [endereço de HelloWorld]• (gdb) x/1db [endereço de ByteLocation]• (gdb) x/1dw [endereço de Int32]• (gdb) x/1dh [endereço de Int16]• (gdb) x/1fw [endereço de Float]• (gdb) x/5dw [endereço de IntegerArray]• (gdb) x/10db [endereço de LargeBuffer]• (gdb) x/100db [endereço de LargeBuffer]
  20. 20. MOVx• É uma das instruções mais utilizadas em Assembly• Sua utilização é basicamente a seguinte: – movx origem, destino – movl  movimenta valores de 32bits movl %eax,%ebx – movw  movimenta valores de 16bits movl %ax,%bx – movb  movimenta valores de 8bits movl %ah,%bh
  21. 21. Movendo dados• Entre registradores: movl %eax, %ebx• Entre registradores e memória: local: .int 10 movl %eax, local movl local, %ebx
  22. 22. Movendo dados• Valor direto no registrador: movl $10, %ebx• Valor direto na memória: local: .byte 0 movl $10, local
  23. 23. Movendo dados• Em um endereço indexado da memória: IntegerArray: .int 10, 20, 30, 40, 50• Para selecionar o 3º valor da integer (30) – BaseAddres(offset, index, size) = – IntegerArray(0, 2, 4) movl %eax, IntegerArray(0, 2, 4)
  24. 24. Quarto programa.section .datastring: .string "Digite algo:n"tam: .long . - string.section .text.globl _start_start:movl $4, %eax # insere o valor 4, para a chamada da syscall write no EAXmovl $1, %ebx # passa o parâmetro da syscall 4 para que algo seja exibidoleal string, %ecx # carrega o endereço de memória do ECX e exibe o conteúdo de stringmovl tam, %edx # armazena o valor de tam no EDXint $0x80movl %esp, %ecx # Salva o Stack Pointer em %ecxsubl $10, %esp # Reserva 10 bytes para o usuario digitar no stackmovl $3, %eax # insere o valor da syscall read (3) no EAXmovl $9, %edx # Tamanho do que vai ser lido para EDXint $0x80movl %eax, %edx # Move o que foi digitado para EDX.movl $4, %eax # syscall writemovl $1, %ebxint $0x80movl $0x1, %eaxmovl $0x0, %ebxint $0x80
  25. 25. Execução• Salve como leia.s.• Compile, linkedite e execute: # as leia.s -o leia.o # lf leia.o -o leia # ./leia
  26. 26. Quinto programa.section .datastring1: .string "Criar um arquivo e inserir conteúdo n"tam1: .long . - string1string2: .string “Viva o Linuxn"tam2: .long . - string2arq: .string "/tmp/arquivo.txt".section .text.globl _start_start:movl $4, %eax # syscall writemovl $1, %ebxleal string1, %ecxmovl tam1, %edxint $0x80movl $5, %eax # syscall open (5)movl $arq, %ebx # arquivo que será abertomovl $03101, %ecx # modo do arquivomovl $0, %edx # Permissão 0int $0x80
  27. 27. Quinto programamovl %eax, %esi # Move o retorno da funcao open para ESImovl $4, %eax # syscall write, para efetuar a escrita no arquivomovl %esi, %ebx # local de escrita, arquivo.txtleal string2, %ecx # escrita do conteúdo de string2 para dentro do arquivomovl tam2, %edx # O tamanho da variavelint $0x80movl $6, %eax # syscall close (6)movl %esi, %ebx # Fecha o arquivoint $0x80movl $1, %eaxmovl $0, %ebxint $0x80
  28. 28. Execução• Salve como ‘escreva.s.• Compile, linkedite e execute: # as escreva.s -o escreva.o # lf escreva.o -o escreva # ./escreva
  29. 29. Comparação – Sexto programa.section .datadata_items: .long 3,67,34,222,45,75,54,34,44,33,22,11,66,0.section .text.globl _start_start: movl $0, %edi # insere 0 no registrador índice movl data_items(,%edi,4), %eax # carrega o primeiro byte de dados movl %eax, %ebx # como este é o primeiro item, %eax é o maior start_loop: cmpl $0, %eax # verifica se alcançamos o final je loop_exit incl %edi # carrega o próximo valor movl data_items(,%edi,4), %eax cmpl %ebx, %eax # compara valores jle start_loop # pula para o loop se o novo valor não for o maior movl %eax, %ebx # grava o valor como o maior jmp start_loop # pula para o início do loop loop_exit: # %ebx é o código de status para a syscall exit # e já possui o valor mais alto movl $1, %eax int $0x80
  30. 30. Execução• Salve como ‘maximo.s.• Compile, linkedite e execute: # as maximo.s -o maximo.o # lf maximo.o -o maximo # ./maximo # echo $?
  31. 31. Condicionais• je – Pula (Jump) se os valores são iguais• jg – Pula se o segundo valor for maior que o primeiro• jge – Pula se o segundo valor for maior ou igual ao primeiro• jl – Pula se o segundo valor for menor que o primeiro• jle – Pula se o segundo valor for menor ou igual ao primeiro• jmp – Pula não importa o resultado da comparação (se houver uma). Esse Jump não precisa ser precedido por uma comparação• OBS: uma condicional normalmente é precedida por um cmpl (comparando dois valores): cmpl $0, %eax je loop_exit
  32. 32. Contatos Luiz Vieirahttp://hackproofing.blogspot.com http://www.oys.com.br luizwt@gmail.com luiz.vieira@oys.com.br luiz.vieira@owasp.org

×