tr [eax+4] )) con (( 74 )) 
La sexta comparación es: (( byte ptr [eax+5] )) con (( 68 )) 
La séptima comparación es: (( byte ptr [eax+6] )) con (( 69 )) 
La octava comparación es: (( byte ptr [eax+7] )) con (( 73 )) 

Entoces el password correcto es: 

68( h ) 61( a ) 63( c ) 6b( k ) 74(x) 68(x) 69(x) 73(x) 

x = hazlo tu mismo :) 

ok, ya está hecho todo el trabajo... como puedes ver ha sido realmente fácil conseguir el password correcto... solo hemos necesitado analizar un poco el 
código. 

Ahora vamos a jugar un poco... conseguir solo el password no es suficiente para nuestras retorcidas cabezas :). 

Jugando con el Código 1ªParte  
INTRODUCIR CUALQUIER PASSWORD  

hmm, ¿porqúe tenemos que poner siempre el password para entrar al menú? ahora podemos jugar con el código y hacer que acepte cualquier password... es 
facilito, ya lo verás. 

Observa que el checkeo de longitud de password o cada checkeo de los caractéres tiene un JNE , dirigido hacia el offset 0040348C . 
Esto hace que si el password no es correcto, se nos salta el offset 00403485 y por lo tanto no se cumple la instrucción, que debería mover 1 ( mov ) a 
la posición [ esi+60 ]. 

Este 1 le dice al programa en un posterior checkeo (que no hace falta ni buscar) si hemos introducido el password correcto. 

:00403483 7507            jne 
0040348C

:
00403485
 C7466001000000  mov [esi+60], 00000001

:
0040348C
 8BCE            mov ecx, esi

¿Como podemos arreglar esto?... si, hay varios métodos... 

Cambiar todas las instrucciones JNE por NOP (nop=instrucción que no hace nada). 
Esta es una forma muy sucia... demasiados bytes parcheados... funcionará, pero yo creo que cuantos menos bytes parcheados mejor es el crack. 

Hacer al código saltar directamente a 00403485 (la intrucción que pone 1 en [esi+60]) 
Esta es una forma más limpia... solo 2 bytes serán cambiados. 

Ok, entonces cambiaremos el primer JNE (el del checkeo de longitud) a un JMP (el JMP hace que salte siempre... ya no es una condición) a donde queremos. 

Original: 00403454 7536    jne 0040348C

Primero haz los cambios en el SoftIce (antes de hacer una modificación real en el fichero) para probar si todo va bien. 

Para hacer el cambio, vete a ese offset (comienza el proceso usando F10 para llegar allí). 
Cuando ya estes situado en el offset q queremos, escribe: a 

Ahora puedes editar ese offset... escribe la nueva instrucción: jmp 403485 y pulsa enter. 

Parcheado:  00403459 EB2F    jmp 00403485

Los bytes han sidos cambiados (en memoria), después de haber hecho esto, desactiva todos los breakpoints ( bd* ) y continua la ejecución normal,.. 

whouuu!!!!, funciona perfectamente :), ahora s2k acepta cualquier cosa q pongamos, incluso una password en blanco. 

Haré una explicación cortita de como parchear el ejecutable permanentemente... 
Coje un buen editor hexadecimal como por ejemplo hiew (dos) o ultraedit (windows), vete al offset donde esta la instrucción que queremos cambiar y 
modifica sus bytes. 
Estos son los bytes originales: 75 36 | Y estos los cambiados: EB 2F 
(La traducción a hexadecimal la obtienes en el softice) 
Para ir a la localización exacta, utiliza un conversor de offset/hex. 

Jugando con el Código 2ªParte  
DIRECTAMENTE AL MENÚ  

Bueno Bueno... :)... esto cada vez se pone más interesante. 

Ya hemos conseguido el password, hemos hecho que acepte cualquier cosa que metamos... que nos falta? 
aha, la perfección :)... y para que queremos que nos salga ese menú de meter el password si aceptará cualquier cosa?, ahora vamos a hacer que 
directamente cuando le demos a la opción en la barra de menú se salte el rollo ese de meter el password y nos abra directamente la ventana con las 
opciones de 'administrador'. 

Ya has visto lo facil que es trabajar con el código y modificarle sabiendo que es lo que hace. 
Ahora tampoco se va a complicar mucho más, pq solo tenemos que hacer una busqueda y unos pequeños cambios teniendo en cuenta todos los conocimientos que 
hemos adquirido sobre este programa anteriormente. 

