elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Como proteger una cartera - billetera de Bitcoin


+  Foro de elhacker.net
|-+  Programación
| |-+  Ingeniería Inversa (Moderadores: karmany, .:UND3R:., MCKSys Argentina)
| | |-+  He vuelto... y con un tuto :)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: He vuelto... y con un tuto :)  (Leído 4,089 veces)
frankener1986

Desconectado Desconectado

Mensajes: 136


Reversing the world


Ver Perfil
He vuelto... y con un tuto :)
« en: 7 Enero 2009, 19:31 pm »

Hola a todos!!! Mil años después de mi último post estoy aquí de nuevo jejeje No he tenido tiempo de estar mucho conectado, pero bueno, en ese tiempo he aprendido bastante xD Le doy un saludo a Karmany que veo que sigue por estos barrios xD

Para aportar algo os dejo un tutorial que he hecho de un crackme y cómo hacer el keygen :) me ha costado algo adaptar el texto para postearlo pero weno.. ya me contaréis xDD



Diablo2002’s Crackme #09

En este tutorial vamos a estudiar el funcionamiento de este crackme y a hacer un keygen funcional.
Explicaré todo de forma básica, pero si alguien no entiende algo que pregunte :)

Links:
-   Crackme
-   Keygen

(si te lo vas a bajar el link de download está abajo a la derecha de la página)

No le metáis mano del tirón a la solución, intentad resolver el crackme primero, si no podéis, intentad resolverlo con el tutorial, y si tampoco podéis, haced lo que sea xD


1.   Encontrando el código de la rutina de comprobación


Este paso es muy fácil. Podéis abrir el crackme en el olly y veréis cómo en las cadenas de texto está el goodboy, entre otras. También podéis poner breakpoints en las Apis obvias que hay como GetDlgWindowText, MessageBox o strlen.

Hecho esto comprobaréis que el principio del código ejecutado al pulsar el botón es:

00401129   |> \FFB5 FCFEFFFF     PUSH [LOCAL.65]

Ponemos un breakpoint en esa línea, ejecutamos el programa, introducimos los datos, en mi caso FreeSoul y 252525 y presionamos el botón.

2.   Estudiando el código

Donde estamos se pueden apreciar la llamada a un par de funciones, la

llamada al MessageBox bueno y al MessageBox malo, y un bucle grande.

Tal que así:

