Aqui dejo el segundo capitulo, que enseña un ejemplo de crack usando el salto condicional.
Este tipo de crack es el mas sencillo y sirve como ejemplo para un primer crack.
---------------------------------------------------------------------------------------------------------------------------
Este documento ha sido elaborado con finalidades educacionales, no para fomentar el tráfico de códigos válidos para registrar programas. Para esta última finalidad ya existen sites especializados
.
CURSILLO OTOÑAL DE CRACKEO
Lección 2 – Cursillo Otoñal de Crackeo (06/10/99)
¡Saludos a todos! Entramos de lleno en el arte de la ingenierÃa invertida que en realidad no es más que el deseo de que los programas instalados en nuestro ordenador se comporten tal como nosotros queramos.
Las herramientas que requeriremos son Wdasm y un editor hexadecimal (el que más
os guste). La primera actividad que llevaremos a cabo constituye una de los más
tÃpicos y conocidos ejercicios de crackeo. Podéis llamarle como queráis, aunque
cualquiera de los siguientes tÃtulos podrÃa valer:
- LA INVERSIÓN DEL SALTO CONDICIONAL
- LA TÉCNICA DEL 74-75
El objetivo de este mÃnimo acto de ingenierÃa invertida consiste en conseguir que un programa acepte cualquier código falso como correcto (y que, por otra parte, considere al código correcto como erróneo).
Más de alguna vez habréis pillado algún crack en cuyas instrucciones sólo os decÃan: copia el crack en el mismo directorio del programa, ejecútalo, entra después en el programa y puedes entrar el código que quieras. Pues bien, este detalle que nos dejó a todos maravillados en su momento

