


                        -+-| DisidentS Hack Journal #3 |-+-







  _________________________________________________________________________
 |                                                                         |
 |  -- Titulo_____: CrackMes en profundidad.                               |
 |  -- Autor______: SparK.                                                 |
 |  -- E-Mail_____: spark@sparkrisp.com                                    |
 |  -- Team_______: DisidentS Argentina - http://www.disidents.int-ltd.com |
 |  -- KB_________: 69.2                                                   |
 |  -- Tema_______: Cracking                                               |
 |_________________________________________________________________________|


Dumping SparK memory ...... OK
Creating presentation...... OK
Indexing................... OK
Loading modules...sparkillo Ok

[--------------------------------------------------------------------------]
[-----------------Estudiando un CrackMe en profundidad.--------------------]
[------------------------Generacion de una Keygen--------------------------]
[--------------------------------------------------------------------------]
[--------------------------------by SparK----------------------------------]
[----------------DisidentS Hacker Team 2002 3zine Nro 0x011----------------]
[--------------------------------------------------------------------------]





.==========================================================================.
|===========~ INDICE ~======================================================
|===========================================================================
|=~ 001 - Introduccion                                                     |
|=~ 010 - Estudio de la vctima                                            |
|=~ 011 - Tomando apuntes                                                  |
|=~ 100 - Meditacin y contemplacin del C0D3                              |
|=~ 101 - Sacando conclusiones                                             |
|=~ 110 - Escribiendo la Keygen                                            |
|=~ 111 - Conclusion                                                       |
|=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=.
======================================================~ INDICE ~============
============================================================================


Disassembling...... OK

Error overflow!......
Cause : stack overflowing at 0x0454ffff | enough content.memory full.
fixing.................... OK

*--------------------------------------------------------------------------*

Starting.................. OK Welcome!




.==========================================================================.
|===========~ 001 - Introduccion ~==========================================
|===========================================================================


Mmmmm, respiro aire fresco de un  nuevo e-zine, nueva informacin a nuestras
mentes, a nuestros espritus;  esta  info que,  nuestro team les trae, es un
caricia para sus neuronas  cansadas  y agoviadas de tanta propaganda y shows
de colores. Bienvenidos a un humilde artculo en el que veremos mas de cerca
como funciona toda  esa  masa  amorfa  de  codigo  que fluye por los buses y
enredados cables  de  nuestras  PC's  ( y  porque no, de nuestras mentes ;).
Estudiaremos el CrackMe programado por mi como desafio en la e-zine nmero 2
ahora veremos mucho mas de cerca como funciona ,como crackearlo parchendolo
y tambin lo mas interesante hacer  un  keygen para generar llaves correctas
bajo cualquier nombre de usuario  ya  que esa es la funcion principal de las
keygens. Espero que lo disfruten !

===========================================================================*



.==========================================================================.
|===========~ 010 - Estudio de la vctima ~=================================
|===========================================================================

Bueno, como comente en el apartado  anterior la vctima se trata nada mas ni
nada menos que de nuestro querido CrackMe del nmero anterior de esta ezine.

Una de las cosas mas interesantes para  saber de nuestra vctima es, como lo
he comentado antes,  en  que  lenguaje  de  programacion  esta programado el
programa que queremos crackear,  para eso disponemos de algunas herramientas
que nos facilitan el trabajo, aqui se las detallo:

Saleng (SAber LENGuage) :  es un programa escrito en VB, muy facil de usar y
lo pueden encontrar en welcome.to/karpoff.

Language 2000 (recomendado) :  es  un  programa muy completo, puede detectar
lenguages, compresores, encriptadores, y mas cosas. Lo  pueden  encontrar en
http://farrokhi.net/language ,  utiliza   una  pequea  base  de  datos para
reconocer los compresores y lenguajes,  esta base de datos est en constante
actualizacin , y desde la pgina se puede bajar para actualizar.

Si han bajado el language 2000 ,  busquen  el crackme y arrastrenlo hasta el
programa, y language 2000 les dira en que lenguaje esta hecho..... lo vieron
??? si! delphi! delphi 6.0. Ok, ya sabemos en que esta hecho, ahora??? ahora
queda ver de acuerdo en que  lenguaje esta hecho , que herramientas usar, yo
recomiendo usar un  decompilador  exclusivo para programas en delphi, el mas
conocido y til es el DEDE  (DElphi  DEcompiler) , es muy  util en todos los
casos, aunque  he  corroborado  diferencias  en  cuanto  al desensamblado de
programas, y diferencias importantes  en  cuanto al desensamblado en lugares
criticos para un  cracker , como  suelen  ser  los  saltos condicionales y/o
incondicionales, la diferencia  fue  encontrada comparando el mismo c0de con
el W32dasm, como he  comentado  antes  es  un gran desensamblador muy util y
facil de usar. Asi  que  una  opinion  mia  es , si  utilizan DEDE, utilicen
paralelamente W32dasm para el mismo  programa en delphi y corroboren, en que
en lugares puede haber  un  salto  y  con DEDE no lo encuentran, busquen con
W32dasm y si no esta, es que no existe. :)

Abramos el DEDE, y hagamos click en  el  boton con la carpetita, y busquemos
el crackme, ahora hagamos click en  process , y cuando aparece una ventanita
diciendo que hagamos  click   cuando   la  victima  este totalmente cargada,
esperemos a que aparezca  el  crackme  en  la pantalla , listo?, bueno ahora
clickeamos en OK y listo DEDE se encargara del proceso, tan fcil como eso.

Vamos a la seccin "Procedures"  y veremos dos eventos que estan programados
solamente, si solo dos eventos uno es button1click y el otro es edit1keydown.
El primero nos dice que hay codigo  que se ejecuta cuando hay un click en un
botn, ese botn 1, intuyo que puede  ser el boton "Registrar", y el segundo
parece ser que cada  vez  que  presionamos  un  boton  dentro de los editbox
calcula algo o genera alguna accin, yo soy el programador de este crackme y
se que hace, pero no se los dir ;).

===========================================================================*


loading..... Error! cs:ip at 00A4:6391 has an erroneus value.
fixing...... OK :)




.==========================================================================.
|===========~ 011 - Tomando apuntes ~=======================================
|===========================================================================

Perfecto, ahora veremos el codigo fuente entero, lo que contiene cada evento
y luego en el apartado siguiente  explicare  instruccion por instruccion que
hace, y veremos que los RAD's  no  hacen  tantas cosas de mas como se supone
que hacen. ;).

* El evento Click del botn 1 contiene lo siguiente:

004516C8   55                     push    ebp
004516C9   8BEC                   mov     ebp, esp
004516CB   33C9                   xor     ecx, ecx
004516CD   51                     push    ecx
004516CE   51                     push    ecx
004516CF   51                     push    ecx
004516D0   51                     push    ecx
004516D1   51                     push    ecx
004516D2   53                     push    ebx
004516D3   56                     push    esi
004516D4   57                     push    edi
004516D5   8BF0                   mov     esi, eax
004516D7   BF2C3C4500             mov     edi, $00453C2C
004516DC   33C0                   xor     eax, eax
004516DE   55                     push    ebp