Código:
00401129   |> \FFB5 FCFEFFFF     PUSH [LOCAL.65]
0040112F   |.  8D85 00FFFFFF     LEA EAX,[LOCAL.64]
00401135   |.  50                PUSH EAX
00401136   |.  E8 C4000000       CALL d2k2_crk.004011FF
0040113B   |.  8D85 00FFFFFF     LEA EAX,[LOCAL.64]
00401141   |.  50                PUSH EAX
00401142   |.  8D45 80           LEA EAX,[LOCAL.32]
00401145   |.  50                PUSH EAX
00401146   |.  FF75 0C           PUSH [ARG.2]
00401149   |.  E8 72000000       CALL d2k2_crk.004011C0
0040114E   |.  8D75 80           LEA ESI,[LOCAL.32]
00401151   |.  8B7D 10           MOV EDI,[ARG.3]
00401154   |.  8B5D 0C           MOV EBX,[ARG.2]
00401157   |.  EB 3E             JMP SHORT d2k2_crk.00401197
00401159   |>  0FB616            /MOVZX EDX,BYTE PTR DS:[ESI]
0040115C   |.  0FB60F            |MOVZX ECX,BYTE PTR DS:[EDI]
0040115F   |.  8D85 00FFFFFF     |LEA EAX,[LOCAL.64]
00401165   |.  50                |PUSH EAX                                   ; /Arg3 = 00000006
00401166   |.  51                |PUSH ECX                                   ; |Arg2 = 7C80BDE6
00401167   |.  52                |PUSH EDX                                   ; |Arg1 = 0012FAD5 ASCII "52525"
00401168   |.  E8 B7000000       |CALL d2k2_crk.00401224                     ; \d2k2_crk.00401224
0040116D   |.  3A03              |CMP AL,BYTE PTR DS:[EBX]
0040116F   |.  74 1D             |JE SHORT d2k2_crk.0040118E
00401171   |.  6A 30             |PUSH 30                                    ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401173   |.  68 7A304000       |PUSH d2k2_crk.0040307A                    ; |Title = "Hey Cracker"
00401178   |.  68 6D304000       |PUSH d2k2_crk.0040306D                     ; |Text = "Wrong Serial"
0040117D   |.  FF75 08           |PUSH [ARG.1]                               ; |hOwner = 002B03F4 ('diablo2oo2's Crackme#09',class='#32770')
00401180   |.  E8 87010000       |CALL <JMP.&user32.MessageBoxA>             ; \MessageBoxA
00401185   |.  33C0              |XOR EAX,EAX
00401187   |.  5B                |POP EBX
00401188   |.  5F                |POP EDI
00401189   |.  5E                |POP ESI                                    ;  d2k2_crk.00401040
0040118A   |.  C9                |LEAVE
0040118B   |.  C2 0C00           |RETN 0C
0040118E   |>  FF8D FCFEFFFF     |DEC [LOCAL.65]
00401194   |.  46                |INC ESI                                    ;  d2k2_crk.00401040
00401195   |.  47                |INC EDI
00401196   |.  43                |INC EBX
00401197   |>  83BD FCFEFFFF 00   CMP [LOCAL.65],0
0040119E   |.^ 75 B9             \JNZ SHORT d2k2_crk.00401159
004011A0   |.  6A 40             PUSH 40                                     ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004011A2   |.  68 93304000       PUSH d2k2_crk.00403093                      ; |Title = "Hey Cracker"
004011A7   |.  68 86304000       PUSH d2k2_crk.00403086                      ; |Text = "Serial is OK"
004011AC   |.  FF75 08           PUSH [ARG.1]                                ; |hOwner = 002B03F4 ('diablo2oo2's Crackme#09',class='#32770')
004011AF   |.  E8 58010000       CALL <JMP.&user32.MessageBoxA>              ; \MessageBoxA
004011B4   |.  B8 01000000       MOV EAX,1
004011B9   |.  5B                POP EBX
004011BA   |.  5F                POP EDI
004011BB   |.  5E                POP ESI                                     ;  d2k2_crk.00401040
004011BC   |.  C9                LEAVE
004011BD   \.  C2 0C00           RETN 0C



CALL 1

Traceamos por dentro de la primera call y encontramos lo siguiente:


Código:
004011FF   /$  55                PUSH EBP
00401200   |.  8BEC              MOV EBP,ESP
00401202   |.  8B45 0C           MOV EAX,[ARG.2]
00401205   |.  C1E0 02           SHL EAX,2
00401208   |.  83F8 3C           CMP EAX,3C
0040120B   |.  76 05             JBE SHORT d2k2_crk.00401212
0040120D   |.  B8 1E000000       MOV EAX,1E
00401212   |>  50                PUSH EAX
00401213   |.  FF75 08           PUSH [ARG.1]
00401216   |.  68 00304000       PUSH d2k2_crk.00403000     ; ASCII "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
0040121B   |.  E8 53000000       CALL d2k2_crk.00401273
00401220   |.  C9                LEAVE
00401221   \.  C2 0800           RETN 8


Bien... vamos traceando y vemos que en el offset 0x401202 lo que hace es mover a EAX un numero que hace referencia a la longitud del nombre introducido. En mi caso 8.

Después vemos  SHL EAX,2, esto realiza una operación binaria (no voy a entrar en esos temas ahora)
que equivale a multiplicar por cuatro. Compara ese número con 0x3C (60 decimal), si es inferior o igual,
sustituye eax por 0x1E (30 decimal).

En resumen: eax = strlen(name)*4; ... if (eax >= 60) eax = 30;

Acto seguido vemos que pasa como argumentos el valor EAX y una cadena con  números y letras.

Entramos en la call 0x401273

Vemos lo siguiente:


Código:
00401273   /$  55                PUSH EBP
00401274   |.  8BEC              MOV EBP,ESP
00401276   |.  56                PUSH ESI                                    ;  d2k2_crk.00401040
00401277   |.  57                PUSH EDI
00401278   |.  8B75 08           MOV ESI,[ARG.1] ; 1
0040127B   |.  8B7D 0C           MOV EDI,[ARG.2] ; 2
0040127E   |.  0375 10           ADD ESI,[ARG.3] ; 3
00401281   |.  EB 02             JMP SHORT d2k2_crk.00401285
00401283   |>  AC                /LODS BYTE PTR DS:[ESI]
00401284   |.  AA                |STOS BYTE PTR ES:[EDI]
00401285   |>  803E 00            CMP BYTE PTR DS:[ESI],0
00401288   |.^ 75 F9             \JNZ SHORT d2k2_crk.00401283 ; 4
0040128A   |.  8B4D 10           MOV ECX,[ARG.3] ;5
0040128D   |.  8B75 08           MOV ESI,[ARG.1] ;6
00401290   |.  EB 03             JMP SHORT d2k2_crk.00401295
00401292   |>  AC                /LODS BYTE PTR DS:[ESI]
00401293   |.  AA                |STOS BYTE PTR ES:[EDI]
00401294   |.  49                |DEC ECX                     ;  kernel32.7C80BDE6
00401295   |>  0BC9               OR ECX,ECX                   ;  kernel32.7C80BDE6
00401297   |.^ 75 F9             \JNZ SHORT d2k2_crk.00401292 ;7
00401299   |.  B0 00             MOV AL,0
0040129B   |.  AA                STOS BYTE PTR ES:[EDI]
0040129C   |.  5F                POP EDI                        ;  d2k2_crk.00401220
0040129D   |.  5E                POP ESI                         ;  d2k2_crk.00401220
0040129E   |.  C9                LEAVE
0040129F   \.  C2 0C00           RETN 0C

Vamos traceando y vemos lo siguiente:


1. Pasa a esi el puntero a la cadena de números y letras (lamémosla cadena).

2. Pasa a edi el puntero a un buffer

3. Añade al puntero de la cadena el valor anterior de EAX. (4*8=32 en mi caso).
De modo que ahora la cadena apunta en vez de a "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
a cadena[32], "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".

4. tracead este loop y comprobad que pasa al buffer (edi) ese trozo de cadena.

5. Pasa a ecx el valor anterior de EAX otra vez (0x20 o 32d, lo que queráis)

6. Carga otra vez la cadena en esi

"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

7. este bucle termina copiando a la nueva cadena
"wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
lo que le faltaba de la inicial empezando por el principio, en otras palabras:

"wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789abcdefghijklmnopqrstuv"
"wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuv"


Yo he usado strcpy y strxfrm para hacer esto... lo veréis en el código. A esta cadena la vamos a llamar cadena2... acordaos de esto :)



CALL 2


Bueno ya no hace nada más hasta aquí, retornamos a la rutina principal... y

entramos a la siguiente call
00401149   |.  E8 72000000       CALL d2k2_crk.004011C0

Vemos lo siguiente:

Código:
004011C0   /$  55                PUSH EBP
004011C1   |.  8BEC              MOV EBP,ESP
004011C3   |.  56                PUSH ESI
004011C4   |.  57                PUSH EDI
004011C5   |.  FF75 10           PUSH [ARG.3]                                ; /String = "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuv"
004011C8   |.  E8 51010000       CALL <JMP.&kernel32.lstrlenA>               ; \lstrlenA
004011CD   |.  8BD8              MOV EBX,EAX
004011CF   |.  8B75 08           MOV ESI,[ARG.1]
004011D2   |.  8B7D 0C           MOV EDI,[ARG.2]
004011D5   |.  8A16              MOV DL,BYTE PTR DS:[ESI]
004011D7   |.  C0C2 03           ROL DL,3
004011DA   |.  EB 16             JMP SHORT d2k2_crk.004011F2
004011DC   |>  AC                /LODS BYTE PTR DS:[ESI]
004011DD   |.  3206              |XOR AL,BYTE PTR DS:[ESI]
004011DF   |.  02C2              |ADD AL,DL
004011E1   |.  02D0              |ADD DL,AL
004011E3   |.  52                |PUSH EDX
004011E4   |.  0FB6C0            |MOVZX EAX,AL
004011E7   |.  99                |CDQ
004011E8   |.  F7F3              |DIV EBX
004011EA   |.  8B45 10           |MOV EAX,[ARG.3]
004011ED   |.  8A0402            |MOV AL,BYTE PTR DS:[EDX+EAX]
004011F0   |.  AA                |STOS BYTE PTR ES:[EDI]
004011F1   |.  5A                |POP EDX                                    ;  0012FC3C
004011F2   |>  803E 00            CMP BYTE PTR DS:[ESI],0
004011F5   |.^ 75 E5             \JNZ SHORT d2k2_crk.004011DC
004011F7   |.  AC                LODS BYTE PTR DS:[ESI]
004011F8   |.  AA                STOS BYTE PTR ES:[EDI]
004011F9   |.  5F                POP EDI                                     ;  0012FC3C
004011FA   |.  5E                POP ESI                                     ;  0012FC3C
004011FB   |.  C9                LEAVE
004011FC   \.  C2 0C00           RETN 0C


Bien, hasta 004011DA va cargando en los registros, en esi un puntero al

nombre (en mi caso "FreeSoul"),
en EAX, la longitud de la famosa cadena2 (62d) (por cierto vaya programador... que llama a la función
strlen() para una cadena que siempre va a ser igual de larga... xD)

Llegados aquí entramos al bucle:

Código:
004011C0   /$  55                PUSH EBP
004011C1   |.  8BEC              MOV EBP,ESP
004011C3   |.  56                PUSH ESI
004011C4   |.  57                PUSH EDI
004011C5   |.  FF75 10           PUSH [ARG.3]                                ; /String = "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuv"
004011C8   |.  E8 51010000       CALL <JMP.&kernel32.lstrlenA>               ; \lstrlenA
004011CD   |.  8BD8              MOV EBX,EAX ;; ebx = eax (longitud cadena)
004011CF   |.  8B75 08           MOV ESI,[ARG.1]
004011D2   |.  8B7D 0C           MOV EDI,[ARG.2]                             ;  (antes de empezar el bucle)
004011D5   |.  8A16              MOV DL,BYTE PTR DS:[ESI]                    ;  dl = rol name[0], 3
004011D7   |.  C0C2 03           ROL DL,3
004011DA   |.  EB 16             JMP SHORT d2k2_crk.004011F2
004011DC   |>  AC                /LODS BYTE PTR DS:[ESI]                     ;  al = name[i]
004011DD   |.  3206              |XOR AL,BYTE PTR DS:[ESI]                   ;  al = al ^ name[i+1]
004011DF   |.  02C2              |ADD AL,DL                                  ;  al += dl
004011E1   |.  02D0              |ADD DL,AL                                  ;  dl += al
004011E3   |.  52                |PUSH EDX                                   ;  var1 = edx
004011E4   |.  0FB6C0            |MOVZX EAX,AL
004011E7   |.  99                |CDQ
004011E8   |.  F7F3              |DIV EBX                                    ;  edx = eax  mod 0x3E
004011EA   |.  8B45 10           |MOV EAX,[ARG.3]
004011ED   |.  8A0402            |MOV AL,BYTE PTR DS:[EDX+EAX]
004011F0   |.  AA                |STOS BYTE PTR ES:[EDI]           ;  key[i] = cadena2[edx]
004011F1   |.  5A                |POP EDX                    ;  0012FC3C ... edx = var1
004011F2   |>  803E 00            CMP BYTE PTR DS:[ESI],0
004011F5   |.^ 75 E5             \JNZ SHORT d2k2_crk.004011DC            ;  loop
004011F7   |.  AC                LODS BYTE PTR DS:[ESI]
004011F8   |.  AA                STOS BYTE PTR ES:[EDI]
004011F9   |.  5F                POP EDI                                   ;  0012FC3C
004011FA   |.  5E                POP ESI                                     ;  0012FC3C
004011FB   |.  C9                LEAVE
004011FC   \.  C2 0C00           RETN 0C


vale... vemos que prepara en ebx la longitud de la cadena... (0x3E)
luego prepara el valor de dl (dl = rol name[0], 3),
luego hace un bucle dodne hace operaciones... (sumas, xor, mod),
y el resultado lo usa como índice en la cadena2 para guardar el valor

para explicarme mejor:

name -> nombre introducido
i -> contador del bucle
var1 -> variable donde guardaremos un dato
al -> parte del registro eax
dl -> parte del registro edx
key -> donde guardamos la nueva cadena...
cadena2 -> esto está claro jeje

... qué es mod? pues es simplemente el resto de dividir un número con otro
así 12 mod 7 = 5.

por fin... salimos de la función y volvemos a la rutina principal... vemos

que un puntero
a esa Key está en el registro ESI. El próximo paso es ver que hace con eso.

Código:
00401149   |.  E8 72000000       CALL d2k2_crk.004011C0 ; salimos...
0040114E   |.  8D75 80           LEA ESI,[LOCAL.32] ; <- Mueve la key, en mi

caso ASCII "alFGOyrr"
00401151   |.  8B7D 10           MOV EDI,[ARG.3] ; <- serial
00401154   |.  8B5D 0C           MOV EBX,[ARG.2] ; <- name

y seguidamente vemos un pedazo de loop que impone pero q no es pa tanto xD

Código:
00401157   |. /EB 3E             JMP SHORT d2k2_crk.00401197	; entramos al loop
00401159   |> |0FB616            /MOVZX EDX,BYTE PTR DS:[ESI]
0040115C   |. |0FB60F            |MOVZX ECX,BYTE PTR DS:[EDI] ; aki abajo hay 1 call decisiva... donde se comparan valores
0040115F   |. |8D85 00FFFFFF     |LEA EAX,[LOCAL.64]
00401165   |. |50                |PUSH EAX                                   ; /Arg3 = 0012F900
00401166   |. |51                |PUSH ECX                                   ; |Arg2 = 7C80BDE6
00401167   |. |52                |PUSH EDX                                   ; |Arg1 = 0012F906
00401168   |. |E8 B7000000       |CALL d2k2_crk.00401224                     ; \d2k2_crk.00401224
0040116D   |. |3A03              |CMP AL,BYTE PTR DS:[EBX]
0040116F   |. |74 1D             |JE SHORT d2k2_crk.0040118E ; Salto que nos libra del badboy
00401171   |. |6A 30             |PUSH 30                                    ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401173   |. |68 7A304000       |PUSH d2k2_crk.0040307A                     ; |Title = "Hey Cracker"
00401178   |. |68 6D304000       |PUSH d2k2_crk.0040306D                     ; |Text = "Wrong Serial"
0040117D   |. |FF75 08           |PUSH [ARG.1]                               ; |hOwner = 002B03F4 ('diablo2oo2's Crackme#09',class='#32770')
00401180   |. |E8 87010000       |CALL <JMP.&user32.MessageBoxA>             ; \MessageBoxA
00401185   |. |33C0              |XOR EAX,EAX
00401187   |. |5B                |POP EBX
00401188   |. |5F                |POP EDI
00401189   |. |5E                |POP ESI
0040118A   |. |C9                |LEAVE
0040118B   |. |C2 0C00           |RETN 0C
0040118E   |> |FF8D FCFEFFFF     |DEC [LOCAL.65]
00401194   |. |46                |INC ESI
00401195   |. |47                |INC EDI
00401196   |. |43                |INC EBX
00401197   |> \83BD FCFEFFFF 00   CMP [LOCAL.65],0
0040119E   |.^ 75 B9             \JNZ SHORT d2k2_crk.00401159 ; salto que nos manda a comprobar la siguiente letra...
004011A0   |.  6A 40             PUSH 40                                     ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004011A2   |.  68 93304000       PUSH d2k2_crk.00403093                      ; |Title = "Hey Cracker"
004011A7   |.  68 86304000       PUSH d2k2_crk.00403086                      ; |Text = "Serial is OK"
004011AC   |.  FF75 08           PUSH [ARG.1]                                ; |hOwner = 002B03F4 ('diablo2oo2's Crackme#09',class='#32770')
004011AF   |.  E8 58010000       CALL <JMP.&user32.MessageBoxA>              ; \MessageBoxA
004011B4   |.  B8 01000000       MOV EAX,1
004011B9   |.  5B                POP EBX
004011BA   |.  5F                POP EDI
004011BB   |.  5E                POP ESI
004011BC   |.  C9                LEAVE
004011BD   \.  C2 0C00           RETN 0C

Se resume en un loop que va comparando letra por letra nuestro name con algo...
si detecta algún error tomamos el camino del bad boy... si no... tiramos hacia el goodboy :)

Vale...  entremos a la call de una vez


CALL 3 - COMPROBACIÓN


Hay 3 calls... qué pereza no? bah que va, no son para tanto XD
Algunas no voy a explicarlas porque ya las hemos visto

Aunque llega la parte que quizás sea mas difícil de entender

Código:
00401224   /$  55                PUSH EBP
00401225   |.  8BEC              MOV EBP,ESP
00401227   |.  81C4 78FFFFFF     ADD ESP,-88
0040122D   |.  56                PUSH ESI
0040122E   |.  57                PUSH EDI
0040122F   |.  53                PUSH EBX
00401230   |.  FF75 08           PUSH [ARG.1]
00401233   |.  FF75 10           PUSH [ARG.3]
00401236   |.  E8 67000000       CALL d2k2_crk.004012A2 ; 1
0040123B   |.  8945 FC           MOV [LOCAL.1],EAX ; guarda el valor generado (veremos abajo cómo lo genera)
0040123E   |.  FF75 FC           PUSH [LOCAL.1]
00401241   |.  8D85 78FFFFFF     LEA EAX,[LOCAL.34]
00401247   |.  50                PUSH EAX
00401248   |.  FF75 10           PUSH [ARG.3]
0040124B   |.  E8 23000000       CALL d2k2_crk.00401273 ; 2
00401250   |.  FF75 0C           PUSH [ARG.2]
00401253   |.  8D85 78FFFFFF     LEA EAX,[LOCAL.34]
00401259   |.  50                PUSH EAX
0040125A   |.  E8 43000000       CALL d2k2_crk.004012A2 3:
0040125F   |.  8945 F8           MOV [LOCAL.2],EAX
00401262   |.  8B4D F8           MOV ECX,[LOCAL.2]
00401265   |.  8B45 10           MOV EAX,[ARG.3]
00401268   |.  0FB60401          MOVZX EAX,BYTE PTR DS:[ECX+EAX]
0040126C   |.  5B                POP EBX                            ;  d2k2_crk.0040116D
0040126D   |.  5F                POP EDI                            ;  d2k2_crk.0040116D
0040126E   |.  5E                POP ESI                            ;  d2k2_crk.0040116D
0040126F   |.  C9                LEAVE
00401270   \.  C2 0C00           RETN 0C



a.


 Esta call devuelve a EDX un puntero a una cadena...

Código:
Veamos como se forma
004012A2   /$  55                PUSH EBP
004012A3   |.  8BEC              MOV EBP,ESP
004012A5   |.  8B55 08           MOV EDX,[ARG.1]                             ;   edx -> cadena2
004012A8   |.  8B4D 0C           MOV ECX,[ARG.2]                             ;  ecx -> key[0]
004012AB   |.  33C0              XOR EAX,EAX
004012AD   |.  EB 0A             JMP SHORT d2k2_crk.004012B9
004012AF   |>  380C10            /CMP BYTE PTR DS:[EAX+EDX],CL
004012B2   |.  75 04             |JNZ SHORT d2k2_crk.004012B8
004012B4   |.  C9                |LEAVE
004012B5   |.  C2 0800           |RETN 8
004012B8   |>  40                |INC EAX
004012B9   |>  803C10 00          CMP BYTE PTR DS:[EAX+EDX],0
004012BD   |.^ 75 F0             \JNZ SHORT d2k2_crk.004012AF                ;  loop until
004012BF   |.  B8 FFFFFFFF       MOV EAX,-1                                  ;  cadena2[x] == key[i]
004012C4   |.  C9                LEAVE
004012C5   \.  C2 0800           RETN 8


el resumen es este:

Código:
Key[i]
es el valor de la key que estemos comprobando ahora... la primera en mi caso es 'a' de "alFGOyrr"
hace un bucle donde va a comparar
Código:
cadena2[x]
(llamemos al contador X) con
Código:
key[i]
y el valor de esa X es el que retorna la función y podemos apreciar arriba que lo guarda en
Código:
[LOCAL, 1]

vallamos a la siguiente call...



b.

 Veamos esta call

Código:
00401273   /$  55                PUSH EBP
00401274   |.  8BEC              MOV EBP,ESP
00401276   |.  56                PUSH ESI
00401277   |.  57                PUSH EDI
00401278   |.  8B75 08           MOV ESI,[ARG.1]                  ;  esi = &cadena2
0040127B   |.  8B7D 0C           MOV EDI,[ARG.2]                  ;  edi = serial introducido
0040127E   |.  0375 10           ADD ESI,[ARG.3]                   ;  esi = cadena2[x] , sí, lo que
00401281   |.  EB 02             JMP SHORT d2k2_crk.00401285          ;  guardamos en [LOCAL, 1];
00401283   |>  AC                /LODS BYTE PTR DS:[ESI]
00401284   |.  AA                |STOS BYTE PTR ES:[EDI]
00401285   |>  803E 00            CMP BYTE PTR DS:[ESI],0
00401288   |.^ 75 F9             \JNZ SHORT d2k2_crk.00401283
0040128A   |.  8B4D 10           MOV ECX,[ARG.3]
0040128D   |.  8B75 08           MOV ESI,[ARG.1]
00401290   |.  EB 03             JMP SHORT d2k2_crk.00401295
00401292   |>  AC                /LODS BYTE PTR DS:[ESI]
00401293   |.  AA                |STOS BYTE PTR ES:[EDI]
00401294   |.  49                |DEC ECX
00401295   |>  0BC9               OR ECX,ECX
00401297   |.^ 75 F9             \JNZ SHORT d2k2_crk.00401292
00401299   |.  B0 00             MOV AL,0
0040129B   |.  AA                STOS BYTE PTR ES:[EDI]
0040129C   |.  5F                POP EDI
0040129D   |.  5E                POP ESI
0040129E   |.  C9                LEAVE
0040129F   \.  C2 0C00           RETN 0C



Vale... tracead y comprobaréis que lo que hace es cortar la cadena2 desde
Código:
cadena2[x] 
(la x la obtuvimos en el call anterior) hasta el final...
y a ese trozo de cadena le añade cadena2 desde el principio hasta
Código:
cadena2[x]

es decir, en mi caso hace lo siguiente:

"wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - "abcdefghijklmnopqrstuv"
"abcdefghijklmnopqrstuv" + "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

llamemos a esta cadena3 xD

OOOOokei, todo bien, sigamos hasta la última call XD



c. ÚLTIMA CALL...


Código:
004012A2   /$  55                PUSH EBP
004012A3   |.  8BEC              MOV EBP,ESP
004012A5   |.  8B55 08           MOV EDX,[ARG.1]                     ;   edx -> cadena2 /// cadena3
004012A8   |.  8B4D 0C           MOV ECX,[ARG.2]                  ;  ecx -> key[0] /// serial[0]
004012AB   |.  33C0              XOR EAX,EAX
004012AD   |.  EB 0A             JMP SHORT d2k2_crk.004012B9
004012AF   |>  380C10            /CMP BYTE PTR DS:[EAX+EDX],CL
004012B2   |.  75 04             |JNZ SHORT d2k2_crk.004012B8
004012B4   |.  C9                |LEAVE
004012B5   |.  C2 0800           |RETN 8
004012B8   |>  40                |INC EAX
004012B9   |>  803C10 00          CMP BYTE PTR DS:[EAX+EDX],0
004012BD   |.^ 75 F0             \JNZ SHORT d2k2_crk.004012AF         ;  loop until
004012BF   |.  B8 FFFFFFFF       MOV EAX,-1                      ;  cadena3[x] == serial[i]
004012C4   |.  C9                LEAVE

Os acordais de la 1º call??? pues esta es igual, pero en lugar de cadena2, hay cadena3 y en lugar de comparar con la letra de la key, ahora comparamos la letra del serial con el contador x hasta encontrar la letra que buscamos en cadena3...

Igual te parece todo esto un quebradero de cabeza... pero ahora lo explicaré de una forma más sencilla, salgamos de esta call.


...
Salimos y vemos lo que queda:

Código:
0040125A   |.  E8 43000000       CALL d2k2_crk.004012A2 ; <- hemos salido de aquí
0040125F   |.  8945 F8           MOV [LOCAL.2],EAX
00401262   |.  8B4D F8           MOV ECX,[LOCAL.2]
00401265   |.  8B45 10           MOV EAX,[ARG.3]
00401268   |.  0FB60401          MOVZX EAX,BYTE PTR DS:[ECX+EAX] ; WoooOhh
0040126C   |.  5B                POP EBX
0040126D   |.  5F                POP EDI
0040126E   |.  5E                POP ESI
0040126F   |.  C9                LEAVE
00401270   \.  C2 0C00           RETN 0C

vale, la función esta que tiene 3 subfunciones y que retorna a la principal, retorna
el valor de
Código:
 cadena2[x]
, sí, el último x obtenido jeje...

Si conseguimos que este valor sea igual que
Código:
name[i]
para todas las i (osea, letras xD), iremos al GoodBoy



Veamos la lógica:

x es un número resultado de buscar
Código:
name[i]
(pongamos 'F' como ejemplo) dentro de cadena2
"wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuv" ... pues x daría 9

y
Código:
serial[i]
debe ser igual a
Código:
cadena3[x]
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

por lo tanto...
Código:
serial[0] = cadena3[9]

La primera letra de mi serial.... 'j' :)

Vamos haciendo el bucle con todas las letras hasta cosneguir el serial completo 'jgnoaqpg'


Te parecerá quizás imposible hacer un keygen... pero a la larga es más sencillo xD


Os dejo el código del keygen mío... adaptarlo y probadlo si queréis xD



Código:
char* CheckSum(HWND hWnd, char* name)
{

char* serial;
serial = new char[60];
char* key;
key = new char[60];

char something[63] =

"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";


char* newsomething;
newsomething = new char[63];



int nlen, mlen;
nlen = strlen(name);
mlen = nlen*4;

if (mlen > 0x3C) mlen=0x1E;

int i; int a;
a = 63-mlen;
strxfrm(newsomething, &something[mlen], a);


char* nspart;
nspart = new char[64];
strxfrm(nspart, &something[0], mlen);
nspart[mlen]='\0';

strcat(newsomething, nspart);


char xdl, xal;
char xdl2;



int b;
xdl = name[0];

__asm {
push eax
mov eax, 00000000
mov al, xdl
rol al, 3
mov xdl, al
pop eax
}


for(i=0; i<nlen; i++)
{
xal = name[i];
b = i+1;
xal = xal ^ name[b];
xal += xdl;
xdl += xal;
xdl2 = xdl;

__asm {
pushad
xor eax, eax
xor ebx, ebx
mov al, xal
mov bl, 03Eh
xor edx, edx
div ebx
mov xdl, dl
popad
}

xal = newsomething[xdl];
key[i] = xal;
xdl = xdl2;
}

key[nlen] = 0;


char *newsom;
newsom = new char[64];


int j;
char ch = 0;
for (i=0; i<nlen; i++)
{

/////j = loop until newsomething[j] == algo[i]
j = 0;
while(newsomething[j] != key[i]) j++;
j;


///edi = newsomething[j-final]
a = 63-j;
strxfrm(newsom, &newsomething[j], a);

///edi -> strcat newsomething[0-j]
///edx = edi
strcpy(nspart, newsomething);
nspart[j] = 0;
strcat(newsom, nspart);



/*
j es un numero al buscar name[i] dentro de edx
serial[i] debe corresponder con newsomething[j]
...
loop until edx[j] == serial[i]
letter = newsomething[j] // letter must = name[i]
*/

j = 0;
while(newsomething[j] != name[i]) j++;

serial[i] = newsom[j];
serial[nlen] = 0;

}


return serial;

}



Espero que alguien se lea todo esto y que le sirva de algo... cualquier duda preguntadme :D
Un saludo !!! :D

« Última modificación: 9 Enero 2009, 23:07 pm por frankener1986 » En línea

Amerikano|Cls


Desconectado Desconectado

Mensajes: 789


[Beyond This Life]


Ver Perfil WWW
Re: He vuelto... y con un tuto :)
« Respuesta #1 en: 8 Enero 2009, 00:52 am »

Muy buen aporte, y que bueno que regreses  :)
En línea





Mi blog:
http://amerikanocls.blogspot.com
frankener1986

Desconectado Desconectado

Mensajes: 136


Reversing the world


Ver Perfil
Re: He vuelto... y con un tuto :)
« Respuesta #2 en: 12 Enero 2009, 15:26 pm »

ni 1 duda ni 1 opinion? XD
En línea

karmany
Moderador
***
Desconectado Desconectado

Mensajes: 1.615


Sueñas que sueñas


Ver Perfil WWW
Re: He vuelto... y con un tuto :)
« Respuesta #3 en: 13 Enero 2009, 09:57 am »

Bienvenido de nuevo.

Muchas gracias por el tute y keygen, realmente muy bien trabajado. Encontrar la rutina nombre-serial puede resultar una labor tediosa y más después explicarlo en un tute...

Muchísimas gracias por la aportación.
Un saludo
karmany
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines