Unconfigured Ad Widget

Collapse

Anúncio

Collapse
No announcement yet.

Pegando ID Assembly

Collapse
X
 
  • Filter
  • Tempo
  • Show
Clear All
new posts

  • Font Size
    #1

    Pegando ID Assembly

    Fala galera, hoje vou falar um pouco sobre Assembly e como criar um pequeno
    programinha.

    Primeiramente seria um tanto enfadonho falar sobre fazer um programa sem
    falar sobre compiladores, mesmo não havendo a necessidade de compilar um
    codigo em assembly,o compilador pode traduzir o codigo para assembly
    e depois usar um assembler para criar as instructions code.

    Na hora de compilar um programa acontece o seguinte:
    (Isso aqui nas linguagens de alto-nivel)
    Resumindo:
    1- o compilador pega o codigo do programa e transforma em
    instruction code que são os codigos que podem ser "entendidos" pelo
    processador.
    2-A primeira etapa gera um arquivo .o que eh um Object code File que contem
    as instructions. Seria mais ou menos assim:

    //Codigo em C
    int main()
    {
    int i = 1;
    exit(0)
    }

    //Instruction code
    55
    89 E5
    83 EC 08
    C7 45 FC 01 00 00 00
    83 EC 0C
    6A 00
    E8 D1 FE FF FF

    Voce não precisa saber a funcao de cada numero ate porque cada processador
    tem suas proprias instruction codes. Mas preste atenção na 4 linha

    01 00 00 00-> Esta carregandoo valor 1.

    Continuando
    O object code em si nao pode ser executado os sistemas operacionais
    requerem um tipo especifico de executavel, e é ai que o Linker entra

    Linker:
    O linker pega o object file e adiciona bibliotecas e outros object codes
    necessarios e cria o executavel.
    Geralmente você não vê isso porque as IDE`s ja compilam e linkam tudo de uma
    vez.

    Mnemonicos:
    Como visto acima decorar todos instructions code, cada numero, cada opcode,etc
    seria quase impossivel, para isso criaram os Mnemonicos.
    Ta, mas pra que servem?
    Eles servem para, ao inves de decorar aqueles numeros infernais voce pode usar
    palavras faceis de lembrar, como por exemplo:movl $1, %eax. Aqui movemos o
    valor 1 para o registrador eax. Voce deve estar percebendo que essa declaracao
    que fiz acima pode ser um pouco diferente do que outros codigo como: usar o
    sinal de porcentagem antes do registrador.Mas jaja eu explico o porque disso.

    Vamos falar um pouco sobre dados em Assembly:
    Um dos modos de armazenar um dado em assembly eh atraves de labels:
    (As barras sao so para deixar mais arrumado,elas nao sao usadas de fato)

    //variavel:
    .ascii "Guia do hacker"
    //contadeluz:
    .long 130

    E obvio olhando isto que, criamos uma string e um valor int.
    Ta mas como eu acesso isso no eu programa?
    Simples, basta colocar o nome do label(variavel ou contadeluz)
    Jaja isso sera posto em prática.

    Esses labels sao colocados na memoria da seguinte maneira:


    Peço desculpa pela imagem pois nao sei mexer com photoshop.
    O primeiro elemento declarado e "insertado" primeiro
    Nesse caso apos o ultimo byte do label variavel o label contadeluz ja seria
    setado ali.(vou colocar as primeiras letras da string)
    De fato como eh uma string ela vai ser colocada na memoria de acordo com o
    valor de cada caractere da tabela ascii .


    Sections:
    As sections em assembly sao uma das coisas mais importantes na hora de fazer
    codigo as principais sao 3:

    -data section // variavel predefinidas
    -bss section // funcao parecida com a .data porem as informacoes nao sao
    inicializadas imediatamente, ela contem buffers para declaracao de dados
    no decorrer do programa
    -section .text // Se você já viu os videos do Nick certamente viu que o entry
    point deve estar na section .text pois eh la que o codigo em si fica.


    Assemblers:
    Os assembler são programas que vao traduzir o codigo assembly para o cpu.
    Ele vai gerar um objet file tambem.
    "AFF entao vai estar compilando?"
    NAO! Ele vai apenas "traduzir" uma vez que estamos falando de linguagem de
    baixo nivel.

    Existem varios assemblers aqui vai o nome de alguns:

    -MASM(Microsotf)
    -NASM(Netwide assembler)
    -GAS(GNU)//uso este
    -HLA(High level Assembler)
    Apos voce "assemblar" surgira um object code, mas oque devemos fazer?
    Vamos usar um linker e criar o executavel.

    Eu vou abordar toda a teoria primeiro depois a pratica ok?

    Vamos para mais uma ferramenta o Debugger:
    Como você ja deve ter usado o Ollydbg ja sabe mais ou menos como
    funciona.O debugger eh muito util para encontrar erros em programas, ou
    para analise.
    Ele executa o programa numa "sandbox" então voce pode acessar suas funções,
    ver o funcionamento, parar a execução,ver locais de memória, etc.
    O debugger que usarei vai ser o gdb(GNU).


    O compilador permite voçê ver o codigo depois de "assemblado"(ex:executavel)
    Mais e os object files?

    Existem varias formas mais eu vou usar um programa chamado objdump.

    Agora chegando no fim da teoria =)
    Vou falar sobre as sintaxes que usarei para criar nosso programa.

    Uma das coisas mais CHATAS é que os assemblers usam sintaxes diferentes
    para o codigo assembly, como eu disse vou usar o gas(GNU) ele usa uma sintaxe
    chama AT&T que vem de AT&T Bell Labs que foi onde o UNIX e a linguagem C
    surgiram.
    Vou citar algumas diferncas sobre esta sintaxe e a Intel vamos la:

    --A sintaxe AT&T usa o '$' quando se fala em valores.Exemplo:$4->AT&T, 4->Intel

    --A AT&T usa o '%' quando se refere a um nome como um registrador.
    Exemplo: AT&T->%eax. Intel->eax

    --Essa é a mais importante: AT&T usa o sentido oposto.Como assim?
    Suponhamos que eu queira mover o valor 4 para o registrador eax:

    AT&T-> movl $4, %eax
    Intel-> mov eax, 4

    --Em jumps as coisas tambem podem mudar:
    AT&T->ljmp $lugar %eax
    Intel->jmp lugarffse
    t

    Bom sem demora vamos fazer o programa:

    A finalidade deste programa é mostrar qual o fornecedor do seu processador:

    #cpuid guaidohacker.com.br extract Vendor Id
    .section .data
    output:
    .ascii "The processor Vendor id is 'xxxxxxxxxxxx'\n"
    .section .text
    .globl _start
    _start:
    movl $0, %eax
    cpuid
    movl $output, %edi
    movl %ebx, 28(%edi)
    movl %edx, 32(%edi)
    movl %ecx, 36(%edi)
    movl $4, %eax
    movl $1, %ebx
    movl $output, %ecx
    movl $42, %edx
    int $0x80
    movl $1, %eax
    movl $0, %ebx
    int $0x80


    Vou enumerar cada linha do codigo ok?
    Criamos um label chamado output que contera uma string, note que ha varios
    "x" eles serão substituidos pelo ID do processador.
    Note que ele esta na section data pois é uma "variavel"

    apos isso temos a section .text e a .globl _start.
    A .globl significa que pode ter um uso externo tal como a ultilização do codigo
    em um programa em C.
    _start é onde o programa vai começar(start point)


    Linha-1-Depois nos movemos o valor 0 para eax.
    Linha-2-Chamamos cpuid.Mas oque e isso?
    //CPUID é uma instrução que vai fazer alguma coisa especifica de acordo
    com o valor de eax, aqui vai algumas tarefas que podem ser feita com cpuid:

    EAX = 0 -> Mostra o Fornecedor do CPU
    EAX = 1 -> Mostra o tipo,modelo,familia do CPU.
    EAX = 2 -> Cache de configuração
    EAX = 3 -> Numero serial do CPU.
    NOTA IMPORTANTE: no nosso caso como EAX = 0 o processador vai retornar
    os valores os registradores:

    EBX -> 4 primeiros bytes da string
    EDX -> 4 bytes do meio da string
    ECX -> 4 ultimos bytes da string



    Sao os principais usos.
    Continuando:

    3-Movemos nosso label output parao registrador EDI(data pointer for destination string)

    4-Criamos/Movemos um ponteiro começando no local 28 baseado em EDI(que e o nosso label) para %ebx

    5-Criamos/Movemos um ponteiro começando no local 32 da string em EDI para %edx

    6-Criamos/Movemos um ponteiro comecando no local 36 da string EDI para %ecx

    NOTA:Voce nao precisa saber oque cada instruçao faz de imediato eu farei mais
    posts detalhando cada função.


    Linha 7,8,9,10,11-São responsaveis para mostrar a informacao obtida e
    chama uma interrupção de software(int $0x80)

    as 3 ultimas linhas:
    Depois de mostrar o ID do 'produtor' é hora de sairmos do programa(exit)
    Vamos usar uma system call(1) o valor 1 diz que o programa acabou.
    E o registrador EBX contem um valor retornado pelo programa o zero indica
    que deu tudo certo.


    Feito isso salve o programa com x.asm ou x.s

    É hora de utilizar o assembler(GAS)

    para usar o GAS basta digitar 'as'[opcoes].

    Vamos la:

    as -o assemblygh.asm assemblygh.o //criando o object file



    Agora vamos utilizar o linker para criar o executavel:


    ld -o assemblygh assemblygh.o

    apos isso é so executar:


    ./assemblygh


    Repare que os valores contidos naqueles ponteiros são relativos a string
    se voce quiser trocar para "O meu ID eh 'xxxxxxxxxxxx'\n", voçê tem que mudar
    os valores no caso serio algo assim:

    ...codigo
    movl %ebx, 12(%edi)
    movl %edx, 16(%edi)
    movl %ecx, 20(%edi)

    Nao entendi a contagem...

    Eh basicamente a contagem dos caracteres:

    O meu ID eh 'xxxxxxxxxxxx'\n

    A letra O seria 0 o espaço seria 1 o M 2 e assim por diante.
    Bom esta ai o nosso programa,Agora vamos "debugar" ele.
    Para isso eu criei outra pasta e movi somente o arquivo .asm para ela.

    Eu vou usar o gdb(GNU debugger).
    Para rodar ele corretamente no programa e preciso reassemblar o programa.asm
    de uma maneira diferente:

    as -gstabs -o programa.o programa.asm
    ld -o programa programa.o

    E criamos o executavel, repare que este é maior que o criado anteriormente
    sem o parametro -gstabs.

    Sem o parâmetro


    Com o gstabs


    Isso ocorre porque este parâmetro é necessário para auxiliar o debugger a
    percorrer o executável.

    Vamos la:
    gdb programa, depois disso ele vai esperar os comandos

    //vamos setar um breakpoint

    break *_start

    //isso faz um breakpoint logo apos a section start

    A partit dai, basta digitar 'next' para percorrer o programa.


    OBJDUMP
    Este carinha vai nos permitir ver object codes, olhe só

    objdump -s programaobj.o



    Você deve estar pensando
    -Já vi isso em um shellcode!

    De fato sim, oque ocorre é que a segunda coluna que contém os objets são usados
    num array do tipo char para executar um shellcode.Eu farei um proxímo post sobre isso. Mas só pra ilustrar iria ficar mais ou menos assim

    char shellcode[] = "\xb8\x00\x00\x00...."
    Depois é necessario cria uma função para executar isso, mas como eu disse farei
    um post sobre shellcode e como escrever um.

    Espero que tenha gostado e peço desculpas pelas imagens, é meu primeiro post,estou aberto a críticas , valeu!

    Similar Threads

  • Font Size
    #2
    Galera deu algum erro na hora de enviar as imagens , vou colocar o link delas aqui

    Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
    Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
    Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
    Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
    Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
    vhttp://postimg.org/image/rfuly1xxh/
    Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
    Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
    Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
    Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
    Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...

    Comment

    X
    Working...
    X