* Possible String Reference to: '#_^[]'
|
004516DF   688F184500             push    $0045188F
***** TRY
|
004516E4   64FF30                 push    dword ptr fs:[eax]
004516E7   648920                 mov     fs:[eax], esp
004516EA   8B07                   mov     eax, [edi]
004516EC   8945FC                 mov     [ebp-$04], eax
004516EF   85DB                   test    ebx, ebx
004516F1   0F84F9000000           jz      004517F0
004516F7   8B07                   mov     eax, [edi]
004516F9   B90A000000             mov     ecx, $0000000A
004516FE   99                     cdq
004516FF   F7F9                   idiv    ecx
00451701   8BDA                   mov     ebx, edx
00451703   8B07                   mov     eax, [edi]
00451705   B90A000000             mov     ecx, $0000000A
0045170A   99                     cdq
0045170B   F7F9                   idiv    ecx
0045170D   8907                   mov     [edi], eax
0045170F   85DB                   test    ebx, ebx
00451711   0F84D1000000           jz      004517E8
00451717   8BC3                   mov     eax, ebx
00451719   83F809                 cmp     eax, +$09
0045171C   0F87C6000000           jnbe    004517E8
00451722   FF248529174500         jmp     dword ptr [$451729+eax*4]
00451729   51                     push    ecx
0045172A   17                     pop     ss
0045172B   45                     inc     ebp
0045172C   006317                 add     [ebx+$17], ah
0045172F   45                     inc     ebp
00451730   007217                 add     [edx+$17], dh
00451733   45                     inc     ebp
00451734   008117450090           add     [ecx+$90004517], al
0045173A   17                     pop     ss
0045173B   45                     inc     ebp
0045173C   009F174500AE           add     [edi+$AE004517], bl
00451742   17                     pop     ss
00451743   45                     inc     ebp
00451744   00BD174500CC           add     [ebp+$CC004517], bh
0045174A   17                     pop     ss
0045174B   45                     inc     ebp
0045174C   00DB                   add     bl, bl
0045174E   17                     pop     ss
0045174F   45                     inc     ebp
00451750   008D45F8BAA8           add     [ebp+$A8BAF845], cl
00451756   184500                 sbb     [ebp+$00], al

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
00451759   E86E2DFBFF             call    004044CC
0045175E   E985000000             jmp     004517E8
00451763   8D45F8                 lea     eax, [ebp-$08]
00451766   BAB4184500             mov     edx, $004518B4

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
0045176B   E85C2DFBFF             call    004044CC
00451770   EB76                   jmp     004517E8
00451772   8D45F8                 lea     eax, [ebp-$08]
00451775   BAC0184500             mov     edx, $004518C0

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
0045177A   E84D2DFBFF             call    004044CC
0045177F   EB67                   jmp     004517E8
00451781   8D45F8                 lea     eax, [ebp-$08]
00451784   BACC184500             mov     edx, $004518CC

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
00451789   E83E2DFBFF             call    004044CC
0045178E   EB58                   jmp     004517E8
00451790   8D45F8                 lea     eax, [ebp-$08]
00451793   BAD8184500             mov     edx, $004518D8

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
00451798   E82F2DFBFF             call    004044CC
0045179D   EB49                   jmp     004517E8
0045179F   8D45F8                 lea     eax, [ebp-$08]
004517A2   BAE4184500             mov     edx, $004518E4

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
004517A7   E8202DFBFF             call    004044CC
004517AC   EB3A                   jmp     004517E8
004517AE   8D45F8                 lea     eax, [ebp-$08]
004517B1   BAF0184500             mov     edx, $004518F0

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
004517B6   E8112DFBFF             call    004044CC
004517BB   EB2B                   jmp     004517E8
004517BD   8D45F8                 lea     eax, [ebp-$08]
004517C0   BAFC184500             mov     edx, $004518FC

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
004517C5   E8022DFBFF             call    004044CC
004517CA   EB1C                   jmp     004517E8
004517CC   8D45F8                 lea     eax, [ebp-$08]
004517CF   BA08194500             mov     edx, $00451908

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
004517D4   E8F32CFBFF             call    004044CC
004517D9   EB0D                   jmp     004517E8
004517DB   8D45F8                 lea     eax, [ebp-$08]
004517DE   BA14194500             mov     edx, $00451914

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
004517E3   E8E42CFBFF             call    004044CC
004517E8   85DB                   test    ebx, ebx
004517EA   0F8507FFFFFF           jnz     004516F7
004517F0   8D55F4                 lea     edx, [ebp-$0C]

* Reference to control TForm1.Edit2 : TEdit
|
004517F3   8B86F4020000           mov     eax, [esi+$02F4]

* Reference to: controls.TControl.GetText(TControl):System.String;
|           or: controls.TControl.GetText(TControl):System.String;
|
004517F9   E8F2DCFDFF             call    0042F4F0
004517FE   8B55F4                 mov     edx, [ebp-$0C]
00451801   8B45F8                 mov     eax, [ebp-$08]

* Reference to: system.@LStrCmp;
|           or: system.@LStrCmp;
|
00451804   E8FF2DFBFF             call    00404608
00451809   7543                   jnz     0045184E
0045180B   8D55F0                 lea     edx, [ebp-$10]

* Reference to control TForm1.Edit1 : TEdit
|
0045180E   8B86F0020000           mov     eax, [esi+$02F0]

* Reference to: controls.TControl.GetText(TControl):System.String;
|           or: controls.TControl.GetText(TControl):System.String;	|
00451814   E8D7DCFDFF             call    0042F4F0
00451819   837DF000               cmp     dword ptr [ebp-$10], +$00
0045181D   742F                   jz      0045184E
0045181F   8D55EC                 lea     edx, [ebp-$14]

* Reference to control TForm1.Edit2 : TEdit
|
00451822   8B86F4020000           mov     eax, [esi+$02F4]

* Reference to: controls.TControl.GetText(TControl):System.String;
|           or: controls.TControl.GetText(TControl):System.String;
|
00451828   E8C3DCFDFF             call    0042F4F0
0045182D   837DEC00               cmp     dword ptr [ebp-$14], +$00
00451831   741B                   jz      0045184E
00451833   6A30                   push    $30

* Possible String Reference to: 'Information'
|
00451835   6818194500             push    $00451918

* Possible String Reference to: 'Estas Registrado!!!'
|
0045183A   6824194500             push    $00451924
0045183F   8BC6                   mov     eax, esi

* Reference to: controls.TWinControl.GetHandle(TWinControl):Windows.HWND;
|           or: controls.TWinControl.GetHandle(TWinControl):Windows.HWND;
|
00451841   E81E43FEFF             call    00435B64
00451846   50                     push    eax

* Reference to: user32.MessageBoxA()
|
00451847   E80855FBFF             call    00406D54
0045184C   EB19                   jmp     00451867
0045184E   6A30                   push    $30

* Possible String Reference to: 'Information'
|
00451850   6818194500             push    $00451918

* Possible String Reference to: 'Cdigo Incorrecto!!!'
|
00451855   6838194500             push    $00451938
0045185A   8BC6                   mov     eax, esi

* Reference to: controls.TWinControl.GetHandle(TWinControl):Windows.HWND;
|           or: controls.TWinControl.GetHandle(TWinControl):Windows.HWND;
|
0045185C   E80343FEFF             call    00435B64
00451861   50                     push    eax

* Reference to: user32.MessageBoxA()
|
00451862   E8ED54FBFF             call    00406D54

* Reference to Form1
|
00451867   8B45FC                 mov     eax, [ebp-$04]
0045186A   8907                   mov     [edi], eax
0045186C   33C0                   xor     eax, eax
0045186E   5A                     pop     edx
0045186F   59                     pop     ecx
00451870   59                     pop     ecx
00451871   648910                 mov     fs:[eax], edx

****** FINALLY
|

* Possible String Reference to: '_^[]'
|
00451874   6896184500             push    $00451896
00451879   8D45EC                 lea     eax, [ebp-$14]
0045187C   BA03000000             mov     edx, $00000003

* Reference to: system.@LStrArrayClr;
|
00451881   E8AA29FBFF             call    00404230
00451886   8D45F8                 lea     eax, [ebp-$08]

* Reference to: system.@LStrClr(String);
|
00451889   E87E29FBFF             call    0040420C
0045188E   C3                     ret

0045188F   E9A023FBFF             jmp     00403C34
00451894   EBE3                   jmp     00451879

****** END
|
00451896   5F                     pop     edi
00451897   5E                     pop     esi
00451898   5B                     pop     ebx
00451899   8BE5                   mov     esp, ebp
0045189B   5D                     pop     ebp
0045189C   C3                     ret

Ahora, el evento keydown del o los editbox es:

00451950   55                     push    ebp
00451951   8BEC                   mov     ebp, esp
00451953   66833908               cmp     word ptr [ecx], +$08
00451957   7446                   jz      0045199F
00451959   6683392E               cmp     word ptr [ecx], +$2E
0045195D   7440                   jz      0045199F
0045195F   668B11                 mov     dx, word ptr [ecx]
00451962   6683EA20               sub     dx, +$20
00451966   7409                   jz      00451971
00451968   83C2DF                 add     edx, -$21
0045196B   6683EA1A               sub     dx, +$1A
0045196F   732E                   jnb     0045199F
00451971   0FB701                 movzx   eax, word ptr [ecx]

