Tutorial sobre Kyodai v10.21
|
Víctima: |
Kyodai v10.21 |
|
URL: |
|
|
Descripción: |
Tipico juego chino... o japones... o... vamos oriental! |
|
Tamaño del ejecutable: |
¿?¿? bytes |
|
Tipo de Protección: |
Empacado (Aspack) & Serial |
|
Método de ataque |
Desempacar "a pelo" con el SICE |
|
Objetivo |
Sacar el KeYgEn |
|
Cracker |
Mr_Burns [K-FoR] |
|
Dificultad |
Newbie - Aficionado - Avanzado - Experto - Élite |
|
Herramientas |
SofIce, Win32Dasm, ProcDump & Tasm5 |
|
Fecha: |
24-09-2000 |
|
|
INTRODUCCIÓN |
|
Hola de nuevo a todos. He decidido hacer este tutorial del Kyodai sabiendo que ya hay suficientes por aburrimiento una tarde de Domingo a las 17:40 de la tarde. Y... porque este es mi primer tutorial sobre cómo hacer un keygen (en ASM). Asi que creo que deberíamos empezar ya.
|
|
LET'S ROCK |
|
Para empezar instalamos el programa con tranquilidad sabiendo que es shareware y que nos pedira una puta clave :-)
Una vez instalado abrimos el programa y lo estudiamos un poco (joder!! que buena pinta tiene el condenado es chulo!!!) y miramos en el menu: Help/Register y observamos que nos pide el Nombre y número de serie. Bueno pues vamos a introducir los datos:
Nombre: Mr_Burns
Serial: 1234567890
Le damos al "OK" y.... nos aparece una ventanita que pone "Lo siento nº incorrecto. Por favor compruebe que lo escribio tal y como le fue entregado". "Caguen..." pues a mi me ha molado mazo y me lo quiero quedar asi que lo voy a CRaCKeaR!!
Empezare
metiendole mano con el Win32Dasm y... joe!! que se me ha colgado!!
Bueno no pasa nada lo voy a cargar en el Loader sel SofIce (SICE)
y... pues tp tira!!! Pufff!! Esto me hace sospechar que este programa
esta empakado!!!
Bueno
para ello usare mi querido ProcDump. Entro en el PE Editor y abro el
kyo1021.exe (no el kyodai.exe!!), entro en Sections y observo dos
cosas:
1º En .CODE (caracteristics) aparece C0000040. Eso significa que el programa no es ejecutable!!! Y que yo sepa deberia tener E0000020 (ejecutable). Bueno, pues eso, lo cambiamos.
2º Aparece una cadena por ahi que pone Aspack. Eso a mi me suena a Compresor!!
Despues
de esto lo que voy a hacer es descomprimir el programa con el Aspack,
la ultima version porque este programa es nuevo, y... no tira!!! Eso
quiere decir que no tenemos esa version. Lo que significa que habra
que hacerlo a mano (jejeje esto se pone interesante asi que me voy a
por un cafetito :-))
----------Desempacar el fichero con el SoftIce----------
Corremos el Loader del Sice y vemos que ahora SI! que tiran esas ruletitas :-) Entramos y vemos que la direccion es un poco rara (5A1001) y observamos:
PUSHAD
CALL 00XXXXXX
JMP 00XXXXXX
[...]
POPAD
Esta es una tipica estructura de un fichero empacado y/ó encriptado. Lo que nosotros estamos buscando es POPAD ya que despues de eso el programa ya esta desempacado. Asi que adelante, a tipear F10 como cerdos hasta encontrarlo (lo que yo os aconsejo es que cuando veais un salto que os lleve hacia arriba introduzcais "G address siguiente al salto" para que no tengais que tragaros todos los bucles que hay). Despues de muchos cuelgues del SICE y de muchos F10 encontramos un POPAD en la dirección 59E4F1. Lo que ahora haremos es S 59E4F1 L FFFFFF 61 (61 = POPAD en hexadecimal) y apretamos F5. Si sales del Sice y entras en el programa ALELUYA!!! la instruccion encontrada es la correcta, en caso contrario, deberas buscar otro POPAD y realizar la misma operacion :-(
Bueno
coninuamos y vemos que despues de varios tipeos de F10
aparece un RET
en 59E501 y
que ese RET
nos lleva a otra dirrecion la cual parece mas normal (499CD4
<-- Anota esta dirección!!!) . Bueno, vamos bien, ahora
debemos volver a ese RET
y tipear: A 59E501
y JMP EIP,
[Esc] y despues F5.
Joe!! ha salido del SICE y no ocurre nada!! Lo que en realidad ha
pasado es que el programa ha sido cargado y desempacado y corrido en
memoria gracias a ese JMP EIP
que genera un bucle infinito que nos ayuda a desempacar el fichero
:-)
Lo
que ahora hacemos es entrar de nuevo en el ProcDump y en la lista
inicial vemos que aparece el path donde teneis instalado el kyodai,
bueno eso es que el programa esta cargado en memoria asi que vamos a
guardarlo, para ello lo seleccionamos con el boton derecho y
seleccionamos "Dump (Full)" poniendo como name "kyo_Mr.exe"
(por ejemplo) una vez guardado lo descargamos de la memoria con la
opcion "Kill". Despues cargamos de nuevo con "PE
Editor" el programa "Kyo_Mr.exe" (el cual esta ya
desempacado) y observamos "Entry Point" e "Image
Size". Lo que ahora debemos hacer es tomar la dirección a
la que nos llevaba el ultimo RET:
499CD4
(recordad que os dije que la apuntarais) y el valor de "Image
Size" y restarlo: 499CD4 - 400000 = 00099CD4. Esta ultima cifra
debemos sutituirla por el "Entry Point" para que el
programa desempacado pueda funcionar ya que si corrieramos el fichero
sin hacer esto cada vez que lo corrieramos se quedaria cargado en
memoria.
----------Detectar el numero de serie----------
Una vez desensamblado el fichero (siempre nos referiremos al desempacado Kyo_Mr.exe) corremos el fichero e introducimos los datos de nuevo:
Nombre: Mr_Burns
Serial: 1234567890
Le damos a "REGISTRAR" y nos aparecera la ventanuca esa de que no estamos registrados. La recordamos. Corremos el Win32Dasm y desensamblamos el Kyo_Mr.exe que es el que esta desempacado. Buscamos en "Reference String" la cadena que tenemos (pero hemos de buscar la cadena en ingles, es decir, "Sorry, wrong password...". Le damos dos veces y aparecemos en 4648BC. Subimos un poco y vemos que hay un salto condicional en 464886, asi que vamonos para alla. Alli observamos que dos lineas mas arriba hay un call, la cual puede que sea la genere la password. Y podemos ver tambien que si no saltase alli nos apareceria otra cadena "Thanks again ! Your are now registered.". Nosotros no vamos a crear el parche sino el keygen por ello entraremos en la call para ver lo que hay... vemos una lista de "nosecuantos" nombres ¿? Que sera eso¿?! Bueno no nos interesa. Lo importante es lo del principio:
*
Referenced by a CALL at Addresses:
|:0046487F , :0048664A ,
:0048C326 , :0048CBDE , :0048D575
|:0048DE10 , :0048E059 ,
:0048E626 , :0048F501 , :00490E32
|:00495149
|
:0047966C
55 push ebp
:0047966D 8BEC mov ebp, esp
:0047966F 6A00 push
00000000
:00479671 53 push ebx
:00479672 56 push esi
:00479673
8BF0 mov esi, eax
:00479675 33C0 xor eax, eax
:00479677 55 push
ebp
:00479678 680F9A4700 push 00479A0F <--
Guarda la lista de nombres que viene mas adelante en el codigo (ni
idea de que es eso)
:0047967D 64FF30
push dword ptr fs:[eax]
:00479680 648920 mov dword ptr fs:[eax],
esp
:00479683 33DB xor ebx, ebx
:00479685 8B864C2B0500 mov eax,
dword ptr [esi+00052B4C] <-- Guarda
en EAX mi nombre: Mr_Burns
:0047968B
E8D4A5F8FF call 00403C64 <-- Calcula
la longitud del nombre y la compara con 8 (creo)
:00479690
85C0 test eax, eax
:00479692 0F8E0C030000 jle 004799A4 <--
Si no posee 8 caracteres salta a error
:00479698
8D4DFC lea ecx, dword ptr [ebp-04]
:0047969B 8B964C2B0500 mov edx,
dword ptr [esi+00052B4C] <-- Guarda
en EDX mi nombre: Mr_Burns
:004796A1
8BC6 mov eax, esi
:004796A3 E860B4FFFF call 00474B08 <--
Genera el serial correcto!!!!!!
:004796A8
8B45FC mov eax, dword ptr [ebp-04] <--
Guarda en EAX el serial correcto!!!!!
:004796AB
8B96502B0500 mov edx, dword ptr [esi+00052B50] <--
Guarda en EDX el serial que yo introduje: 12345
:004796B1
E8BEA6F8FF call 00403D74 <-- Compara
EAX con EDX
:004796B6 0F85E8020000
jne 004799A4 <- Si no son iguales
salta a error
:004796BC 8B864C2B0500
mov eax, dword ptr [esi+00052B4C]
Como podemos comprobar, encontrar el serial correcto es cosa de niños xDDD. Por si os habeis perdido, en 4796A8 esta el serial ccorrecto, lo unico que debeis hacer es d eax y os aparecera el serial. Como esto me resulto demasiado facil quise hacer el KeYgEn ya que descbri la rutina que genera el serial, asi que apor ella:
*
Referenced by a CALL at Address:
|:004796A3
|
:00474B08 55
push ebp
:00474B09 8BEC mov ebp, esp
:00474B0B 83C4F4 add esp,
FFFFFFF4
:00474B0E 53 push ebx
:00474B0F 56 push esi
:00474B10
57 push edi
:00474B11 33DB xor ebx, ebx
:00474B13 895DF4 mov
dword ptr [ebp-0C], ebx
:00474B16 8BF9 mov edi, ecx
:00474B18
8955F8 mov dword ptr [ebp-08], edx
:00474B1B 8945FC mov dword ptr
[ebp-04], eax
:00474B1E 8B45F8 mov eax, dword ptr
[ebp-08]
:00474B21 E8F2F2F8FF call 00403E18
:00474B26 33C0 xor
eax, eax
:00474B28 55 push ebp
:00474B29 68E34B4700 push
00474BE3
:00474B2E 64FF30 push dword ptr fs:[eax]
:00474B31
648920 mov dword ptr fs:[eax], esp
:00474B34 8B45F8 mov eax, dword
ptr [ebp-08]
:00474B37 E828F1F8FF call 00403C64 <--
Todo lo de arriba no es importante para el KeYgEn
:00474B3C
8B55F8 mov edx, dword ptr [ebp-08] <--
EDX = Nombre (Mr_Burns)
:00474B3F
0FB64402FF movzx eax, byte ptr [edx+eax-01] <--
EAX = Ultima letra de nuestro nombre (s)
:00474B44
8B55F8 mov edx, dword ptr [ebp-08] <--
EDX = Nombre
:00474B47 0FB612 movzx
edx, byte ptr [edx] <-- EDX = Primera
letra del nombre (M)
:00474B4A 03C2
add eax, edx <-- EAX + EDX = EAX
:00474B4C
B90A000000 mov ecx, 0000000A <-- ECX
= 10
:00474B51 99 cdq
<-- NPI (Ni Puta Idea!, pero nos da igual nos nos hace
falta)
:00474B52 F7F9 idiv ecx <--
Divide con signo EAX / ECX y el resto queda en EDX
:00474B54
83C230 add edx, 00000030 <-- Añade
a EDX (resto) 30h
:00474B57
8BC7 mov eax, edi
:00474B59 E82EF0F8FF call 00403B8C
:00474B5E
8B45F8 mov eax, dword ptr [ebp-08]
<-- EAX = Nombre
:00474B61
E8FEF0F8FF call 00403C64 <-- Calcula
la longitud del nombre
:00474B66 8BF0
mov esi, eax <-- ESI = La longitud
del nombre (8)
:00474B68 83EE02 sub
esi, 00000002 <-- Le resta 2 (esto es
porque los dos primeros bytes contienen datos de la meoria
reservada)
:00474B6B 7C39 jl 00474BA6
<-- Si es menor salta a
error
:00474B6D 46 inc esi <--
Sino, incrementa ESI
:00474B6E
BB02000000 mov ebx, 00000002 <-- EBX
= 2
* Referenced by a
(U)nconditional or (C)onditional Jump at
Address:
|:00474BA4(C)
|
:00474B73 8B45F8 mov eax, dword ptr
[ebp-08] <-- EAX = Nombre
:00474B76
0FB64418FE movzx eax, byte ptr [eax+ebx-02] <--
EAX = Primera letra del nombre (M)
:00474B7B
8B55F8 mov edx, dword ptr [ebp-08] <--
EDX = Nombre
:00474B7E 0FB6541AFF
movzx edx, byte ptr [edx+ebx-01] <--
EDX = Siguiente letra del nombre (r)
Hagamos
aqui una pausa para indicaros la "inteligencia" del
programador: observad que en 474B6E
EBX = 2 y que en 474B76
a EBX le resta 2. Y despues, en 474B7B
le resta 1. Esto es una autentica estupidez ya que se podia haber
ahorrado tantas molestias poniendo:
474B6E EBX = 0
474B76 movzx eax, byte ptr [eax+ebx]
474B7B movzx edx, byte ptr [edx+ebx+01]
Si esto es un intento de despistar a gente como nosotros, usease, crackers.... SE HA LUCIDO!!!!!!!!! No se como pueden denominarse a si mismos programadores!!!!!!!!!!!
:00474B83
03C2 add eax, edx <-- EAX = EAX + EDX
:00474B85
B90A000000 mov ecx, 0000000A <-- ECX
= 10
:00474B8A 99 cdq <--
NPI
:00474B8B F7F9 idiv ecx <--
Divide con signo EAX / ECX y el resto queda en EDX
:00474B8D
83C230 add edx, 00000030 <-- EDX +
30h
:00474B90
8D45F4 lea eax, dword ptr [ebp-0C]
:00474B93 E8F4EFF8FF call
00403B8C
:00474B98 8B55F4 mov edx, dword ptr [ebp-0C]
:00474B9B
8BC7 mov eax, edi
:00474B9D E8CAF0F8FF call 00403C6C
:00474BA2
43 inc ebx <-- Incrementa EBX en
1
:00474BA3 4E dec esi <--
Y decrementa ESI en 1
:00474BA4 75CD
jne 00474B73 <-- Si son diferentes
salta (BUCLE!)
* Referenced by a
(U)nconditional or (C)onditional Jump at
Address:
|:00474B6B(C)
|
:00474BA6 8B45F8 mov eax, dword ptr
[ebp-08] <-- EAX = Nombre
:00474BA9
E8B6F0F8FF call 00403C64 <-- Calcula
la longitud del nombre
:00474BAE
83F808 cmp eax, 00000008 <-- La
compara con 8
:00474BB1 7D15 jge
00474BC8 <-- Si es mayor o igual
bien
:00474BB3 8BCF mov ecx, edi <--
Sino.... ERROR!!!
:00474BB5 8B45FC
mov eax, dword ptr [ebp-04]
:00474BB8 8B80DC050000 mov eax, dword
ptr [eax+000005DC]
Despues
de haber estudiado la rutina que genera el serial no damos cuenta de
que extremadamente simple!!!! :-D Veamos: El primer byte contiene la
suma de la primera y ultima letras del nombre; y el resto es la suma
de un letra con la siguiente. como os habia dicho extremadamente
simple!!!
Me
gustaria decir que el codigo que hay entre 474B4C-474B54
y 474B85-474B8D
no tiene nada que ver con la generacion del serial. Lo que quiero
decir es que esta parte del codigo, las cuales son iguales, lo unico
que hacen es convertir el resultado de la suma en un numero decimal.
Lo pillais¿? Bueno os lo explicare mas adelante :-)
Ahora
que sabemos como funciona la rutina de generacion del serial,
empezemos el KeYgEn. Yo como el lenguaje que mas controlo es
Ensamblador, lo voy a hacer en este lenguaje, pero no descarteis
hacerlo en cualquier otro, tan solo hace falta un poco de imaginacion
e ingenio :-)
----------Elaborar un KeYgEn en Asm----------
Aqui
os presento el codigo, el cual ire comantando para aquellos que no
esten muy metidos en la materia:
;Kyodai
10.21 KeYgEn
;CoDeD bY Mr Burns
;DaTe: 22-09-2000
.MODEL
SMALL ;Indica que el ejecutable va a ser un COM
.CODE ;Segemnto
del codigo
.386 ;Funcones de 386
ORG 100h ;Desplazamiento
100h=256d respecto al origen del segmento
Start: jmp LetsRock
;Saltamos al codigo, dejamos los datos a un lado
Intro db
10,13,'Kyodai 10.xx KeYgEn CoPYaLL 2000 CoDeD bY Mr Burns',10,13
db
10,13,'eNTeR YouR NaMe: $'
NameOut db 20,0
Name2 db 20
DUP(0)
SerialOut db 10,13,'THe PaSSWoRD iS: '
Pass db 20
DUP(0)
EndPass db 10,13,'$'
TempPass db 20 DUP(0)
TempPassEnd
db 0
NoName db '***eRRoR*** THe NaMe MusT Be MoRe THaN 8 LeTTeRS
:(',10,13, '$'
Pass2 db 20 DUP(0)
SizeName db 0
LetsRock:
mov ah,09h ;Escribe texto por pantalla
lea dx,Intro
int
21h
mov ah,0Ah ;Recoge el Nombre
lea dx,NameOut
int
21h
LongName:
mov al,byte ptr [NameOut+1] ;AL = Long del
Nombre
cmp al,8 ;Lo compara con 8
jge CalculateSerial ;Si es
MAyor o Igual salta
BadName:
mov ah,09h ;Sino hay un
error
lea dx,NoName
int 21h
mov ah,4Ch ;Y sale del
programa
int 21h
CalculateSerial:
xor eax,eax ;Limpia
los registros
xor ebx,ebx
xor ecx,ecx
xor edx,edx
mov
al,byte ptr [NameOut+1] ;AL = Longitud del nombre
mov byte ptr
[SizeName],al ;SizeName = AL
lea esi,Name2 ;ESI apunta al
nombre
lea edi,Pass2 ;EDI apunta al serial
movzx ebx,byte
ptr [SizeName] ;EBX = SizeName = AL X-D
mov al,byte ptr
[esi+ebx-1] ;AL = Ultima letra del nombre
mov cl,byte ptr [esi]
;CL = Primera letra del nombre
add eax,ecx ;Se suman y se guarda
en EAX
mov ecx,0Ah ;ECX = 10
xor edx,edx ;EDX = 0
idiv ecx
;Divide EAX / ECX y el resto queda en EDX
add dl,30h ;A¤ade
al resto 48
mov byte ptr [edi],dl ;Lo mete en la pass
inc edi
;Incrementa el puntero del pass en 1
xor ebx,ebx ;EBX = 0
xor
eax,eax ;EAX = 0
xor edx,edx ;EDX = 0
SecondPart:
mov
al,byte ptr [esi+ebx] ;AL = Primera letra del nombre
mov dl,byte
ptr [esi+ebx+1] ;DL = Segunda letra del nombre
cmp dl,0 ;¨El
nombre se acaba?
je TheEnd ;Si = Escribirlo por pantalla
add
eax,edx ;NO = Se suman y se guarda en EAX
mov ecx,0Ah ;ECX =
10
xor edx,edx ;EDX = 0
idiv ecx ;Divide EAX / ECX y el resto
queda en EDX
add dl,30h ;A¤ade al resto 48
mov byte ptr
[edi+ebx],dl ;Mueve el resto al serial
inc ebx ;Incrementa EBX
jmp
SecondPart ;Salta al comienzo (Bucle)
TheEnd:
mov byte ptr
[edi+ebx-1],0 ;Poner un 0 (binario) al final del serial
lea
esi,Pass2 ;ESI apunta al pass
lea edi,Pass ;EDI apunta donde va a
ir el pass
Serial:
movsb ;Mover de ESI a EDI byte a
byte
cmp byte ptr [esi],00h ;Comparar el pass con 0
jne Serial
;si no lo es continua (Bucle)
Print:
mov ah,09h ;Saca
el Serial por pantalla
lea dx,SerialOut
int 21h
mov
ah,4Ch ;Sale del programa
int 21h
; end Start ;Terminamos
el KeYgEn :)
Pues
eso es todo!!!!! Con esto hemos hecho un sencillo keygen para el
kyoday!!!! xDDDDD
|
|
AGRADECIMIENTOS Y DESPEDIDAS |
|
Bueno, esto hay sido todo. espero que os halla servido de ayuda este tutorial para saber un poquito mas de cracking ;-) Se que este KeYgEn puede ser mejorado, si crees que tu puedes hacerlo mejor... ADELANTE!!!! te animo a que lo hagas mejor y me lo comentes (y no me lo restriegues por la cara :-] )
Me he dado cuanta de el gran tamaño de este tutorial pero creo que en necesario ya que he intentado explicar un poco las causas y el porqué de todos los pasos que he realizado ya que es asi como me gustaria encontrame un tutorial a mi :-)
Como
siempre digo en mis tutoriales, si deseais hablar conmigo buscad en:
|
NiCK |
SeRViDoR |
CaNaL |
|
Mr_Burns |
irc.irc-hispano.org |
CRaCKeRS |
|
[MoRDReD] |
irc.chat.org |
TnTCRaCKeRS & WkT |
O
por el contrario si tan solo deseas mandarme un e-mail:
mr_burns@go.to
http://go.to/mr_burns/ http://mr_burns.go.to/ http://mrburns.da.ru/