, En realidad se puede conseguir con muy pocos cambios en el programa (generalmente un único cambio). El ejecutable del crack no hizo más que cambiar un 74 por un 75 o quizás al revés !!! (Bueno, en realidad hay cracks que permiten entrar cualquier código y no se basan en el cambio 74/75, pero dejémoslo para más adelante, ¿no?)
Antes que nada, hay que decir que la técnica que aprenderemos en esta Lección 2 vale para un buen número de programas, pese a que ya no son muchos los que
toman tan pocas precauciones. Más adelante expondremos un listado de algunos programas elaborados por personas con muy pocos deseos de proteger su producto.
· ¿POR DÓNDE EMPEZAMOS?
Estamos de acuerdo en que un programa no deja de ser un listado de instrucciones que se ejecutan de arriba hacia abajo y que el ordenador debe entender. Al parecer las máquinas sólo hablan / entienden "lenguaje máquina". Asà que los ficheros ejecutables de nuestros programas contienen unos numeritos (0-9) y letras (A-F) que la máquina interpreta como instrucciones en lenguaje ensamblador:
80 fc 40 en un ejecutable es leÃdo por la máquina como CMP ah,40 (compara AH con 40)
75 14 en un ejecutable es leÃdo por la máquina como jne XXXXXX (sino es igual a lo que se esperaba, salta 14 numeritos más abajo)
No os preocupéis por ahora sobre qué significan estas cosas. Sólo tenéis que creeros que los numeritos en hexadecimal que aparecen cuando abrimos un ejecutable con un editor hexadecimal son instrucciones que la máquina sabe entender.
¿Cómo deben funcionar las instrucciones que tienen que ver con la comprobación de un código? Evidentemente los esquemas pueden ser muy diversos, pero muchos programas recurren a un listado muy similar a lo que tenéis expuesto a continuación: (recordad que la máquina lee de arriba a abajo)
1) bla, bla, bla
2) Inicio de zona de comprobación de código
3) Cojamos el código que ha introducido el usuario y pongámoslo en un cajoncito llamado EAX
4) Cojamos el código auténtico y pongámoslo en un cajoncito llamado ECX
5) Comparemos EAX y ECX
6) Si no son iguales, saltemos a (9)
7) Emitir el mensaje "Gracias por registrarse"
8) Permitir acceso completo, desbloquear lo que sea,...bla,
9) SaldrÃa un mensaje “Código Incorrecto, .....†o algo parecido.
10) Bla, bla...
Leamos de arriba a abajo las instrucciones. Al llegar a la comparación nos
encontramos con que el programa debe tomar una decisión que dependerá del resultado de dicha comparación. En este caso el programa está preparado para saltar hacia (9) en el caso de que EAX(nuestro código) y ECX(código válido) no sean iguales. ¿Qué habrÃa pasado si fueran iguales? Lógicamente, no habrÃa saltado a (9), sino que habrÃa continuado con la lÃnea siguiente (7), donde nos dan las gracias por ser tan buenos.
Si habéis desensamblado algún ejecutable con Wdasm, a lo mejor os habéis encontrado con que, cerca del mensaje de error, algo más arriba se encuentran los mensajes de felicitación!! Probablemente algo más arriba aún se encontrará el salto condicional (je o jne)en el que se decide si saltar a error (Chico malo) o no saltar, dejar que las instrucciones sigan hasta llegar a "Gracias" (Chico Bueno).
· ¿HAY ALGUNA MANERA DE EVITAR QUE SE PRODUZCA EL SALTO A ERROR?
Efectivamente! Si llegamos a identificar y localizar "el salto", tendremos la posibilidad de cambiar dicha instrucción (con un editor hexadecimal) por otra que nos asegure que llegaremos a la zona de los agradecimiento
s. Llegados a este punto, pueden ser varias las soluciones que podrÃamos adoptar:
1.- PodrÃamos decirle por ejemplo que saltara, pero no hacia (9), sino hacia (7). En otras palabras, el programa comprobarÃa que los dos números no son iguales y por consiguiente saltarÃa, pero hacia la zona que más nos gusta (Buen chico)
2.- Otra posibilidad serÃa decirle que no hiciera nada, con lo cual, nuestro ordenador pasarÃa a leer la siguiente instrucción, que es la de los agradecimiento
s. Al arte de ordenar "no hacer nada", se le denomina NOPEAR (NO OPERATION)
3.- La tercera posibilidad para conseguir llegar a la zona de "Gracias" consiste en INVERTIR EL SALTO, es decir, DAR UNA INSTRUCCIÓN CONTRARIA A LA INICIAL.
Imaginaos que somos capaces de meter en "6) Si no son iguales, saltemos a (9)" una orden invertida “6) Si SON iguales, saltemos a (9)â€. ¿Qué pasarÃa entonces?
Muy simple, el programa saltarÃa a error si fueran iguales, es decir, si entráramos el código correcto. Si no introdujéramos el código correcto, como no serÃa igual al esperado, no saltarÃamos, sino que pasarÃamos a la siguiente instrucción, llegando pues a la zona del Buen chico!!!!
En definitiva, el salto condicional original evitaba que llegásemos a la zona de Gracias, puesto que el salto se producÃa. Nuestra intención es la de evitar que el salto tenga lugar.. y la mejor forma que se nos ocurre es despistar al programa cambiando las condiciones del salto (salta si son iguales! Si entramos el código auténtico recibimos mensaje de error; mientras que cualquier otro código es enviado a la zona-del- Buen Chico)
Leed con detenimiento el siguiente punto porque es la clave de lo que vamos a trabajar a continuación.
· ¿CÓMO LOCALIZAR EL "SALTO"?
Para nosotros es vital que el programa nos envÃe un mensaje de error, puesto que la cadena de texto contenida en ese mensaje de error será nuestra referencia clave para conseguir localizar el salto.
Para probar una vez más nuestra voluntad de no perjudicar a nadie con nuestro cursillo, nada mejor que hacer nuestro primer experimento con un programa que todo el mundo debe tener seguramente y que no vamos a craquear por completo.
Cualquier versión de Winrar nos sirve para lo que pretendemos practicar. Espero que el objetivo educacional del C.O.C quede demostrado por el hecho de que sólo vamos a forzar al programa a decirnos "Gracias" sin que, por ello, este totalmente craqueado.
Mr. Nobody ha utilizado Winrar 2.5 beta2, pero cualquier versión vale si os quedáis con el detalle de cómo funciona el tinglado. Instalémoslo, busquemos la manera de registrarnos. Nos piden nombre y código.
Introduzcamos lo que nos venga en gana. Ahà está el mensaje de error: "Registration failed"
Hagamos una copia del fichero ejecutable y desensamblémoslo con Wdasm. (el motivo de lo de la copia es que no podremos realizar cambios con un editor
hexadecimal mientras el fichero esté desensamblado con Wdasm. De esta forma podremos realizar cambios en un exe mientras el otro esté siendo desensamblado
por Wdasm).
Busquemos el texto "Registration failed" en String Data References. (fijaos que podréis ver también cadenas de texto como el "Evaluation Version" que aparece en la parte superior del programa o el mismo mensaje de felicitación!!)
String Resource ID=00870: "Registration failed"
Una vez localizado, le hacemos doble clic y aparecemos aquà >>>>
* Possible Reference to String Resource ID=00870: "Registration failed"
:00408EE4 6866030000 push 00000366
:00408EE9 E856D6FFFF call 00406544
Si nos fijamos en las cadenas que hay por el entorno, apreciaremos que los mensajes de felicitación vienen más abajo. Bueno, no pasa nada. No nos sorprende la existencia de diferentes variantes que puede haber de la misma estructura. La cosa pinta asÃ:
Bla bla
"Registration failed"
"Correct registration "
Necesariamente, antes del "registration failed" debe haber un salto condicional que decide si debe llegar a "failed" o salta a la zona que viene después, la zona del buen Chico.
¿Cómo identificamos un salto condicional? Estas son las instrucciones en ensamblador que valen para los dos saltos que nos interesan:
je (en hex. = 74) salta si es igual (a lo que la máquina esperaba)
jne (en hex. = 75) salta si no es igual (a lo que se esperaba)
Subamos para arriba para ver qué se cuece en el código. Uy!!! qué es esto!!
**************************************
:00408ECD E836C30100 call 00425208
:00408ED2 83C408 add esp, 00000008
:00408ED5 85C0 test eax, eax
:00408ED7 752C jne 00408F05 >>> si no es igual a lo que esperaba, salta a 408f05
(2c hex. = 44 decimal indica saltar 44 bytes. Comprobadlo con la calculadora de Windows: 2c = 44)
:00408ED9 6A30 push 00000030
* Possible Ref. to Menu: MAIN_MENU, Item: "Change drive Ctrl-D"
* Possible Reference to Dialog: ABOUTRARDLG, CONTROL_ID:0065, ""
* Possible Reference to String Resource ID=00101: "Warning"
:00408EDB 6A65 push 00000065
:00408EDD E862D6FFFF call 00406544
:00408EE2 59 pop ecx
:00408EE3 50 push eax
* Possible Reference to String Resource ID=00870: "Registration failed"
:00408EE4 6866030000 push 00000366
:00408EE9 E856D6FFFF call 00406544
:00408EEE 59 pop ecx
:00408EEF 50 push eax
:00408EF0 8B4D08 mov ecx, dword ptr [ebp+08]
:00408EF3 51 push ecx
* Reference To: USER32.Message
BoxA, Ord:0000h
:00408EF4 E89A220400 Call 0044B193
:00408EF9 33C0 xor eax, eax
:00408EFB A37CF04400 mov dword ptr [0044F07C], eax
:00408F00 E9F9000000 jmp 00408FFE
* Referenced by a (U)nconditional or (C)onditional Jump at Address: :00408ED7(C)
:00408F05 6A40 push 00000040 >>>>>el salto lleva hasta aquÃ!!!!!LA
zona del Buen chico!!!
* Possible Reference to String Resource ID=00872: "Correct registration"
:00408F07 6868030000 push 00000368
:00408F0C E833D6FFFF call 00406544
:00408F11 59 pop ecx
:00408F12 50 push eax
* Possible Reference to String Resource ID=00871: "Thank you for support"
**************************************************
El jne lleva hasta 00408F05 . Si bajáis la vista hasta esta dirección, veréis que es la zona en que se establece "Correct registration".
Evidentemente este salto no tiene lugar cuando entramos un código erróneo, sino que las instrucciones se ejecutan hasta llegar a "Registration failed". ¿Os gustarÃa saltar hasta la zona de felicitaciones? Sólo nos falta invertir el salto en cuestión: si se trata de jne, pondremos je (o a la inversa). El programa acabará haciendo lo contrario de lo que se supone que debe hacer.
¿CÓMO REALIZAR EL CAMBIO?
Si nos situamos con Wdasm encima de la lÃnea:
00408ED7 752C jne 00408F05
(Dirección) (hex. ) ==== (instrucción ensamblador)
Podremos ver como se pone de color verde (si le dais a "Execute jump" en Wdasm, saltaréis hacia la zona a la que apunta el salto). En la parte inferior de Wdasm aparece (en mi caso):Offset@000084d7h.
Lo que nos interesa exactamente es 84d7. Esta es la "dirección" que buscaremos con el editor hexadecimal. Iniciamos nuestro editor hex., abrimos el ejecutable y buscamos el
Ofsett 84d7. Esto deberÃa llevarnos directamente a una zona con numeritos hex. y
justo encima de un precioso 75 2C. Debemos cambiarlo por 74 2C, guardar los cambios y ya está!!! (Los cambios los llevamos a cabo, estando Winrar sin ejecutarse!!)
Al reiniciar, vamos a Options, Register... y podremos entrar lo que queramos. EL programa nos dirá "Thanks for...".
Hemos forzado Winrar para que nos dé las gracias. Si introducÃs un código real válido os dirá "Registration failed†Ahora llega la decepción. Al reiniciar el programa continúa estando sin registrar. ¿Porqué? Pues porque el programador se ha molestado en incluir otro chequeo aparte del que nosotros acabamos de reventar. A lo largo del programa hay más de una comprobación con lo que sólo hemos "craqueado" parcialmente el producto. Ya hablaremos de la solución definitiva...
¿Todos los programas tienen más de una comprobación o chequeo? En absoluto. A continuación tenéis un pequeño listado (que iremos ampliando) de ejercicios que
se solucionan por el mismo método (o similar) y no tienen ningún chequeo adicional,
con lo cual, el método explicado será suficiente para conseguir lo que pretendemos.
Si queréis una pequeña dosis de 74/75 fáciles:
SUPER TEXT SEARCH
FONTLOOK
DIRECTORY PRINTER
DIRECTORY COMPARE
SIMPLY3D (!!!)
COPYTO
FULLDISK 3.3
ACEEXPERT 3.0
CD-R DIAGNOSTIC 1.44
MORPHER 2.0
(Mr. Nobody no ha verificado cada uno de los programas citados, pero sÃ
ha leÃdo tutoriales al respecto que confirman su protección de 1 solo
cambio)
(Ya sabéis que un simple NOMBREDELPROGR
AMA + DOWNLOAD en Altavista será suficente para localizarlos)
En la mayorÃa de estos programas, al encontrar el mensaje de error, vemos unas lÃneas más arriba algo parecido a:
* Referenced by a (U)nconditional or (C)onditional Jump at Address: 0040114C(C)
Con ello nos dicen DESDE DONDE se ha saltado a error. Con Goto / Goto code location... 40114c Wdasm nos llevará directos al je / jne que nos interesa!!!
A trabajar!!! Recordad 1.mensaje error/ 2.de donde viene/ 3.invertir je /jne)
PS: A veces podéis encontraros 0F 84 (EN LUGAR DE 74) y 0F 85 (en lugar de 75). La inversión funcionarÃa de la misma forma.
PSS: En algunos manuales encontraréis que "je" es lo mismo que "jz" (y jne = jnz)
PSSS: ¿Demasiada información? Que cada uno se tome su tiempo