* Reference to GlobalVar_00453C28
|
00451974   A3283C4500             mov     dword ptr [$453C28], eax
00451979   8B15243C4500           mov     edx, [$453C24]
0045197F   A1283C4500             mov     eax, dword ptr [$453C28]
00451984   8904952C3C4500         mov     [$453C2C+edx*4], eax
0045198B   8B15243C4500           mov     edx, [$453C24]
00451991   01052C3C4500           add     [$453C2C], eax
00451997   FF05243C4500           inc     dword ptr [$453C24]
0045199D   EB65                   jmp     00451A04
0045199F   66833908               cmp     word ptr [ecx], +$08
004519A3   751A                   jnz     004519BF	
004519A5   FF0D243C4500           dec     dword ptr [$453C24]
004519AB   A1243C4500             mov     eax, dword ptr [$453C24]
004519B0   8B04852C3C4500         mov     eax, [$453C2C+eax*4]
004519B7   29052C3C4500           sub     dword ptr [$453C2C], eax
004519BD   EB45                   jmp     00451A04
004519BF   6683392E               cmp     word ptr [ecx], +$2E
004519C3   753F                   jnz     00451A04

* Reference to control Edit1 : TEdit
|
004519C5   8B80F0020000           mov     eax, [eax+$02F0]
004519CB   8B10                   mov     edx, [eax]
* Possible reference to virtual method TEdit.OFFS_00CC
|
004519CD   FF92CC000000           call    dword ptr [edx+$00CC]
004519D3   8B1485303C4500         mov     edx, [$453C30+eax*4]
004519DA   29152C3C4500           sub     dword ptr [$453C2C], edx
004519E0   40                     inc     eax
004519E1   8B15243C4500           mov     edx, [$453C24]
004519E7   2BD0                   sub     edx, eax
004519E9   7C13                   jl      004519FE
004519EB   42                     inc     edx
004519EC   8D0485303C4500         lea     eax, [$453C30+eax*4]
004519F3   8B08                   mov     ecx, [eax]
004519F5   8948FC                 mov     [eax-$04], ecx
004519F8   83C004                 add     eax, +$04
004519FB   4A                     dec     edx
004519FC   75F5                   jnz     004519F3
004519FE   FF0D243C4500           dec     dword ptr [$453C24]
00451A04   5D                     pop     ebp
00451A05   C204                   ret     $04

Ustedes se preguntarn con que fin  pegu este texto aqu?, ok, la respuesta 
es, que a medida que explique como  funciona el crackme , sacare el texto de
aqui e ir  mostrando  que  significa  cada  una  de  las  instrucciones que
componen estos  dos  eventos,  estos  dos  eventos son lo ms importante del 
programa, si aunque no  lo  crean , este  cdigo  es lo que hace que estemos 
registrados o no, fabuloso no? :)

============================================================================







.==========================================================================.
|===========~ 100 - Meditacin y contemplacin del C0D3 ~===================
|===========================================================================


Estamos en la  parte  clave  de   este   artculo  donde  trato  de explicar
bsicamente que hace el crackme.  Dividamos el cdigo en partes para que sea
ms leible y  encontraremos  lo  siguiente  al  principio  de ambos eventos,
aunque no sea exactamente igual, es similar:

	004516C8   55                     push    ebp
	004516C9   8BEC                   mov     ebp, esp
	004516CB   33C9                   xor     ecx, ecx
	004516CD   51                     push    ecx
	004516CE   51                     push    ecx
	004516CF   51                     push    ecx
	004516D0   51                     push    ecx
	004516D1   51                     push    ecx
	004516D2   53                     push    ebx
	004516D3   56                     push    esi
	004516D4   57                     push    edi
	004516D5   8BF0                   mov     esi, eax
	004516D7   BF2C3C4500             mov     edi, $00453C2C
	004516DC   33C0                   xor     eax, eax
	004516DE   55                     push    ebp

 que sugiere esto ? 
Perfecto, antes de nada dar un poco de teoria sobre las llamadas subrutinas
en ensamblador como se manejan,  y  cual  es el sistema para "simular" a una
funcion o a un procedimiento,  tal  cual  como  lo conocemos en lenaguaje de 
alto nivel.

En un lenguaje de alto nivel:


	sentencia1;
	sentencia2;
	sentencia3;
	llamada a procedimiento o funcion(argumentos);
	sentencia4;
	....

Ahora explicare como esto se traduce a ensamblador:

Cuando la PC viene ejecutando las instrucciones (sentencia1, sentencia2,etc)
la ejecucin  es  totalmente  normal  a  una  le  sucede  la siguiente y asi 
sucesivamente, pero cuando se llega a un llamado a proceso o funcin, sucede
algo que en ASM lo llamamos CALL .  Si,  CALL es una instruccin del ASM, se 
usa exactamente para hacer llamadas  a  subrutinas (procesos o funciones), y 
luego cuando un proceso o funcion termina, en pascal se usa un simple END; ,
esto en ASM equivale a un RET (return).

Pero no es tan sencillo como parece, aparentemente cada instruccion tiene su
analoga con una de ASM, pero lo que  vara es la preparacin interna de los
registros que se lleva a cabo para no producir errores ni cuelgues,  porque
se hace esto ?.

Supongamos que tenemos:

MOV ax,1; mueve el valor 1 al registro ax

MOV bx,2; mueve el valor 2 al registro bx

PUSH cx; guardamos el valor que trae cx en la pila \
								   | aqui es lo importante
CALL suma; llamada a subrutina		         /

LEA dx, offset cx ; carga el valor en el offset para mostrarlo en pantalla	   \
                                                                                 | no prestarles atencion
MOV ah,9	; llama a la funcion 9 de la interrupcion 21 (mostrar en pantalla)   |
			                                                               | solo finalizan el ejemplo 
 INT 21h		; ejecuta funcion llamando a la interrupcion			   /

POP cx; liberamos al viejo valor que tenia cx

Como podran ver, antes de llamar a la subrutina guardamos a cx en la pila, y
luego llamamos a la  subrutina , esto  se hace porque dentro de la subrutina
hay lo siguiente:

suma:

ADD ax,bx	; sumamos ax + bx , y el resultado se guarda en ax

MOV cx,ax	; como queremos que la funcin devuelva en cx el
                        ; resultado entonces movemos el valor de ax 
				; en cx
RET		; ahora retornamos al programa principal


bueno, esto funciona de la siguiente forma, como modificamos a cx dentro del
proceso suma, antes de llamar a esta  subrutina, guardamos el valor de cx en
la pila para luego recuperarla y  que  asi el programa pueda seguir su rumbo
correcto, sino hiciramos eso,  el programa seguira con un valor incorrecto
en cx, y si luego cx se usara  para  otra  cosa suponiendo el valor antiguo,
el programa puede llegar a hacer cualquier cosa. Por eso tambin, despus de
la llamada lo recuperamos de la pila.

El secreto de CALL y RET:
-*-*-*-*-*-*-*-*-*-*-*-*	

Mas all de todo esto, el par de instrucciones CALL y RET, hacen otras cosas
a nivel interno en  los  registros  de  la PC. Cuando se realiza un CALL, el 
registro IP ( es  un  registro  que   lleva  la  direccin  de  la siguiente 
instruccion a ejecutar )  modifica  su  valor,  por  el  valor de la primera 
instruccion de la subrutina , y para  que  no se pierda el valor anterior de 
IP, este se guarda en la pila.

Cuando un RET se ejecuta, sucede lo inverso, pero se desperdicia el valor de
IP dentro de la subrutina,  entonces  se saca de la pila el valor antiguo de
IP para seguir su ejecucion  en el programa principal, pero todavia queda un
detalle, en vez de ser el mismo  valor RET hace que el valor que se restaure
en IP sea el valor antiguo  + 1 ,  para  que no ejecute la misma instruccion
otra vez.

Ahora si estamos listos  para  explicar el trozo de cdigo mencionado antes,
pues  que hace esto ? , bueno  esto  lo  que  hace es preservar los valores 
traidos  del  programa  principal   y  guardarlos  en  la  pila , para luego
devolverlos de nuevo, y que el programa principal siga su rumbo correcto con 
los valores correctos. Como podrn ver los eventos no son ms que subrutinas
que en el programa principal se llaman a travs de CALLs. ;)


Ya que hemos aclarado algunas cosas bsicas con respecto al manejo de subru-
tinas en ensamblador, explicare que hace el programa cuando hacemos click en
 "registrar", que chequea para saber si el codigo es el correcto y como res-
ponde a ello, por "si" o por "no", veamos:

* Possible String Reference to: '#_^[]'
|
004516DF   688F184500             push    $0045188F

***** TRY
|
004516E4   64FF30                 push    dword ptr fs:[eax]
004516E7   648920                 mov     fs:[eax], esp
004516EA   8B07                   mov     eax, [edi]
004516EC   8945FC                 mov     [ebp-$04], eax
004516EF   85DB                   test    ebx, ebx
004516F1   0F84F9000000           jz      004517F0       <---- como podrn 
                                                               ver hay che-
                                                               queos
