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...

Oficina

KeygenMe #1 (I-2)

Dom

27

Ago

2006


17:46

(16 votos, média 4.81 de 5) 


Saindo do loop, a linha de execução prossegue colocando alguns valores na pilha como parâmetros para a chamada à função wsprintfA que transforma valores hexadecimais em strings:

...
00401250  |. 53             PUSH EBX                                 ; /<%lX> = FFFFFE58
00401251  |. 68 F8DB4000    PUSH keygenme.0040DBF8                   ; |Format = "%lX"
00401256  |. 68 F8E04000    PUSH keygenme.0040E0F8                   ; |s = keygenme.0040E0F8
0040125B  |. E8 38010000    CALL <JMP.&user32.wsprintfA>             ; \wsprintfA
...
  1. (F7) PUSH EBX - Coloca o valor FFFFFE58 na pilha. Observe no painel inferior direito do OllyDbg que o valor entrou na posição superior.
  2. (F7) PUSH keygenme.0040DBF8 - Coloca mais o parâmetro de formato na pilha. Observe mais uma vez o painel da pilha.
  3. (F7) PUSH keygenme.0040E0F8 - Coloca na pilha o endereço onde a string deve ser armazenada. Posicione o painel da memória do OllyDbg (o inferior esquerdo) para poder ver o endereço 0040E0F8.
  4. (F8) CALL - A string "FFFFFE58" é colocada no endereço de memória 0040E0F8.

Obtida a primeira string, vamos analisar o cálculo para obter a segunda.

...
00401260  |. 83C4 0C        ADD ESP,0C
00401263  |. 33C0           XOR EAX,EAX
00401265  |. 33D2           XOR EDX,EDX
00401267  |. 33C9           XOR ECX,ECX
00401269  |. 03C3           ADD EAX,EBX
0040126B  |. 0FAFC3         IMUL EAX,EBX
0040126E  |. 03C8           ADD ECX,EAX
00401270  |. 2BD3           SUB EDX,EBX
00401272  |. 33D0           XOR EDX,EAX
00401274  |. 0FAFD8         IMUL EBX,EAX
00401277  |. 53             PUSH EBX                                 ; /<%lX>
00401278  |. 68 F8DB4000    PUSH keygenme.0040DBF8                   ; |Format = "%lX"
0040127D  |. 68 F8E14000    PUSH keygenme.0040E1F8                   ; |s = keygenme.0040E1F8
00401282  |. E8 11010000    CALL <JMP.&user32.wsprintfA>             ; \wsprintfA
...
  1. (F7) ADD ESP,0C - Adiciona 0Ch (12 decimal) ao ponteiro da pilha.
  2. (F7) XOR EAX,EAX - Zera o registrador EAX.
  3. (F7) XOR EDX,EDX - Zera o registrador EDX.
  4. (F7) XOR ECX,ECX - Zera o registrador ECX.
  5. (F7) ADD EAX,EBX - Adiciona o valor de EBX a EAX, ou seja, EAX = 0 + FFFFFE58 = FFFFFE58.
  6. (F7) IMUL EBX,EAX - Multiplica EBX por EAX (ou seja, eleve EBX ao quadrado), o que resulta em FFFFFCB00002BE40. Mais uma vez, este baita número não cabe em EAX e o registrador só segura a parte final deixando EAX = 0002BE40.
  7. (F7) ADD ECX,EAX - Adiciona o valor de EAX ao de ECX, ou seja, ECX = 0 + 0002BE40 = 0002BE40.
  8. (F7) SUB EDX,EBX - Subtrai EBX de EDX, ou seja, EDX = 0 - 0002BE40 = 000001A8.
  9. (F7) XOR EDX,EAX - Faça a operação XOR entre EDX e EAX. Na operação XOR, os bits dos dois valores são comparados e, quando forem iguais, o resultado é zero; quando forem diferentes, o resultado é 1. Use a calculadora do Windows no modo científico para obter os bits dos valores:
    EDX 0001A8    0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 0
    EAX 02BE40    1 0 1 0 1 1 1 1 1 0 0 1 0 0 0 0 0 0
                 -------------------------------------
           XOR =  1 0 1 0 1 1 1 1 1 1 1 1 1 0 1 0 0 0   ==> 02BFE8
      
    Agora EDX = 2BFE8.
  10. (F7) IMUL EBX,EAX - Multiplica EBX com EAX, ou seja, EBX = FFFFFE58 x 02BE40 = FB74E600.
  11. (F7) PUSH EBX - Coloca o valor de EBX, FB74E600, na pilha.
  12. (F7) PUSH keygenme.0040DBF8 - Coloca o formato na pilha.
  13. (F7) PUSH keygenme.0040E1F8 - Põe o endereço de memória onde deve ser colocada a string do valor de EBX.
  14. (F8) CALL <JMP.&user32.wsprintfA> - Chama a função wsprintfA para transformar em string o valor hexadecimal de EBX.

Agora a pergunta: para que serviu esta história de subtrair EBX de EDX e depois fazer um XOR de EDX com EAX? Toda esta frescura de bits pra cá, bits pra lá, pra depois não usar o valor calculado?

smile Encare com otimismo. Isto é o chamado junk code ou código lixo que alguns autores colocam na programação para torrar a paciência de quem está bisbilhotando o código. Por outro lado (e aí está o otimismo), foi uma bela oportunidade de rever o que vem a ser uma operação XOR e de entender porque um XOR de um registrador com ele mesmo resulta em zero (bits iguais sempre resultam em zero) smile

Informações adicionais