Ok, vamos al atakeerrrr! 

Organización... 

1er Paso : Buscar llamada al Menu 'Administration Tools' 

2º Paso : Hacer que se salte el menu ese del password y que vaya directamente a donde queremos, teniendo en cuenta q la llamada que se hace al menu del 
password devuelve una respuesta como ya sabemos (recordad el mov 1 a esi+60). 

3er Paso : Hacer permanentes nuestros cambios en el ejecutable e irnos por hay a dar una vuelta con la novia (eso solo si teneís la suerte de tener una 
:))). 

Comenzamos, 
Como lo que buscamos es la creación de un menú, lo mejor para encontrar quien o que llama a este menú será desensamblar el ejecutable con el W32DSM. 
Hacemos una copia del ejecutable y la desensamblamos... ningún problema para hacerlo... ni Antiw32dsm, ni encriptaciones, ni compresores... nada... joer 
q rollo :) 

También podriamos hacerlo con SoftIce, pero mejor usamos W32DSM para q resulte más facil y veamos como atacar a la victima con distintas aplicaciones. 

Pues para buscar el menú que nos interesa no tenemos más que mirar en el DIALOG INFORMATION que está al principio de la 'dead list': 

Name: DialogID_0092, # of Controls=004, Caption:
"Password Verification
", ClassName:
""
001 - ControlID:0406, Control Class:
"EDIT
" Control Text:
"" 
002 - ControlID:0001, Control Class:
"BUTTON
" Control Text:
" & 
Ok
" 
003 - ControlID:0002, Control Class:
"BUTTON
" Control Text:
"
 & 
Cancel
" 
004 - ControlID:FFFF, Control Class:
"STATIC
" Control Text:
"Enter Admin. Password:
" 

Aquí lo tenemos... 
El dato más importante es el de ' DialogID_0092 ', que nos servirá para encontrar cuando es llamado este menú. 

Damos a Search , Find Text, y ponemos 'DialogID_0092'... ploff... hay está :) 

* Possible Reference to Dialog: DialogID_0092

Ahora solo tenemos que subir para arriba y observar quien hace referencia a esta llamada... bueno ya lo sabemos (el click al menú de arriba)... pero lo 
que queremos saber realmente es donde ocurre esto. 

Pues subimos unas cuantas líneas y hay está!. 

* Referenced by a CALL at Address:
|:00402974

Jeje, una CALL ha llamado aquí... exactamente ha sido la localizada en el OffSet 00402974 ... ya tenemos a nuestra victima rodeada, bueno vamos allí a 
ver q encontramos. 

:00402974 E837090000              call 004032B0
:00402979 8D8C24A4000000          lea ecx, dword ptr [esp+000000A4]
:00402980 C784249401000000000000  mov dword ptr [esp+00000194], 00000000

* Reference To: MFC42.Ordinal:09D2, Ord:09D2h
                                  |
:0040298B E8E8D80000              Call 00410278
:00402990 83F801                  cmp eax, 00000001
:00402993 7571                    jne 00402A06
:00402995 8B842404010000          mov eax, dword ptr [esp+00000104]
:0040299C 6A00                    push 00000000
:0040299E 85C0                    test eax, eax
:004029A0 7452                    je 004029F4

hmm, interesante... 

A mi ya se me ocurre una idea de que hace aquí el programa... pero mejor vamos directamente a SoftIce a verlo en tiempo de ejecución. 

Para esto hay q poner un Breakpoint en el offset 402974 , ah, ahora recuerdo que esto suele causar problemas a muchos newbies. 
Voy a explicar como poner correctamente el Breakpoint para evitar mensajes como 'Invalid Address' o que no funcione. 

SoftIce necesita que le demos una referencia de que app debe ser la actuada mediante el breakpoint. Para esto usaremos el Symbol Loader , aplicación 
incluida con SoftIce que tendrás en tu carpeta de Numega SoftIce. 

Ok, abrimos el symbol loader, y en File/Open Module abrimos el ejecutable del Serials 2000 . 

C:\Program Files\ Serials 2000 \Serial2k.exe - loaded successfully 

Bueno, ahora para ejecutarle no tenemos mas que dar en Module/Load o el icono de los engranajes. 
Nos saldrá un error sin importacia, le damos ok, y sigue la ejecución del Serials 2k. 

Plof!, SoftIce aparece ante nuestros ojos... este es el momento perfecto para meter el breakpoint. Como podrás comprobar en la barrita verde aparece que 
esta procesando en el ejecutable del Serials 2000 . 

Metemos el BreakPoint: BPX 402974 , y le damos a F5 para que continue cargando. 

Ya está el anzuelo puesto jejeje, ahora solo tenemos que hacerle picar. 
Pulsamos File/Administration Tools... y... como queriamos, SoftIce salta antes de que aparezca ninguna ventana inutil. 

Estamos viendo el código que anteriormente veíamos con W32DSM... con la ventaja de que ahora podemos ver que hace cada llamada y los posteriores saltos. 

:00402974 E837090000              call 004032B0
:00402979 8D8C24A4000000          lea ecx, dword ptr [esp+000000A4]
:00402980 C784249401000000000000  mov dword ptr [esp+00000194], 00000000
:0040298B E8E8D80000              Call 00410278
:00402990 83F801                  cmp eax, 00000001
:00402993 7571                    jne 00402A06
:00402995 8B842404010000          mov eax, dword ptr [esp+00000104]
:0040299C 6A00                    push 00000000
:0040299E 85C0                    test eax, eax
:004029A0 7452                    je 004029F4

Aparecemos en 402974 como nuestro breakpoint le había dicho al fiel SoftIce, pulsamos F10 para pasar a la siguiente instrucción y observamos que no 
ocurre nada (en pantalla), seguimos hasta la siguiente call y al pulsar F10 sobre está nos aparece la ventana de introducir password. 
Ya sabemos donde está la función que abré esa ventana. Si nos metemos en la call (con F8) y damos unas cuantas vueltas, llegaremos hasta el código dónde 
se encuentran las comparaciones que hemos estudiado anteriormente. Pero ahora no es necesario eso. 

Solo tenemos que anular esa llamada y adecuar la comprobación de la respuesta que se obtiene a nuestras necesidades. 

Primero vamos a hacerlo todo en un modo temporal para ir comprobando que sucede con cada instrucción importante. 

La primera instrucción (call 004032b0) aparentemente no hace nada que no queramos, por lo que no la cambiamos. 

La siguiente call es la que llama a la ventana de meter el password... vamos a deshacernos de ella, cambiando sus bytes actuales por NOP s (90). 
Cuando estamos situados en 0040298B , escribimos DB 40298B , entonces en la ventana de datos (arriba) aparecerán los bytes de esta instrucción. 

Pues pulsamos con el botón del ratón arriba en el primero y sustituimos todos los bytes por 90. 

Entonces quedaría asi: 

Inicialmente: E8 E8 D8 00 00 
Modificado: 90 90 90 90 90 

Cuando pulsamos intro, vemos como en la ventana de instrucciones hay un cambio y aparecen 5 nops en vez de la anterior call. 

ya podemos ir pulsando F10 y pasando cada NOP. 

Hasta que llegamos a los saltos de comprobación. 

:0040298B E8E8D80000              Call 00410278 
|5 Nops 

<> Call q llama al password.

:00402990 83F801                  cmp eax, 00000001 
|Compara EAX con 1...

:00402993 7571                    jne 00402A06 
|Salta si EAX no es = 1

:00402995 8B842404010000          mov eax, dword ptr [esp+00000104]
:0040299C 6A00                    push 00000000
:0040299E 85C0                    test eax, eax 
|Comprueba si EAX es 0

:004029A0 7452                    je 004029F4
 |Salta si es 0

Como vemos al ir pulsando F10 por el código, después de la primera comparación, saltará y entonces el programa no hará nada. Eso es equivalente a que 
pulsemos el botón Cancel en la ventana de meter el password. 

La segunda comparación (test eax, eax) y su correspondiente salto condicional también hacen de las suyas :). 
Aquí también saltará al offset 004029F4 , haciendo aparecer directamente el messagebox de Invalid Password. 

Pues ya está todo resuelto... nos tenemos que deshacer de la call que llama a la ventana de password y evitar los dos saltos condicionales. 

Podriamos dejarlo 'mu pofesional' convirtiendo el primer call en una instrucción que nos mueva a EAX un 1, y asi el salto condicional que tenemos a 
continuación no saltase nunca. 
Después hay una instrucción que mueve a EAX algo situado en esp+00000104. Si lo que mueve es un 0, el salto condicional de la siguiente línea nos 
llevará a la ventana de 'invalid password', entonces pondremos un 1 también, asi este salto se portará adecuadamente y nos dejará seguir sin problemas. 

Todo esto son pijadillas... para hacer algo rapido podemos llenar de NOPs la call y los saltos y seguro que funciona. Pero esto demuestra que sabemos lo 
que estamos haciendo. 

El cambio lo realizamos en memoria con SoftIce... 
Esto ya debería estar claro como hacerlo. 

Para que el programa se vuelva a cargar en memoria correctamente (anulando todos los cambios que hicimos anteriormente), le cerramos y le volvemos a 
cargar con el Symbol Loader. 

Entonces activamos nuestro efectivo breakpoint en 402974 y comenzamos con las modificaciones finales. 

Usando F10, llegamos hasta 0040298B. Escribimos a en softice y hacemos nuestra bonita modificación de mover a EAX un 1 :). 

a [enter] 
mov eax, 1 

Ya está.. hmmm pero tenemos que tener en cuenta una cosa. La anterior instrucción (la call) usaba 5 bytes, hemos tenido suerte, y nuestra instrucción 
(el mov) ocupa también 5. Entonces no tendremos q añadir nada para rellenar. 

Entonces el código quedaría asi: 
Inicialmente: E8 E8 D8 00 00 (call 00410278) 
Nuevo código: B8 01 00 00 00 (mov eax, 1) 


Ahora nos queda hacer el otro cambio... es en 402995. 
Nos situamos allí y escribimos a en SoftIce. Ahora ponemos lo que queremos: 

mov eax, 1 

ya está... hmmmmmm ahora si que tenemos el 'problema' ese. Nuestra nueva instrucción ocupa 5 bytes, y la antigua ocupaba 7. 
Bueno, solamente tendremos que rellenar los dos bytes de diferencia con 2 nops. 

Ponemos DB 402995 en softIce, y en la parte de arriba nos aparecen los bytes de ese offset. 
Solo tenemos que poner 90 90 en el 00 00 que queda al final de la instrucción y ya está arreglado. 

Entonces el código quedaría asi: 
Inicialmente: 8B 84 24 04 01 00 00 (mov eax, dword ptr [esp+00000104]) 
Nuevo código: B8 01 00 00 00 90 90 (mov eax, 1 | nop | nop ) 

Resumen: 

Código Inicial: 

:0040298B E8E8D80000     Call 00410278 
| Llamada a la ventana de Password

:00402990 83F801         cmp eax, 00000001 
| Eax no es 1 si damos cancel

:00402993 7571           jne 00402A06 
| Vuelve al programa

:00402995 8B842404010000 mov eax, dword ptr [esp+00000104]
| a eax resultado checkeos

:0040299C 6A00           push 00000000
:0040299E 85C0           test eax, eax 
| Comprueba si eax es 0.

:004029A0 7452           je 004029F4 
| Si es 0, salta a Invalid password.

Código 'Reparado': 

:0040298B B801000000     mov eax, 1 
| (Nuevo) - Mueve 1 a eax

:00402990 83F801         cmp eax, 00000001 
| Eax siempre será 1

:00402993 7571           jne 00402A06 
| Nunca saltará

:00402995 B801000000     mov eax, 1 
| (Nuevo) - Mueve 1 a eax

:0040299A 90             nop 
| (relleno)

:0040299B 90             nop 
| (relleno)

:0040299C 6A00           push 00000000
:0040299E 85C0           test eax, eax 
| eax lo pusimos en 1...

:004029A0 7452           je 004029F4 
| Nunca saltará

Ok, ya está, ahora le damos en File/Administrationm Tools y directamente nos abré la ventana de opciones sin pedir ni password ni leches. :) 

El cambio para que sea permantente en el ejecutable se realiza como ya explique antes... solo hay que modificar los bytes con un editor hexadecimal y 
listo. 

Despedida, agradecimientos y esas cosas....  

Ha quedado un tutorial bastante extenso, pero es lo que ocurre cuando se explica todo y no se da nada por supuesto... cosa que he intentado hacer (menos 
en lo de parchear los ejecutables) para que nadie se quede con dudas o atascado en cierto punto o haga cosas solo porque las pone aquí sin razonar el 
porqué. 

Si os ha gustado este tutorial hacedmelo saber escribiendome a tntcrackteam@hotmail.com . 

Agradecimientos y Saludos: 

Primero a Thndrkiss por hacer el Serials 2k: ey, estoy ayudando a tus coders a mejorar la seguridad para próximas versiones...