004516F7   8B07                   mov     eax, [edi]
004516F9   B90A000000             mov     ecx, $0000000A
004516FE   99                     cdq
004516FF   F7F9                   idiv    ecx 
00451701   8BDA                   mov     ebx, edx
00451703   8B07                   mov     eax, [edi]
00451705   B90A000000             mov     ecx, $0000000A
0045170A   99                     cdq
0045170B   F7F9                   idiv    ecx 
0045170D   8907                   mov     [edi], eax
0045170F   85DB                   test    ebx, ebx
00451711   0F84D1000000           jz      004517E8        <--- por todas par-
                                                               tes :P
00451717   8BC3                   mov     eax, ebx
00451719   83F809                 cmp     eax, +$09
0045171C   0F87C6000000           jnbe    004517E8       <--- otro mas? aqui
                                                         se pregunta demasiado 
                                                                 ;)

00451722   FF248529174500         jmp     dword ptr [$451729+eax*4]
00451729   51                     push    ecx
0045172A   17                     pop     ss
0045172B   45                     inc     ebp
0045172C   006317                 add     [ebx+$17], ah
0045172F   45                     inc     ebp
00451730   007217                 add     [edx+$17], dh
00451733   45                     inc     ebp
00451734   008117450090           add     [ecx+$90004517], al
0045173A   17                     pop     ss
0045173B   45                     inc     ebp
0045173C   009F174500AE           add     [edi+$AE004517], bl
00451742   17                     pop     ss
00451743   45                     inc     ebp
00451744   00BD174500CC           add     [ebp+$CC004517], bh
0045174A   17                     pop     ss
0045174B   45                     inc     ebp
0045174C   00DB                   add     bl, bl
0045174E   17                     pop     ss
0045174F   45                     inc     ebp
00451750   008D45F8BAA8           add     [ebp+$A8BAF845], cl
00451756   184500                 sbb     [ebp+$00], al

ok, ahora las dems lineas las iremos analizando paso a paso, los saltos son 
3 condicionales y uno incondicional que parece bastante raro su  formato,  o 
no? :)

004516E4   64FF30                 push    dword ptr fs:[eax] <--se guarda en
                                                                la  pila  un
                                                                valor que c-
                                                                ontiene :
                                                                fs:[eax]

004516E7   648920                 mov     fs:[eax], esp    <-- ahora se mueve 
                                                               un valor a 
                                                               fs:[eax]
004516EA   8B07                   mov     eax, [edi]   <--ahora eax contendra
                                                          lo que contiene la 
                                                          direccion contenida 
                                                          por [edi], [edi] s-
                                                          ignifica que el va-
                                                          lor que contiene edi 
                                                          es una  direccion de 
                                                          memoria, es decir el
                                                          programa toma el va-
                                                          lor de edi como dir-
                                                          eccion de memoria p-
                                                          ara acceder  a  otro 
                                                          valor esta contenido 
                                                          en esa direccion  de 
                                                          memoria, el valor de 
                                                          edi es  tomado  como 
                                                          puntero.

004516EC   8945FC                 mov     [ebp-$04], eax   <-- movemos lo  que 
									     contenia    eax   a 
									     ebp-$04

004516EF   85DB                   test    ebx, ebx   <--testeamos ebx con ebx,
									 aqui pregunta si ebx es 

004516F1   0F84F9000000           jz      004517F0   <---- diferente o no a 0,
								      si lo es  salta  a  otro 
									lado.

004516F7   8B07                   mov     eax, [edi] <-- ok, no es distinto de
								     0, seguimos, en ebx, debe
								     haber alguna variable que
								     el programa esta usando .
								     volvemos a  mover  algo a 
								     eax a traves de [edi]

004516F9   B90A000000             mov     ecx, $0000000A <-- ahora movemos $A, 
									   que es esto? es un 10
									   en decimal!

004516FE   99                     cdq<--cdq es una operacion aritmetica, gene-
						 ralmente un IDIV va precedido de  un  CDQ 
						 para dividir EDX:EAX


004516FF   F7F9                   idiv    ecx 
00451701   8BDA                   mov     ebx, edx <-- como ven EDX es copiado
								    a EBX

00451703   8B07                   mov     eax, [edi]<--parece que en [edi] hay 
                                                    otra variable, por lo vis-
								    to la dividiremos,  porque 
								    como ven la moveremos a EAX, 
                                                    y  como IDIV  divide  entre 
                                                    EAX y EDX, pues aqui lo ven
                                                    :) , como movemos a  ECX un 
                                                    $A (10 en decimal),  parece 
                                                    que dividimos por 10 al va-
                                                    lor de EAX.

00451705   B90A000000             mov     ecx, $0000000A 
0045170A   99                     cdq
0045170B   F7F9                   idiv    ecx 
0045170D   8907                   mov     [edi], eax <--una vez  hecho  movemos 
                                                     eax a [edi] nuevamente.
0045170F   85DB                   test    ebx, ebx <-- y c omo  ebx   tenia edx, 
                                                   quiere decir que aqui esta el
 								   resultado,  y  lo  chequeamos 
                                                   para ver si es igual a 0, fa-
                                                   ntastico no? ;)
00451711   0F84D1000000           jz      004517E8<--- saltamos a otro lado   si 
                                                  es as.
00451717   8BC3                   mov     eax, ebx<--- movemos  el  resultado de
                                                  ebx a eax

00451719   83F809                 cmp     eax, +$09<--- y lo comparamos con  $09 
                                                    en hexa que es 9 en decimal!

0045171C   0F87C6000000           jnbe    004517E8<-- [X] si NO es menor o igual 
                                                  saltar, es = ke decir mayor :)

00451722   FF248529174500         jmp     dword ptr [$451729+eax*4]<-- aqui sal-
                                             tamos a algun lado raro, que ahora
 						         explicare :)


 [X] esta es una llamada que hice mientras leiamos el  c0d3,  como  prodrn 
ver aqui pasa algo, el cmp eax,+$09 chequea si eax es igual a 9. significa,
y luego el salto se produce si es mayor a 9, o sea, 10!, que significa, que
 estamos seguramente  y por las expresiones, ante un calculo o una traducc-
in, me refiero de nros enteros a letras.

00451722   FF248529174500         jmp     dword ptr [$451729+eax*4] 

salta como dije antes, a un lugar rarisimo, que  no est bien  desensamblado 
por DeDe. Entonces usemos el lder en desensambladores, el mejor del mundo , 
el IDA, me arrodillo ante l, es el desensamblador ms popular entre los cr-
ackers, testers, y programadores, es una herramienta   realmente potente, ya 
explicar como usarla y porque lo digo, ahora  solamente miremos los resulta-
dos de los dos desensambladores:

DeDe:
	00451729   51                     push    ecx
	0045172A   17                     pop     ss
	0045172B   45                     inc     ebp
	0045172C   006317                 add     [ebx+$17], ah
	0045172F   45                     inc     ebp
	00451730   007217                 add     [edx+$17], dh
	00451733   45                     inc     ebp
	00451734   008117450090           add     [ecx+$90004517], al
	0045173A   17                     pop     ss
	0045173B   45                     inc     ebp
	0045173C   009F174500AE           add     [edi+$AE004517], bl
	00451742   17                     pop     ss
	00451743   45                     inc     ebp
	00451744   00BD174500CC           add     [ebp+$CC004517], bh
	0045174A   17                     pop     ss
	0045174B   45                     inc     ebp
	0045174C   00DB                   add     bl, bl
	0045174E   17                     pop     ss
	0045174F   45                     inc     ebp
	00451750   008D45F8BAA8           add     [ebp+$A8BAF845], cl
	00451756   184500                 sbb     [ebp+$00], al

IDA:
	off_0_451729   dd offset loc_0_451751  ; DATA XREF: sub_0_4516C8+5Ar
	CODE:00451729                 dd offset loc_0_451763  ;jump table for 
								           switch statement
	CODE:00451729                 dd offset loc_0_451772
	CODE:00451729                 dd offset loc_0_451781
	CODE:00451729                 dd offset loc_0_451790
	CODE:00451729                 dd offset loc_0_45179F
	CODE:00451729                 dd offset loc_0_4517AE
	CODE:00451729                 dd offset loc_0_4517BD
	CODE:00451729                 dd offset loc_0_4517CC
	CODE:00451729                 dd offset loc_0_4517DB

creo que la diferencia es bastante grande, DeDe, genera iunstrucciones  y 
usa la pila tambin (POP y PUSH), en cambio IDA,  nos dice  en  que seccin 
del archivo esta el cdigo (CODE), y que puede ser esto!, aqui dice, que es
una tabla usada por un SWITCH, ahora los que tengan idea de programacion en 
BASIC u otro lenguaje parecido, piensen SWITCH, no puede ser.... un.... un.
... CASE!!!! si seor en pascal y/o delphi es usado el CASE, osea que esta-
mos ante, un CASE cuando se hace la conversin se chequea algun valor en lo 
que IDA llama una tabla de valores, que no es ni mas ni menos que una comp-
aracion con valores puestos por el programador.

Si hacemos doble click en IDA en algun dd offset... nos llevara a algo  co-
mo esto: 

(lo siento por los DeDe users no lo vern) ;)

CODE:00451763   lea     eax, [ebp+var_8] ; case 0x1<-- MIREN ESTO!!! case
CODE:00451766   mov     edx, offset dword_0_4518B4<-- cargamos un valor  en 
                                                      edx

CODE:0045176B   call    sub_0_4044CC		   <-- llamada a rutinas... 

CODE:00451770   jmp     short loc_0_4517E8 ; default <-- y saltamos!!

si hacemos doble click en ese jump, en el ltimo, nos vamos a:

CODE:004517E8                 test    ebx, ebx ; default <-- testeamosss...
CODE:004517EA                 jnz     loc_0_4516F7<-- y saltamoss!!! 
                                                  (ya me estoy mareando xD )

y ahora si volvemos ah...

CODE:004516F7                 mov     eax, [edi]
CODE:004516F9                 mov     ecx, 0Ah
CODE:004516FE                 cdq
CODE:004516FF                 idiv    ecx
CODE:00451701                 mov     ebx, edx
CODE:00451703                 mov     eax, [edi]
CODE:00451705                 mov     ecx, 0Ah
CODE:0045170A                 cdq
CODE:0045170B                 idiv    ecx
...			      ...

no nos parece familiar???? piensen... si! es la conversin de nuevo quiere 
decir que todo este embrollo es algo as:

muevo variables
mientras (valor <> 0) hacer
begin
	resultado =valor dividido 10
	resultado = resultado dividido 10
	if (valor es <> 0) then
	begin
		CASE valor of:
			(tabla de valores)
		end;
	end;
end;

aqui por lo que vemos hay 10 valores,  cuales son esos 10 valores?;  pues 
veamos, vamos a la instruccin, que habamos visto antes:

CODE:00451766   mov  edx, offset dword_0_4518B4  <-- cargamos un valor en 
                                                     edx

 que valor cargamos en edx ?
Bien, hagamos doble click en esta parte del texto: offset dword_0_4518B4
ahora IDA nos llevar a:

CODE:004518A8 dword_0_4518A8 dd 30h,0FFFFFFFFh,1;DATA XREF: sub_0_4516C8+8Co
CODE:004518B4 dword_0_4518B4 dd 31h,0FFFFFFFFh,1;DATA XREF: sub_0_4516C8+9Eo
CODE:004518C0 dword_0_4518C0 dd 32h,0FFFFFFFFh,1;DATA XREF: sub_0_4516C8+ADo
CODE:004518CC dword_0_4518CC dd 33h,0FFFFFFFFh,1;DATA XREF: sub_0_4516C8+BCo
CODE:004518D8 dword_0_4518D8 dd 34h,0FFFFFFFFh,1;DATA XREF: sub_0_4516C8+CBo
CODE:004518E4 dword_0_4518E4 dd 35h,0FFFFFFFFh,1;DATA XREF: sub_0_4516C8+DAo
CODE:004518F0 dword_0_4518F0 dd 36h,0FFFFFFFFh,1;DATA XREF: sub_0_4516C8+E9o
CODE:004518FC dword_0_4518FC dd 37h,0FFFFFFFFh,1;DATA XREF: sub_0_4516C8+F8o
CODE:00451908 dword_0_451908 dd 38h,0FFFFFFFFh,1;DATA XREF: sub_0_4516C8+107o
CODE:00451914 dword_0_451914 dd 39h             ;DATA XREF: sub_0_4516C8+116o


esta es la tabla de valores famosa, y los valores son: 30h, 31h....  y  que 
son esos valores, convirtamoslos a decimal por favor....   que obtenemos??? 
pues claro!!!! 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 !!! los 10 valores!!!

Ok, tenemos algo perfecto, un CASE es programado por Delphi en ASM como  un 
bucle de X valores segn la cantidad de valores que  chequemos  dentro  del 
CASE y luego si una condicin se cumple sale del bucle y contina su camino. 
:)

Bien, ahora sabemos que el crackme, hace una conversion de valores, al hac-
er dos divisiones, como vimos antes (CDQ y luego IDIV) vemos algo especial 
en ello:

Por ejemplo:

		100 dividido 10 = 0
		101 dividido 10 = 1
		102 dividido 10 = 2
		103 dividido 10 =  ya se imaginan ? , no? xD

bien, podemos decir que div 10 saca un dgito a un nmero empezando por la 
derecha de ste.

si miramos bien, las dos veces que hacemos el IDIV  anteriormente  movemos
distintos registros, y por lo tanto distintos valores,  porque hacerlo dos
 veces ?

Bueno, una posible explicacin es, si tenemos que chequear por  una  "tabla
de valores" , que no es nada ms ni nada menos que un CASE con valores as:

	CASE valor of:
	     	0:resultado:=resultado+'0';
        	1:resultado:=resultado+'1';
	        2:resultado:=resultado+'2';
	        3:resultado:=resultado+'3';
	        4:resultado:=resultado+'4';
	        5:resultado:=resultado+'5';
	        6:resultado:=resultado+'6';
	        7:resultado:=resultado+'7';
	        8:resultado:=resultado+'8';
	        9:resultado:=resultado+'9';
        end;

Tenemos que una variable depende del dgito que hayamos  "desprendido"  del 
nmero introducido por el usuario, chequearemos en un CASE, y lo sumaremos, 
y as convertiremos un nmero en string.

Ahora, posiblemente los dos IDIV se hagan porque queremos "desprender" un 
dgito, pero no queremos que el nmero continue como antes, sino que saque 
realmente el dgito, y que si antes era 156, ahora sea 15.

Esto se hace asi:

	resultado:= numero mod 10;
	numero := numero div 10;

por eso, es que seguramente en ASM el mod es un IDIV  una  DIVISION  ENTERA 
(Integer DIVision), entonces as haciendo dos divisiones y moviendo los re-
sultados a distintas variables, se obtiene en una de ellas, el nmero orig-
inal con el dgito realmente desprendido, sorprendente no?

Volvamos al IDA y veamos algo:

* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
00451759   E86E2DFBFF  call  004044CC<--- estos son los case's que habamos
0045175E   E985000000  jmp   004517E8<--- visto en el IDA, todos  hacen  lo
							  mismo.	
00451763   8D45F8      lea   eax, [ebp-$08] <--- llaman  al   mismo  lugar, 
                                                   (CALL) y
00451766   BAB4184500  mov   edx, $004518B4 <---saltan al mismo lugar (JMP)
                                                que es la tablita.
	
...
...
10  veces hasta que en la ltima cambia de esta forma:
	
* Reference to: system.@LStrCat;
|           or: system.@LStrCat;
|
004517E3   E8E42CFBFF     call  004044CC
004517E8   85DB           test  ebx, ebx
004517EA   0F8507FFFFFF   jnz   004516F7<---aqu chequeamos si es 0 ebx  o 
						    no, se acuerdan? con lo que  si no 
						    lo es empezamos de nuevo des el p-
						    rincipio con CDQ e IDIV, para ter-
						    minar... :P

0045180B   8D55F0         lea    edx,[ebp-$10]<---cargamos un valor en edx
	
* Reference to control TForm1.Edit1 : TEdit
|
0045180E   8B86F0020000           mov     eax, [esi+$02F0]<--- obtenemos a 
										edit1

* Reference to: controls.TControl.GetText(TControl):System.String;
|           or: controls.TControl.GetText(TControl):System.String;
|
00451814   E8D7DCFDFF     call   0042F4F0<---y sacamos el texto introduci-
							do con llama a API.

00451819   837DF000       cmp   dword ptr [ebp-$10], +$00 <---  chequeamos 
				      				    si es 00, quiere
									    decir, que cheq-
									    ueamos si el co-
									    digo correcto es 
									    distinto de vaco,
                                                          el nro calculado 
									    y el introducido