ADDENDUM/Lección 2 – Cursillo Otoñal de Crackeo (09/10/99)
Debido a que parece claro que es un problema que practiquemos con programas diferentes, versiones diferentes, etc. vamos a realizar una pequeña práctica con un mismo material.
Completamos nuestra lección 2 con un pequeño añadido que corrobora
nuestro deseo de no perjudicar a nadie con nuestro cursillo. En esta ocasión trabajaremos con un programa diseñado adhoc para ser crackeado. Los interesados en conseguirlo podéis hurgar en es.binarios.mi
sc con el tÃtulo C.O.C- ejercicio lección 2
Cruhead's Crackme1.0
(el autor recomienda no ser tramposo y usar Wdasm, pero para nosotros será un ejemplo muy ilustrativo)
Entramos cualquier dato y nos encontramos con el mensaje de error.
Desensamblamos con Wdasm y buscamos el mensaje de error en StringData References. Doble click y nos traladamos a:
* Referenced by a CALL at Address: |:00401245
:00401362 6A00 push 00000000
* Reference To: USER32.Message
Beep, Ord:0000h
:00401364 E8AD000000 Call 00401416
:00401369 6A30 push 00000030
* Possible StringData Ref. from Data Obj ->"No luck!"
:0040136B 6860214000 push 00402160
* Possible StringData Ref. from Data Obj ->"No luck there, mate!"
:00401370 6869214000 push 00402169
Algo más arriba tenemos la pista de como hemos llegado hasta aquÃ: Reference by a CALL (podrÃa ser un JUMP) at Adress 401245
Es el momento de darle a Goto Codee Location 401245. Esto nos hará llegar a:
dirección heñas instrucciones ensamblador
:00401241 3BC3 cm ex, ex
:00401243 7407 je 0040124C
:00401245 E818010000 cal 00401362 >>>>>>>>CALL que nos ha llevado a
"error"
:0040124A EB9A jmp 004011E6
¿Cómo podrÃamos haber evitado entrar en CALL 401362(ERROR)? Fijémonos en una lÃnea más arriba: Hay un salto condicional justo después un CMP (comparación). Bien, asà pues, el programa compara y decide si saltar a algún sitio o seguir hasta llegar al CALL-error.
Nuestra deducción es la siguiente: el salto no se ha producido y por tanto
el programa ha llegado una lÃnea más abajo al CALL-error. Si hacéis la prueba con Wdasm, podéis darle al Execute Jump (cuando
estéis sobre esta lÃnea) y llegaréis a un CALL, entonces le dais al Execute CALL
y entraréis de pleno en la zona del buen chico, asà pues, estamos
interesados en que el salto se produzca. La solución: Invertir el salto je 40124c por jne 40124c.
Para ello cambiaremos el 74 07 por 75 07. Nos colocamos encima de la lÃnea y Wdasm nos informa en la parte inferior que se trata de la dirección-offset @offset000843h, o sea, 843.
Los que tengáis Ultraedit como editor hexadecimal deberéis darle al Ctrl+g
y entrar 0x843 y os situaréis justo en 74 07, cambiáis por 75 07 y
guardar!!!
Hay otro método para buscar la cadena de bytes que nos interesa.
Podemos buscar los bytes en hex. 3B C3 74 07 E8 18 01 00 00 EB 9A y cambiar el
74. Esta técnica es algo más delicada ya que deberemos asegurarnos de que
esta secuencia sólo se encuentra una sola vez en todo el programa. Si
hubiera más de una cadena de bytes similar, no sabrÃamos cuál es la que nos
interesa!!
Una vez guardados los cambios, el programa admitirá cualquier chorrada que
le introduzcamos.
Un detalle. Cuando practiquemos con Softice, tendremos acceso "en vivo" a lo
que se está comparando en "cmp eax, ebx". Veremos qué contiene EAX y
qué contiene EBX. Se intuye pues, la diferencia de técnicas entre el
LISTADO MUERTO y el DEBUGGEO EN VIVO?
PS: Como habéis visto, en este caso, tenÃamos claro que querÃamos que se produjera el salto. HabÃa otra forma de lograrlo, aparte de invertir el 74 por un 75. PodÃamos haber cambiado el 74 por EB (JMP), que significa "saltar siempre", es decir, se trata de un salto incondicional, el cual nos traslada inevitablement
e a la zona deseada, sea cual sea el resultado de la comparación.
· CONSIDERACIONES FINALES.
¿ES "NORMAL" LA ESTRUCTURA DE ESTE PROGRAMA EN LO CONCERNIENTE A LA ZONA DEL MENSAJE DE ERROR?
En realidad, cuando buscamos un mensaje de error con wdasm, lo más frecuente es que, algunas lÃneas más arriba, encontremos un: *Referenced by an (U)nconditional JUMP . Es decir, que al mensaje de error se ha llegado desde un jump (je, jne).
Fijaos que en nuestra práctica se llegaba a error por un *Referenced by a CALL. En otras palabras, no se llegaba a error por un salto, sino por una LLAMADA. No deja de ser una pequeña variación de lo habitual, pero tengamos en cuenta que lo "normal" es lo de la primera posibilidad.
Esto nos lleva a la última consideración... ¿QUÉ ES UN CALL? Cuando la máquina lee las instrucciones de un ejecutable, al llegar a un CALL XXXXXX, se desplaza hasta la dirección XXXXXXX y empieza a leer lo que allà se encuentra y sigue, sigue,.. hasta encontrarse la instrucción RET (return) que le devuelve al sitio donde habÃa el CALL XXXXXX. En cierto modo es como una especie de salto momentáneo para
ejecutar/comprobar/comparar hacer lo que sea,...y regresar al sitio inicial. Dentro de los CALLS suelen generarse los códigos reales, comparaciones entre el código chungo y auténtico,...y al regresar, la máquina lleva una serie de indicaciones que le harán tomar una u otra dirección al encontrarse, por ejemplo un je o un jne,... Muchas veces os encontraréis con secuencias del tipo:
call xxxxxxx (el programa salta a xxxxxx, hace una serie de cálculos y regresa)
test eax,eax
jne xxxxx
En nuestro Crackme1, el call 00401362 iba a una zona en que se establecÃa que se debÃa mostrar el mensaje de error, por tanto era un CALL a evitar. Cosa que hemos logrado invirtiendo el salto condicional que le precedÃa. Mr. Nobody os aconseja jugar un poco
con los CALL. Poneos encima de uno, dadle a EXECUTE CALL XXXXXX y veréis como os traslada a XXXXXXX. Allà habrá una serie de instrucciones y tarde o temprano llegaréis (si vais descendiendo) hasta un RET , que se supone que nos devolverá a la dirección donde empezó el CALL XXXXXXX. Por cierto, un CALL puede contener en su interior otros CALLs (con sus propias direcciones y RETs). En cierta manera tenemos que verlo como una especie de cuadro jerárquico. HabrÃa pues un CALL-madre que en su interior contendrÃa muchas instrucciones, nuevos calls,...pero que al final todo acabarÃa devolviéndonos al sitio en que se habÃa iniciado todo.
Ejemplo:
push....
call XXXXXX (contiene instrucciones, calls,.....) y acabamos volviendo a...
test eax, eax
jne.....
Es frecuente ver que a lo largo de las instrucciones de un programa haya un CALL XXXXXXX que se repita con cierta frecuencia. Imaginaos que en XXXXXX hay unas instrucciones que verifican la autenticidad de un código y devuelven una respuesta positiva o no. EL programador puede hacer que esta sección del programa sea llamada con un CALL XXXXXXXX al iniciarse el programa, más tarde también en la sección del cuadro de diálogo que permite introducir un código para registrarse, o también, por ejemplo al intentar realizar una acción sólo disponible en la versión registrada,...
Bfff... basta por hoy, fale?
**********************************************************************
Bueno, habréis observado que el fichero que Mr. Nobody ha dejado en es.binarios.mi
sc contiene un fichero llamado crackme2. Bueno, se trata de otro trabajito de Cruehead. ¿Creéis que la técnica para "arreglarlo" va a ser muy diferente de la de su Crackme 1.0,
tratándose del mismo autor? Es hora de comprobarlo. Ya tenemos deberes para el fin de semana.
PSS: ¿No es una gozada desensamblar un programa tan pequeñito?
PSSS: ¿Se empieza a ver algo de luz al final del túnel??

PSSSS: Muy pronto retomaremos el Winrar desde donde lo habÃamos dejado.
EXAMEN LECCIÓN 2
Buenas!!!!! Aquà estamos con un bonito examen sorpresa. A ver qué tal nos sale. Trabajamos con el código de LVIEW PRO 1c5/32 (no creo que esté ya disponible en
la red, puesto que es algo viejito ya)
EstarÃa muy bien que alguien (tan solo 1) se molestara a responder las preguntas y enviarlas. ¿Quién se atreve? Si hemos asumido los contenidos de la lección 2, nos resultará fácil. Sólo hay que prestar atención a las direcciones, ¿no?
Atención: Echemos un vistazo a esta zona de mal-chico que hemos sacado del programa. A continuación podemos responder al pequeño cuestionario final.
Direcciones hexas instrucciones en ensamblador
:0041EDC1 E86AFEFFFF call 0041EC30
:0041EDC6 83C408 add esp, 00000008
:0041EDC9 85C0 test eax, eax
:0041EDCB 751A jne 0041EDE7
* Possible StringData Ref. from Data Obj ->"User name and ID numbers do
not†->"match, please verify if name and "
->"ID# were typed correctly."
:0041EDCD 68388F4600 push 00468F38
:0041EDD2 57 push edi
:0041EDD3 E8B856FEFF call 00404490
:0041EDD8 83C408 add esp, 00000008
:0041EDDB 33C0 xor eax, eax
:0041EDDD 5F pop edi
:0041EDDE 5E pop esi
:0041EDDF 5B pop ebx
:0041EDE0 81C478020000 add esp, 00000278
:0041EDE6 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0041EDCB(C)
:0041EDE7 8D44240E lea eax, dword ptr [esp+0E]
:0041EDEB 8D8C2454010000 lea ecx, dword ptr [esp+00000154]
:0041EDF2 8D542424 lea edx, dword ptr [esp+24]
:0041EDF6 50 push eax
:0041EDF7 51 push ecx
:0041EDF8 52 push edx
:0041EDF9 E842C5FFFF call 0041B340
:0041EDFE 83C40C add esp, 0000000C
:0041EE01 E8DAF8FFFF call 0041E6E0
:0041EE06 8BF0 mov esi, eax
:0041EE08 85F6 test esi, esi
:0041EE0A 745E je 0041EE6A
:0041EE0C 8B44240E mov eax, dword ptr [esp+0E]
:0041EE10 8D8C2454010000 lea ecx, dword ptr [esp+00000154]
:0041EE17 25FFFF0000 and eax, 0000FFFF
* Possible StringData Ref. from Data Obj ->"RegInfo"
:0041EE1C 8B15D08D4600 mov edx, dword ptr [00468DD0]
:0041EE22 50 push eax
:0041EE23 51 push ecx
* Possible Reference to Menu: MenuID_0003
:0041EE24 6A03 push 00000003
:0041EE26 6A00 push 00000000
:0041EE28 52 push edx
(disculpad si el pedazo de código es demasiado largo, seguro que no hacÃa falta todo)
***************
CUESTIONARIO
***************
PREGUNTA 1: Nos encontramos en plena zona del mal-chico (mensaje de error). Habréis observado que hay un salto condicional justo antes del mensaje de
error. ¿Crees que este salto se produce cuando entramos un código falso? Razonemos nuestra respuesta.
PREGUNTA 2: Hay (como mÃnimo) dos maneras para asegurarse que el programa llegue a la zona del buen-chico (en este caso, creedme, reginfo...). Coméntalos.
PREGUNTA 3: Supongamos que no queremos utilizar wdasm para conseguir la dirección hex. en la que hay que aplicar los cambios. ¿Qué método alternativo podrÃamos utilizar para hallar los bytes hex. que nos interesan y cambiarlos con el
editor hexadecimal?
REPUESTAS EXAMEN
PREGUNTA 1: Nos encontramos en plena zona del mal-chico (mensaje de error). Habréis observado que hay un salto condicional justo antes del mensaje de error. ¿Crees que este salto se produce cuando entramos un código falso? Razonemos nuestra respuesta.
NO, si entramos un código falso, eax y eax serán iguales, con lo que el programa no efectuará el salto y entraremos en la zona de mal-chico
:0041EDC9 85C0 test eax, eax
:0041EDCB 751A jne 0041EDE7
* Possible StringData Ref from Data Obj ->"User name and ID numbers do not "->"match, please verify if name and "->"ID# were typed correctly."
PREGUNTA 2: Hay (como mÃnimo) dos maneras para asegurarse que el programa llegue a la zona del buen-chico (en este caso, creedme, reginfo...). Coméntalos.
En este caso NOPEAR no nos servirÃa de nada, ya que nos interesa el salto
1.- Cambiamos jne por je con lo que saltarÃa si son iguales (75 por 74).
2.- Cambiamos jne por jmp con lo que saltarÃa siempre (75 por EB).
PREGUNTA 3: Supongamos que no queremos utilizar wdasm para conseguir la dirección hex. en la que hay que aplicar los cambios. ¿Qué método alternativo podrÃamos utilizar para hallar los bytes hex. que nos interesan y cambiarlos con el editor hexadecimal?
Pues buscamos la cadena E8 6A FE FF FF 83 C4 08 85 C0 75 1A
:0041EDC1 E86AFEFFFF call 0041EC30
:0041EDC6 83C408 add esp, 00000008
:0041EDC9 85C0 test eax, eax
:0041EDCB 751A jne 0041EDE7
Bueno... eso creo
AgradecerÃa a Mr. Nobody que me contestara si he aprobado o por el contrario no he acertado ni una, ya que sin tener el programa... aun funciono un poco con la teorÃa del ensayo y error.
DEBERES PARA FIN SEMANA
ftp://ftp.rediris.es/mirror/simtelnet/win95/graphics/asimg10.zip
ftp://ftp.tas.gov.au/pub/simtelnet/win95/graphics/asimg10.zip
ftp://sunsite.anu.edu.au/pub/pc/simtelnet/win95/graphics/asimg10.zip
ftp://ftp.univie.ac.at/mirror/simtelnet/win95/graphics/asimg10.zip
Elegir el que queráis. Asmallimage es un pequeño programa (635k) cuyo autor no ha leÃdo nada sobre los peligros de hacer aparecer un mensaje de error y no incluir chequeos iniciales en el código. Ello implica que el señor 74-75 es suficiente para resolver todo el meollo con cualquier dato que le sea introducido...
. Una lástima, una vergüenza
Si alguien no resuelve el ejercicio, que lo manifieste y Mr. Nobody lo explicitará en forma de capturas de pantalla (que, en caso de ser necesario, se postearÃan a es.binarios.mi
sc
Ya queda menos para acabar lo del Winrar y llegar a la lección 3
APÉNDICE FINAL/Lección 2 – Cursillo Otoñal de Crackeo (22/10/99)
Bienvenidos nuevamente a la parte final de nuestra lección 2, donde acabaremos de completar nuestros estudios sobre Winrar. Antes de empezar, no obstante, serÃa bueno recordar qué hemos estado viendo recientemente:
*La técnica del salto invertido 74/75 nos valió para forzar a Winrar a mostrarnos un mensaje de "Tañas for registering", aunque posteriormente, al reinicializar el programa, comprobábamos que habÃa algún chequeo que devolvÃa el programa a su estado original.
*Mr. Nobody sugirió el estudio de otros programas como Copyto, Fontlook o Techfacts que serán analizados en breve y que, de no haber cambiado su perfil de protección, responderán también a la llamada del 74/75
*Hicimos un pequeño examen sobre el código de lview pro 1c5/32 que fue magistralmente resuelto por uno de los "inscritos". La técnica del 74/75 también resolvÃa el "problema".
*Sugerimos el programa Asmallerimage 1.0 como ejercicio interesante en que el 74/75 nos llevaba al éxito. No perdamos de vista este programa, porque será objeto de estudio al llegar al uso del debugger Softice, muy, muy pronto.
*Vamos allá pues...a resolver lo pendiente que tenÃamos con Winrar.
La primera idea que deberÃa habernos quedado clara con el uso del "listado muerto" de Wdasm es que las cadenas de texto contenidas en Strng Data Ref.. nos son de gran utilidad. Al localizarlas, les hacemos doble click y nos vemos trasladados a la zona en que aparecen. Nuestra misión consiste, pues, en detectar qué salto les ha llevado hasta allà y conseguir invertirlo con la ayuda de un editor hexadecimal. No sólo son susceptibles de ser invertidos los saltos hacia mensajes como "Invalid code", sino que cualquier otra cadena de texto puede ser evitada o forzada a aparecer. Al reiniciar Winrar nos reaparece el mensaje Evaluation Copy en la barra superior, pues bien, nuestra primera tarea consistirá en localizarlo entre las StringDataRefe
rences, hacer doble click y reflexionar sobre cómo podemos evitar tal cadena de texto. Esto es lo que tenemos:
****************
Winrar 2.50 Beta 2
****************
:004134F1 833D7CF0440000 cmp dword ptr [0044F07C], 00000000
:004134F8 752F jne 00413529
* Possible Reference to String Resource ID=00873: "evaluation copy"
|
:004134FA 6869030000 push 00000369
:004134FF E84030FFFF call 00406544
En este caso nos lo han puesto muy fácil. El salto condicional jne previo al mensaje desagradable apunta hacia 413529. Está claro que si se produce, nos enviará lejos de 4134fa (evaluation copy). ¿Qué haremos pues para conseguir nuestro propósito? Invertir el salto con un 742F o obligar a saltar EB27.
Si nos colocamos sobre la lÃnea con Wdasm, en la parte inferior nos aparecerá la dirección hex. que deberemos buscar con nuestro editor hexadecimal. Recordemos que en 0012AF8h (en mi caso), la -h sólo indica que se trata de "hexadecimal" y los 0000.. no tienen importancia.
Si aplicamos los cambios y los guardamos, al volver a arrancar Winrar ya no
tendremos que ver más mensajes de "evaluation copy", que resultan muy desagradables
para la vista humana ya que parece como si quisieran recordarnos en todo momento
que somos pobres

Muchos tutoriales sobre el crackeo de Winrar lo dejaban aquÃ. Menos mal que ya más
de uno se ha percatado de que a pesar de la inversión de lo de "invalid code" y lo
de"evaluation copy", el programa mantiene una serie de limitaciones.
En realidad no son ningún obstáculo para quien quiera usar Winrar y..seguramente, la compañÃa creadora de esta utilidad sólo mantienen estas limitaciones a nivel simbólico. Les encanta que la gente utilice su programa, con lo cual ponen unas limitaciones a determinadas opciones que son vitales para disfrutar del producto en sÃ.
Son las siguientes: Nos aparece un mensaje de "Available only in registered version"
en las siguientes situaciones
menu-options >settings >general> log errors to file
menu-options >settings >compression> put authenticity verification
menu-commands > add files to archive > Erase destination disk before...
menu-commands > add files to archive > put authenticity verification
Una vez más se comete el error de darnos un mensaje de error (válgame la redundancia), puesto que podremos localizarlo sin problemas entre las StringData: Available in registered version only.
No obstante, antes de ser demasiado optimistas, Mr. Nobody se ha permitido el
lujo de utilizar un programa fantástico denominado Search&Replace y ha buscado
cuántas veces aparece este mensaje a lo largo del código desensamblado de winrar.
Tiemblen!!
******************************
Processing file: D:\W32DASM\W32DASM\WPJFILES\WinRAR.alf
Line 6257 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 6424 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 6443 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 6621 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 7013 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 7164 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 7183 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 7321 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 8063 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 8079 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 8651 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 8778 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 9009 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 9868 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 10790 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 21565 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 22173 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 22646 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 22706 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 24036 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 28973 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 29241 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 29815 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 29976 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 33632 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 38648 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 38841 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Line 59644 - * Possible Reference to String Resource ID=00106: "<Available> in registered version only"
Found 28 occurrences.
Searched 1 file(s), found 28 occurrences in 1 file(s)
*************************************
El mensaje aparece 28 veces a lo largo del listado de wdasm. De hecho, si hacemos
doble clic en StringData, nos traslada a la primera localización, un nuevo doble
clic a la siguiente, etc, etc......
Nosotros sólo estamos interesados en invertir el salto que lleva a cuatro de estos
mensajes, pero por cuál empezamos, ¿lo invertimos todo? En realidad si echamos un vistazo a las diferentes zonas en que aparece "Available in reg." observaremos
que no todas ellas están precedidas por un salto condicional. En algunos casos ni tan sólo aparece por ahà cerca algo que poder invertir. Fijémonos en dos ejemplos:
*************************************
Este parece fácil
*************************************
:00403F03 85C0 test eax, eax
:00403F05 740A je 00403F11
:00403F07 6A01 push 00000001
* Possible Ref to Menu: MAIN_MENU, Item: "Unselect group Gray -"
* Possible Reference to Dialog: CMDWNDADD, CONTROL_ID:006A, ""
* Possible Reference to String Resource ID=00106: "Available in registered version only"
|
:00403F09 6A6A push 0000006A
:00403F0B 53 push ebx
***************************************************
Pero aquà vienen un par realmente poco claros para nosotros
****************************************************
:00403FAD 833D7CF0440000 cmp dword ptr [0044F07C], 00000000
:00403FB4 7524 jne 00403FDA
:00403FB6 6A30 push 00000030
* Possible Ref to Menu: MAIN_MENU, Item: "Change drive Ctrl-D"
* Possible Reference to Dialog: ABOUTRARDLG, CONTROL_ID:0065, ""
* Possible Reference to String Resource ID=00101: "Warning"
:00403FB8 6A65 push 00000065
:00403FBA E885250000 call 00406544
:00403FBF 59 pop ecx
:00403FC0 50 push eax
* Possible Ref to Menu: MAIN_MENU, Item: "Unselect group Gray -"
* Possible Reference to Dialog: CMDWNDADD, CONTROL_ID:006A, ""
* Possible Reference to String Resource ID=00106: "Available in registered version only"
:00403FC1 6A6A push 0000006A
:00403FC3 E87C250000 call 00406544
:00403FC8 59 pop ecx
:00403FC9 50 push eax
:00403FCA 53 push ebx
* Reference To: USER32.Message
BoxA, Ord:0000h
:00403FCB E8C3710400 Call 0044B193
:00403FD0 6A00 push 00000000
* Possible Ref to Menu: MAIN_MENU, Item: "Unselect group Gray -"
* Possible Reference to Dialog: CMDWNDADD, CONTROL_ID:006A, ""
* Possible Reference to String Resource ID=00106: "Available in registered version only"
|
:00403FD2 6A6A push 0000006A
:00403FD4 53 push ebx
***************************************
¿Qué hacemos? Podemos intentar ir a lo loco a por los que parezcan fáciles
como el primer ejemplo, invertirlos y luego arrancar Winrar para ver
cuál de los 4 mensajes de "Available..." ha desaparecido. Evidentemente,
cuando desparezca el mensaje "Available..", la opción estará habilitada para
su uso.
La opción de "ir a lo loco" es válida, requiere algo de paciencia y
siempre se puede dar con lo que buscamos aunque resulte un poco fatigante. En
este caso, mr.nobody, cansado de invertir cosas y comprobar después que
ninguno de los cuatro mensajes desaparecÃa, ha optado por hacer algo de
trampa, al utilizar una herramienta en la cual nos introduciremos muy pronto en
la lección 3, se trata de Softice.
Con este debuggeador uno puede dar la orden de que se detenga la ejecución
del programa en determinadas situaciones. En su caso, mr.nobody ordenó
a Softice que detuviera la ejecución de Winrar en el momento en que
apareciera un messagebox (la tÃpica cajita de error con el texto "Available...").
Al detener la ejecución de Winrar en el preciso momento de aparecer el
mensaje de error, se tiene acceso a la información sobre en qué parte del
programa nos encontramos. Entonces, no es precisó más que anotar la dirección en
que nos encontramos e ir al listado de Wdasm a buscar qué se cuece por ahÃ,
cuál ha sido el último salto condicional que se ha producido.
Estos fueron los resultados:
menu-options >settings >general> log errors to file = zona 403FCB
menu-options >settings >compression> put authenticity verification = zona 40437F
menu-commands > add files to archive > Erase destination disk before...= zona 40a970
menu-commands > add files to archive > put authenticity verification = zona 40a93c
Ahora ya sabemos dónde se encuentra el meollo real y no la paja inútil. Veamos el primer ejemplo:
****************************+
:00403FAD 833D7CF0440000 cmp dword ptr [0044F07C], 00000000
:00403FB4 7524 jne 00403FDA << salta más allá de error
:00403FB6 6A30 push 00000030
* Possible Ref to Menu: MAIN_MENU, Item: "Change drive Ctrl-D"
* Possible Reference to Dialog: ABOUTRARDLG, CONTROL_ID:0065, ""
* Possible Reference to String Resource ID=00101: "Warning"
:00403FB8 6A65 push 00000065
:00403FBA E885250000 call 00406544
:00403FBF 59 pop ecx
:00403FC0 50 push eax
* Possible Ref to Menu: MAIN_MENU, Item: "Unselect group Gray -"
* Possible Reference to Dialog: CMDWNDADD, CONTROL_ID:006A, ""
* Possible Reference to String Resource ID=00106: "Available in registered version only"
:00403FC1 6A6A push 0000006A
:00403FC3 E87C250000 call 00406544
:00403FC8 59 pop ecx
:00403FC9 50 push eax
:00403FCA 53 push ebx
* Reference To: USER32.Message
BoxA, Ord:0000h
:00403FCB E8C3710400 Call 0044B193
:00403FD0 6A00 push 00000000
* Possible Ref to Menu: MAIN_MENU, Item: "Unselect group Gray
|
* Possible Reference to Dialog: CMDWNDADD, CONTROL_ID:006A, ""
* Possible Reference to String Resource ID=00106: "Available in registered version only"
:00403FD2 6A6A push 0000006ª
:00403FD4 53 push ebx
* Reference To: USER32.CheckDl
gButton, Ord:0000h
:00403FD5 E887700400 Call 0044B061
* Referenced by a (U)nconditional or (C)onditional Jump at Address: 00403FB4(C)
:00403FDA B801000000 mov eax, 00000001 >>>el salto viene hasta
aquÃ!!!lejos de error
:00403FDF E969010000 jmp 0040414D
******************
Fijémonos en que aparecen dos referencias a "Available..." y que más arriba aparece un salto condicional que, de producirse, nos enviarÃa un par de lÃneas más abajo de "Available.." con lo que evitarÃamos el mensaje de error.
Quedémonos con el detalle de que el salto de dirige a una zona cuya primera instrucción
es mov eax, 00000001.
Aquà sólo tenemos el ejemplo del primero de los cuatro mensajes, pero es igualmente válido para los tres restantes, cuya estructura es prácticamente idéntica. Sólo tenemos que buscar un lugar con dos referencias a "Available.." cercanas a una anotación del tipo * Reference To: USER32.Message
BoxA y que tenga algo más arriba un JNE que se dirige hacia una lÃnea después de todo el meollo.
Los interesados pueden divertirse buscando los tres mensajes restantes a invertir (recordad, o 74 o EB puesto que lo que queremos es saltar). Por cierto, si queremos hacer una reflexión más profunda, podemos quedarnos con el detalle de que el salto deseado no se ha producido porque en la comparación
cmp dword ptr [0044F07C], 00000000 el valor que se esconde en la dirección de
memoria 44f07c es 0.
Reflexionemos: el programa compara lo que hay en 44f07c con 0. y a continuación decide salta si no son iguales. ¿Ha saltado? No. Ello indica que 44f70c contiene
un 0. Los 4 mensajes "Available..." aparecen después de una comparación idéntica. ¿Qué pasarÃa si en 44f07c hubiera un 1? Pues que sin necesidad de retocar el
salto condicional, este saltarÃa (lejos del mensaje "Available..") puesto que 44f07c i 0 no
serÃan iguales.(recordad = jne = salta si no son iguales)
¿Hay posibilidades de meter un 1 en la dirección 44f07c? SÃ. pero para
ello debemos esperar a que llegue el turno de Softice. Creed a mr.nobody. Con sólo meter un 1 en esa zona, todas las comparaciones acaban devolviendo resultados positivos para nosotros. Con mucha frecuencia el programa se interesa por saber si "el cajoncito EAX" contiene un 0 o un 1 después de un CALL o si en determinada dirección de memoria hay un 0 o un 1. ¿Os imagináis que vienen a representar estos numeritos?
Habitualmente 0 = no registrado / 1= registrado (estamos generalizando, por suspuesto!)
A esta doble posibilidad se la denomina FLAG, o sea, la banderita que nos anuncia si SI o NO. Precioso, ¿verdad?
Eso es todo por el momento. Ya queda menos para la lección 3. Probablemente haremos un pequeño estudio de algún otro programa que se deje manosear por
el señor 74 o el señor 75.
La reflexión que nos debe ocupar ahora es: ¿cómo es posible que conociendo
sólo un par de instrucciones en ensamblador se puedan hacer estas cosas? Lo
cierto es que hay un montón de programadores que procuran evitar que
sus programas cedan ante un 74/75 y eso es, como mÃnimo, respetable. Cuando una utilidad cae con un simple 74/75 sólo podemos pensar que no tienen interés
en proteger el producto ni un mÃnimo. SerÃa algo similar a cuando te muestran una imagen pornográfica super fuerte e incorporan una diminuta estrellita en un punto minúsculo para simular que "asà ya no se verá nada"

Son las comparaciones de Mr. Nobody.
--------------------------------------------------------------------------------------------------------------------------------------