0045181D   742F           jz      0045184E<--- si no es as, saltamos...sal-
							tamos a esta parte del cdigo	 -\
0045181F   8D55EC         lea     edx, [ebp-$14]			        |
											        |
* Reference to control TForm1.Edit2 : TEdit				        |
|										              |
00451822   8B86F4020000           mov     eax, [esi+$02F4]		        |
											        |
* Reference to: controls.TControl.GetText(TControl):System.String;        |
|           or: controls.TControl.GetText(TControl):System.String;        |
|										              |
00451828   E8C3DCFDFF   call    0042F4F0			                    |
0045182D   837DEC00     cmp     dword ptr [ebp-$14], +$00                 |
00451831   741B         jz      0045184E <---aqu chequeamos otra vez	  |
							si es disntinto de vaco        |
00451833   6A30                   push    $30					  |
											        |
* Possible String Reference to: 'Information'					  |
|										              |
00451835   6818194500             push    $00451918				  |
										              |
* Possible String Reference to: 'Estas Registrado!!!'				  |
	|										        |
0045183A   6824194500       push    $00451924 <---entonces el generado es |
								igual al correcto!!!	  |
	0045183F   8BC6                   mov     eax, esi			  |
											        |


-+-+-+-	Luego de esto se va a la rutina de finalizacin.-+-+-+-
				|
											|
* Reference to: controls.TWinControl.GetHandle(TWinControl):Windows.HWND;|
|           or: controls.TWinControl.GetHandle(TWinControl):Windows.HWND;|
|									|
00451841   E81E43FEFF             call    00435B64	|
00451846   50                     push    eax<-------/  (entonces el nmero es
									   incorrecto)
	
* Reference to: user32.MessageBoxA()
|
00451847   E80855FBFF             call    00406D54
0045184C   EB19                   jmp     00451867
0045184E   6A30                   push    $30

* Possible String Reference to: 'Information'
|
00451850   6818194500             push    $00451918

* Possible String Reference to: 'Cdigo Incorrecto!!!'
|
00451855   6838194500             push    $00451938	<--- aqui en esa direccin se encuentra ese texto.
0045185A   8BC6                   mov     eax, esi

* Reference to: controls.TWinControl.GetHandle(TWinControl):Windows.HWND;
|           or: controls.TWinControl.GetHandle(TWinControl):Windows.HWND;
|
0045185C   E80343FEFF             call    00435B64
00451861   50                     push    eax

* Reference to: user32.MessageBoxA()
|
00451862   E8ED54FBFF             call    00406D54	<--- llamamos a la API messageboxA para el cartelito :)

* Reference to Form1
|
00451867   8B45FC                 mov     eax, [ebp-$04]<---\\
0045186A   8907                   mov     [edi], eax		||
0045186C   33C0                   xor     eax, eax		||
0045186E   5A                     pop     edx			||
0045186F   59                     pop     ecx			||
00451870   59                     pop     ecx			||
00451871   648910                 mov     fs:[eax], edx	||
										||
****** FINALLY								||
|										||RUTINA
										||
* Possible String Reference to: '_^[]'				||
|										||
00451874   6896184500             push    $00451896		||
00451879   8D45EC                 lea     eax, [ebp-$14]	||	
0045187C   BA03000000             mov     edx, $00000003	|| DE 
										|| 		  	
* Reference to: system.@LStrArrayClr;<---borramos contenido ||
                                         de un array? mm... ||
|								            ||
00451881   E8AA29FBFF             call    00404230		||
00451886   8D45F8                 lea     eax, [ebp-$08]	||
								            ||
* Reference to: system.@LStrClr(String);		            ||
|										||FINALIZACIN
00451889   E87E29FBFF             call    0040420C		||
0045188E   C3                     ret				||
									      ||
0045188F   E9A023FBFF             jmp     00403C34		||
00451894   EBE3                   jmp     00451879		||
										||
****** END									||
|										||
00451896   5F                     pop     edi			||
00451897   5E                     pop     esi			||
00451898   5B                     pop     ebx			||
00451899   8BE5                   mov     esp, ebp		||
0045189B   5D                     pop     ebp			||
0045189C   C3                     ret			  <---//


Puff... por fin, hemos terminado, vieron lo que un CASE lleva en lneas de 
ASM?, es totalmente perjudicial para su PC xD. Pero ojo,  hemos  terminado 
una de las dos rutinas... como? si seor, falta la rutina de keydown. :)


Ahora el evento KeyDown, este se genera cada vez, que una tecla es presiona
da dentro de un EditBox, y empieza as:

00451950   55              push    ebp
00451951   8BEC            mov     ebp, esp
00451953   66833908        cmp     word ptr [ecx], +$08 <-- comparamos   si 
                                            lo que contiene la direccion de 
                                            ecx	es un 8 hex, o sea 8 en dec, 
                                            o sea una H en ASCII
00451957   7446            jz      0045199F <-- si no es asi, saltamos y va-
                                            mos pa otro lao
00451959   6683392E        cmp     word ptr [ecx], +$2E <-- ahora comparamos 
                                  con 2e, que es?, un 46 en dec, y 46 en dec
	                            que es?, la letra n en ASCII
0045195D   7440            jz      0045199F<--si no es asi, saltamos y vamos 
                                           pa otro lao
0045195F   668B11          mov     dx, word ptr [ecx]  <-- muve un dato a dx
00451962   6683EA20        sub     dx, +$20            <--resta 20 en hex, y
                                                       que es?, un 32 en dec
00451966   7409            jz      00451971	<-- si la resta fue correcta, 
                                                saltamos
00451968   83C2DF          add     edx, -$21	<-- sumamos en edx 21 en hex
0045196B   6683EA1A        sub     dx, +$1A	<--    restamos  1a  en  hex
0045196F   732E            jnb     0045199F	<--   jnb (jump if not below)
00451971   0FB701          movzx   eax, word ptr [ecx]<-- movemos un valor a 
                                             eax, (en IDA este es el comienzo 
                                             de una subrutina, pero....)

* Reference to GlobalVar_00453C28
|
00451974   A3283C4500      mov     dword ptr [$453C28], eax <-- movemos  eax, 
                                     a un lugar de la memoria, con un puntero
00451979   8B15243C4500    mov     edx, [$453C24]	<-- ahora movemos a edx
0045197F   A1283C4500      mov     eax, dword ptr [$453C28]<-- ahora  a   eax
00451984   8904952C3C4500  mov     [$453C2C+edx*4], eax <-- again and again :)
0045198B   8B15243C4500    mov     edx, [$453C24]<-- y ahora a edx volvemos a 
                                                 mover
00451991   01052C3C4500    add     [$453C2C], eax<-- y  esto   me   suena   a 
                                             valor:=valor+valor2; posiblemente 
                                             los mov's sean movimientos de va-
                                             lores entre array's...
00451997   FF05243C4500    inc     dword ptr [$453C24]<-- esto es un incremen-
                                                     to de una variable en  1,
                                                     tipo as: valor:=valor+1;
0045199D   EB65            jmp     00451A04 <-- saltamos, y esto creo  que  va
                                                al final    de    la subrutina

0045199F   66833908        cmp     word ptr [ecx], +$08<-- volvemos a chequear
                                                           si es un 08 en hexa
004519A3   751A            jnz     004519BF<-- si NO es igual entonces nos va-
                                               mos:)

004519A5   FF0D243C4500    dec     dword ptr [$453C24]<--  decrementamos   una 
                                                      variable en 1
004519AB   A1243C4500      mov     eax, dword ptr [$453C24] <-- movimientos.... 
                                                   como dije antes posiblemente
004519B0   8B04852C3C4500  mov     eax, [$453C2C+eax*4]<-- sean movimientos en-
                                                   tre arreglos...
004519B7   29052C3C4500    sub     dword ptr [$453C2C], eax <--   y  finalmente 
                                                    vemos que realiza una resta
004519BD   EB45            jmp     00451A04<--   va   al  final de la subrutina

004519BF   6683392E        cmp     word ptr [ecx], +$2E<--    si no era  08  el 
                                                          caracter,  viene aca, 
                                                          y pregunta  si  es  o 
004519C3   753F            jnz     00451A04<----------    o no 46 en  de, si no 
                                                          lo es, salta  al  fi-
                                                          nal  donde termina el 
                                                          proceso.

* Reference to control Edit1 : TEdit
|
004519C5   8B80F0020000    mov     eax, [eax+$02F0]  <-- obtiene al editbox
004519CB   8B10            mov     edx, [eax]		

* Possible reference to virtual method TEdit.OFFS_00CC
|
004519CD   FF92CC000000   call    dword ptr [edx+$00CC] <--   esto  pertenece 
                                                         a un metodo, segura-
                                                         mente en Delphi esto
                                                         es,  editbox.METODO.
004519D3   8B1485303C4500 mov     edx, [$453C30+eax*4]
004519DA   29152C3C4500   sub     dword ptr [$453C2C], edx
004519E0   40             inc     eax      <-- incrementa una variable en 1
004519E1   8B15243C4500   mov     edx, [$453C24]   <--\
004519E7   2BD0           sub     edx, eax	      |
004519E9   7C13           jl      004519FE            |
004519EB   42             inc     edx		      |
004519EC   8D0485303C4500 lea     eax, [$453C30+eax*4]| Esta parte la  exp-
004519F3   8B08           mov     ecx, [eax]		| lico mas abajo...		
004519F5   8948FC         mov     [eax-$04], ecx	|
004519F8   83C004         add     eax, +$04		|
004519FB   4A             dec     edx			|
004519FC   75F5           jnz     004519F3         <--/
004519FE   FF0D243C4500   dec     dword ptr [$453C24]		
00451A04   5D             pop     ebp				
00451A05   C204           ret     $04				

Bueno, explicar esa parte que dije, eso es claro que hay un bucle, que mie
ntras no se cumpla una condicion se repite, si seguimos el hilo de la ruti-
na veremos lo siguiente:

* mueve un dato a edx

* luego lo resta con eax, y obtiene un valor

* si es MENOR entonces salta abajo y termina la rutina ( luego  haremos un 
  Zen cracking con respecto a esto)

* sino lo es entonces incremento una variable en 1, y movemos algunos valo-
  res, seguramente ese 	[$453C30+eax*4] sea un arreglo, y entonces mueve v-
  alores de variables a arreglos.

* luego decrementa una variable, esta variable parece ser, la que antes ch-
  equeo por si era menor que eax (el jl de 4519e9)

* si NO es cero, vuelve a repetir la rutina, hasta que lo sea, y en ese ca-
  so termina la rutina, que pertenece al evento,keydown.

Como podemos ver, esto es un FOR, fijense  la anatomia  de un FOR,  esto es 
asombroso, hasta yo me asombro :))

for i:=1 to tope  do  _
.....\->mov     inc     eax ,  edx, [$453C24] , sub  edx, eax , jl 004519FE

eso es el FOR, en este ejemplo incrementa eax, que es donde esta el 1 al p-
rincipio (i:=1) y luego mueve a edx el valor de la variable tope,  y  luego 
hace una resta entre los dos, entonces si hay diferencia quiere  decir  que 
eax sigue siendo menor que edx y luego sigue con la rutina del FOR, sino t-
ermina, el salto JL genera la repeticin del FOR, el bucle.

Ahora har una analoga, de cdigo ASM a cdigo de ALTO NIVEL, como DELPHI,
C o algn otro:	

	
IF (cmp word ptr [ecx], +$08) AND (cmp word ptr [ecx], +$2E) AND (mov dx,__
                                      __word ptr [ecx] , sub dx, +$20) THEN

BEGIN

movzx   eax, word ptr [ecx]   
mov     dword ptr [$453C28], eax 
mov     edx, [$453C24]
mov     eax, dword ptr [$453C28]
mov     [$453C2C+edx*4], eax
mov     edx, [$453C24]	  
add     [$453C2C], eax	   
inc     dword ptr [$453C24]

end							

ELSE

IF (cmp     word ptr [ecx], +$08) THEN

BEGIN

dec     dword ptr [$453C24]
mov     eax, dword ptr [$453C24]
mov     eax, [$453C2C+eax*4]    
sub     dword ptr [$453C2C], eax

END

ELSE

IF (cmp     word ptr [ecx], +$2E) THEN

BEGIN

mov     edx, [$453C30+eax*4]
sub     dword ptr [$453C2C], edx
inc     eax	

FOR edx TO eax DO
BEGIN
lea     eax, [$453C30+eax*4]	
mov     ecx, [eax]
mov     [eax-$04], ecx		
add     eax, +$04		
END;
dec     edx			
END;

dec     dword ptr [$453C24]		

END;


Ah vemos que hace exactamente el C0d3, y como esta organizado  dentro  del 
crackme e inclusive como se desensambla y como, debemos estructurar nuestra 
mente al leerlo.





.==========================================================================.
|===========~ 101 - Sacando conclusiones ~==================================
|===========================================================================


Hemos visto la parte mas importante del c0d3, el click del botn  registrar
y el editbox, tenemos que, ordenarnos y pensar en hacer la keygen o por  lo
menos un pseudocdigo que incite a hacerla. Vemos que, cada vez que presio-
namos una tecla en la edit box, se va ejecutando una rutina que  genera  el
cdigo correcto, y luego lo que hace es compararlo con el introducido, y de
ah saca el mensaje de correcto! o incorrecto!.Lo importante es haber ente-
ndido la generacin del cdigo, por lo visto hasta ahora, el cdigo se gen-
era, sacando el valor ASCII de cada letra que presionamos, y  luego  las va
sumando, formando una cifra, que luego cuando termina ese  proceso,  genera
el nmero de serie vlido.





.==========================================================================.
|===========~ 110 - Escribiendo la Keygen ~=================================
|===========================================================================


Muy bien, el proceso  de  creacin   de  una  keygen  en base a un programa,
keygenme, crackme o cualquier cosa que ofrezca resistencia, se puede dividir
 en dos formas, en dos caminos, como todo en el cracking, como es la vida, y
 el ser humano, como es el CAMINO, todo camino....


Las formas que explicar dependen  de  como est implementada la proteccin,
pero bsicamente tocare dos caminos  y algunas variaciones que ya veremos en
ms detalles.

Primero empezar por el ms fcil , resulta que tenemos un programa que esta
protegido para registrarse , y que nos permite ingresar el nombre de usuario
y el nro de serie, bien,  como  podemos  intuir, para saber si se ingres el
nmero de serie vlido el programa debe chequear con el nmero vlido. Salvo
 que nuestro programa quee estemos analizando tenga un solo serial, cosa que
es algo que no suele suceder porque  cada usuario que se registra debe tener
un  serial  diferente   porque   sino   conseguiran  el  programa  completo
introduciendo el mismo serial, que es el  mismo de todos; eso no es factible
como podran ver. Entonces  la  conclusin  es, por cada usuario un nmero de
serie distinto, ahora, como  consigue  el  programa esos nmeros de serie??,
tiene una base de  datos  de  5000  terabytes??? , NO!!!! , los genera en el
instante , si , cuando ingresas  el  nombre de usuario , genera el nmero de
serie correspondiente para ese usuario, y lo testea luego con el introducido
por supuesto, el que el program genera no se muestra, sino sabras el nmero
que te corresponde. ;)

Una de las  tcnicas  del  cracking  es  SERIAL  FISHING , y  esto es pescar
justamente el serial, en  el  momento  en  que  se crea, esto se hace con un
debugger, poniendo un breakpoint ( punto de ruptura ) y en ese momento, leer
el cdigo hasta encontrar en que parte  de la memoria se almacen el serial,
entonces, ya tenemos el serial vlido para el nombre de usuario introducido,
fcil no?; pero eso no  tiene  nada  que  ver con las keygens, ese es mtodo
fcil, y limitado al nombre de  usuario  de  ese momento, lo que es muy pero
muy til, es generar un programa que  genere esos nmeros de serie, segn el
nombre de usuario, y la forma fcil de  hacerlo, es encontrando la rutina de
generacin del cdigo y luego simplemente copiando toda la rutina de clculo
(algunas suelen ser muy tontas), modificarla , para que se pueda compilar, y
listo!, keygen.

O sea, sabiendo donde  esta  la  rutina, pero  no estudiando la ecuacin que
calcula el serial, ya podemos hacer el keygen con unas pocas modificaciones,
agregndole etiquetas, variables mas leibles que las direcciones de memoria,
etc. Generalmente se generan en win32asm , es un lenguaje perfecto para este
tipo de cosas, fcil de  implementar  (casi como el visual c++) no necesitas
traducir la rutina del  programa  a  otro lenguaje de alto nivel, con lo que
conlleva el  entendimiento  de  patrones de cdigo y dems, y encima de todo
eso, genera cdigo ultra rpido y optimizado.

Las rutinas de generacion  de  codigo  pueden  ser muy variadas, tenemos las
otra gran variante, las famosa s rutinas  en  las que debes hacer el clculo
inverso para poder generar  el  cdigo  correcto, porque es asi?, justamente
porque muchas veces sacan un valor  inicial y luego hace clculos en los que
se incluyen el nombre de  usuario  o  solo algunas letras de l, luego hasta
pueden contener patrones  de  caracteres  como por ejemplo por decir algo al
azar: #$&"%/EGRTH$%B$%BYW%BWR ,  y  luego  de ahi sacar una suma de todos, o
algunos al azar... como ven se  pueden  hacer las cosas mas paranoicas, pero
sabiendo que hace el c0d3 y  entender  bien ASM se puede siempre comprender,
 llevar mas o menos tiempo ,  mas  o  menos  esfuerzo, todo eso depende del
reverser (nosotros!!! :)) tanto como de la rutina a analizar.

El segundo camino es la forma de hacer  el  camino inverso al clculo que se
realiza, por ejemplo:


for i:=1 to 10 do
	repetir:=repetir + llave[i]*255 + 5 div 2;

en ensamblador esto seria de la siguiente manera:


		mov ecx, 10
denuevo:
		mov ebx,llave[ecx]
		mov edx, 255
		idiv ebx, edx
		sub ebx, 5
		imul ebx, 2
		add eax,ebx
		dec ecx
		cmp ecx, 10
		je denuevo

Expliquemos esto, ecx es un contador, hago un bucle de 10 iteraciones, ebx ,
contendra por cada  iteracin  un  numero  de  la llave que es una llave que
introdujo el usuario,  esta  llave  es  un  numero , y luego el usuario debe
introducir un nro de serie, para registrarse tambien, pero aqui sera de esta
forma, la llave la  calculamos  usando  un  sentido  inverso, el original lo
programe en pascal, y el "keygen" en ASM, mas abajo, es solamente un ejemplo
facil, el nro de serie lo situo en  ebx , y tomo de la llave un nro dado por
el indice , en este caso ecx,  luego  hago  la inversa de la multiplicacion,
que hice en pascal , simplemente  lo invierto , divido , resto, y por ultimo
multiplico. :)

Estas estrategias de "kaygenear" un programa, depende de la proteccin como,
dije antes.

A lo nuestro:

Yo, aqu no har  el  cdigo  compilable  ni  con  masm , ni nasm, ni ningn
compilador, porque podra  llevar  mas  tiempo para debugearlo y demas, solo
expondr el c0d3 una vez ms y con  etiquetas, un poco mas "civilizado" para
darle el ltimo vistazo y concluir mi estudio de hoy. :)



.code

notermino:

	mov     eax, [nrodeserie]
	mov     ecx, A
	cdq
	idiv    ecx
	mov     ebx, edx
	mov     eax, [nrodeserie]
	mov     ecx, A
	cdq
	idiv    ecx
	mov     [nrodeserie], eax
	test    ebx, ebx
	jz      termino
	mov     eax, ebx
	cmp     eax, 09
	jnbe    error1 (error1 diria que el editbox deberia contener nros)

CODE:004518A8 dword_0_4518A8  dd 30h, 0FFFFFFFFh, 1   ; DATA XREF: sub_0_4516C8+8Co
CODE:004518B4 dword_0_4518B4  dd 31h, 0FFFFFFFFh, 1   ; DATA XREF: sub_0_4516C8+9Eo
CODE:004518C0 dword_0_4518C0  dd 32h, 0FFFFFFFFh, 1   ; DATA XREF: sub_0_4516C8+ADo
CODE:004518CC dword_0_4518CC  dd 33h, 0FFFFFFFFh, 1   ; DATA XREF: sub_0_4516C8+BCo
CODE:004518D8 dword_0_4518D8  dd 34h, 0FFFFFFFFh, 1   ; DATA XREF: sub_0_4516C8+CBo
CODE:004518E4 dword_0_4518E4  dd 35h, 0FFFFFFFFh, 1   ; DATA XREF: sub_0_4516C8+DAo
CODE:004518F0 dword_0_4518F0  dd 36h, 0FFFFFFFFh, 1   ; DATA XREF: sub_0_4516C8+E9o
CODE:004518FC dword_0_4518FC  dd 37h, 0FFFFFFFFh, 1   ; DATA XREF: sub_0_4516C8+F8o
CODE:00451908 dword_0_451908  dd 38h, 0FFFFFFFFh, 1   ; DATA XREF: sub_0_4516C8+107o
CODE:00451914 dword_0_451914  dd 39h                  ; DATA XREF: sub_0_4516C8+116o

	call    004044CC   (obtiene texto, no viene al caso explicarlo ahora)
	jmp     repetir
	lea     eax, [nrodeserie]
	mov     edx, $004518B4

	call    004044CC
	jmp     repetir
	lea     eax, [nrodeserie]
	mov     edx, $004518C0

	call    004044CC
	jmp     repetir
	lea     eax, [nrodeserie]
	mov     edx, $004518CC

	call    004044CC
	jmp     repetir
	lea     eax, [nrodeserie]
	mov     edx, $004518D8

	call    004044CC
	jmp     repetir
	lea     eax, [nrodeserie]
	mov     edx, $004518E4

	call    004044CC
	jmp     repetir
	lea     eax, [nrodeserie]
	mov     edx, $004518F0

	call    004044CC
	jmp     repetir
	lea     eax, [nrodeserie]
	mov     edx, $004518FC

	call    004044CC
	jmp     repetir
	lea     eax, [nrodeserie]
	mov     edx, $00451908

	call    004044CC
	jmp     repetir
	lea     eax, [nrodeserie]
	mov     edx, $00451914

	call    004044CC

repitir:
	test    ebx, ebx
	jnz     notermino



termino:

	test 	ebx,ebx
	jnz     notermino

	cmp     word ptr [ecx], 08
	jz      vemossies08
	cmp     word ptr [ecx], 2E
	jz      vemossies08
	mov     dx, word ptr [ecx]
	sub     dx, 20
	jz      chequeoporotro
	add     edx, -21
	sub     dx, 1A
	jnb     vemossies08
chequeoporotro:

	movzx   eax, word ptr [ecx]
	mov     dword ptr [$453C28], eax
	mov     edx, [$453C24]
	mov     eax, dword ptr [$453C28]
	mov     [$453C2C+edx*4], eax
	mov     edx, [$453C24]
	add     [$453C2C], eax
	inc     dword ptr [$453C24]
	jmp     salir

vemossies08:

	cmp     word ptr [ecx], 08
	jnz     004519BF
	dec     dword ptr [$453C24]
	mov     eax, dword ptr [$453C24]
	mov     eax, [$453C2C+eax*4]
	sub     dword ptr [$453C2C], eax
	jmp     salir
	cmp     word ptr [ecx], +$2E
	jnz     salir
	
	
	mov     eax, [eax+$02F0]
	mov     edx, [eax]
	
	call    dword ptr [edx+$00CC]
	mov     edx, [$453C30+eax*4]
	sub     dword ptr [$453C2C], edx
	inc     eax
	mov     edx, [$453C24]
	sub     edx, eax
	jl      salgosinocumple
	inc     edx
	lea     eax, [$453C30+eax*4]

asignacion:

	mov     ecx, [eax]
	mov     [eax-04], ecx
	add     eax, 04
	dec     edx
	jnz     asignacion

salgosinocumple:

	dec     dword ptr [$453C24]

salir:

	ret     $04

end.

Esta es una aproximacin del keygen que se podra programar para este 
crackme que he programado como desafo.





.==========================================================================.
|===========~ 111 - Conclusin ~============================================
|===========================================================================


Bueno, espero que les haya servido bastante, creo que es de suma importancia
para poder  entender  como  se  codifica  un  programa  programado (valga la
redundancia) en Delphi, uno de  los  lenguajes mas potentes del mundo. Hemos
visto tambin diferencias  de  desensamblado  entre desensambladores famosos
como el DeDe y el invencible IDA; pero  no dejamos de mirar el aspecto de la
ingeniera inversa los cuales mis  artculos van dedicados mayormente a este
tema. Tambin pasamos por la  programacin en general, lgica de condiciones
y estructuras de datos, como se manejan internamente y demas cosillas.


Espero que les haya gustado y...

					Hasta la prxima!!!

					                S-p-a-r-K

					                Cr@c|<!ng S3ct!0n

============================================================================

							EOF
shutting down...... OK!
Power Down......... OK!



