| ESTUDIO COLECTIVO DE DESPROTECCIONES Última Actualizacion: 25/10/2001 |
Programa | Flash 32 v1.27 | W95 / W98 / NT
Descripción | Este programa sirve para capturar pantallas o secuencias de estas, acepta multitud de formatos incluso AVI y FLI y tambien puede capturar pantallas de programas en MS-DOS.
Tipo | Trial de 30 días + special banner
Tipo de Tutorial | [X]Original, []Adaptación, []Aplicación, []Traducción
Url | http://perso.infonie.fr/chass/indexe.htm
Protección | Nag Screen + Trial 30 días + banner
Dificultad | 1) Principiante, 2) Amateur, 3) Aficionado, 4) Profesional, 5) Especialista
Herramientas | SoftIce v4, W32dasm , UltraEdit
Objetivo | Eliminar el banner y el límite de tiempo mediante parcheado del código.
Cracker | Black Fenix
Grupo | http://kickme.to/wkt
Fecha | Mayo del 2000
INTRODUCCION
Bueno nuestro quinto tutorial sobre cracking, en esta entraga vamos a variar un poco dejando los keygenerators de lado y vamos a examinar un programa llamado Flash 32 v 1.27. El programa es de evaluación y expira a los treinta dias , ademas en todas las pantallas que capturemos aparecerá el texto 'Flash - Evaluation' tapando con ello parte de la imagen. Nuestro proposito es eliminar el limite de tiempo (30 dias) el texto que imprime al salvar las capturas y el NAG que muestra al salir del programa. Como puedes ver este crack promete ser divertido y variado :) El programa no permite introducir ningún numero de registro por lo que en este caso nuestra busqueda empezará de otra manera y tendremos que modificar directamente el ejecutable.
AL ATAQUE
Instalar el programa, ejecutarlo y este funcionará normalmente, ahora salimos del programa (este queda instalado en la barra de tareas por lo que haremos click sobre su icono con el botón izquierdo y seleccionaremos 'Close Flash'. Nos aparecera una pantalla en la que se nos invita a registrarnos (aunque pulsemos register lo unico que saldrá es una ventana con un fichero de texto donde deberemos rellenar unos datos y enviarlos al autor para que nos envie la versión registrada) pulsaremos Ok y saldremos del programa. - Ahora cambiamos la fecha del sistema y la avanzamos en más de treinta dias de la actual. Ejecutamos de nuevo el programa y nos aparece una ventana que dice: 'The evaluation period is finished bla bla bla...' bien, recordarla, Ahora hacemos una copia del ejecutable y lo renombramos a Flash32.exx abrimos el W32Dasm y desensamblamos dicha copia para no trabajar con el original. - Una vez desensamblado, pulsamos sobre el icono 'Strn Ref' y buscamos la cadena 'The evaluation bla bla ...' una vez encontrada hacemos doble click sobre esta y el W32Dasm nos llevará a la unica parte del programa donde se hace referencia a esta cadena, veras algo así:
* Possible StringData Ref from Data Obj //"The evaluation period is finished."
:00407774 | 6858CF4300 | push 0043CF58 | // ESTA ES LA REFERENCIA A LA CADENA
* Possible StringData Ref from Data Obj //"%s"
:00407779 | 68A4C84300 | push 0043C8A4
:0040777E | 68409C4500 | push 00459C40
* Reference To: USER32.wsprintfA, Ord:02ACh
:00407783 | FF156C554300 | Call dword ptr [0043556C]
:00407789 | 83C40C | add esp, 0000000C
:0040778C | 6A10 | push 00000010
* Possible StringData Ref from Data Obj //"Flash"
:0040778E | 68F4CE4300 | push 0043CEF4 | // Titulo de la ventana
:00407793 | 68409C4500 | push 00459C40
:00407798 | 6A00 | push 00000000
* Reference To: USER32.MessageBoxA, Ord:01BEh
:0040779A | FF15E8544300 | Call dword ptr [004354E8] | // Muestra el cuadro de dialogo
:004077A0 | 5E | pop esi
:004077A1 | 33C0 | xor eax, eax
:004077A3 | 5B | pop ebx
:004077A4 | C21000 | ret 0010
Como puedes comprobar este código prepara el cuadro de dialogo y lo muestra con MessageBox, esto quiere decir que alguien tuvo que enviarnos aquí de alguna manera por lo que mirando los posibles saltos vemos que el primero viene de 40775Ah
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0040775A(C) * Possible StringData Ref from Data Obj //"The evaluation period is finished."
:00407774 | 6858CF4300 | push 0043CF58 | // ESTA ES LA REFERENCIA A LA CADENA
Esta dirección está justo por encima, si miramos el código superior encontraremos un salto en la dirección 407755A.
:00407732 | C7053098450000010000 | mov dword ptr [00459830], 00000100
:0040773C | 8915A4954500 | mov dword ptr [004595A4], edx
:00407742 | A32C984500 | mov dword ptr [0045982C], eax
:00407747 | 8915A4984500 | mov dword ptr [004598A4], edx
:0040774D | E81EC70100 | call 00423E70
:00407752 | 83C430 | add esp, 00000030
:00407755 | 48 | dec eax
:00407756 | 5F | pop edi
:00407757 | 744E | je 004077A7
:00407759 | 48 | dec eax
:0040775A | 7418 | je 00407774 | // ESTE ES EL SALTO QUE NOS ENVIA AL CUADRO DE DIALOGO
:0040775C | 6A00 | push 00000000
:0040775E | 6820614000 | push 00406120
:00407763 | 6A00 | push 00000000
* Possible Reference to Dialog: DialogID_009C
:00407765 | 689C000000 | push 0000009C
:0040776A | 56 | push esi
:0040776B | FFD3 | call ebx
:0040776D | 5E | pop esi
:0040776E | 33C0 | xor eax, eax
:00407770 | 5B | pop ebx
:00407771 | C21000 | ret 0010
Examinando este código podriamos suponer que EAX contiene algun tipo de flag que nos indica si el programa está o no registrado ya que si seguimos el flujo normal del programa vemos que este no llamaria a ningún cuadro de dialogo y volveria al proceso que lo llamo con un ret. Si suponemos lo anteriormente dicho, estamos en lo cierto (no es que sea adivino si no que lo he comprobado) ya que la función que es llamada en 4077D4 se encarga de leer la fecha de instalación del programa desde el registro de windows y comprobar la diferencia de tiempo con la función GetSystemTimeAsFileTime, puedes comprobarlo tu mismo si miras el codigo a partir de la dirección 423E70 (No lo he incluido por ser muy extenso). - Bueno pues ya sabemos que si cambiamos el salto por un par de NOPs (código 90h cada NOP) probablemente el programa funcionará aunque pasemos el límite de tiempo de 30 días. Para realizar esta modificación nos colocamos sobre la linea :0040775A asegurandomos que la linea azul del W32Dasm este sobre esta y ahora apuntamos el offset que nos marca en la barra de estado (este offset es la posición física del primer byte de la instrucción dentro del ejecutable) este valor debe ser 775Ah. Ahora nos vamos a nuestro editor hexadecimal favorito y abrimos el ejecutable original (Flash32.exe) nos vamos al offset 775Ah con las bunciones de busqueda de este (debe tenerlas) y cambiamos los bytes 74 18 por 90 90 salvamos los cambios y ejecutamos el programa. Sorpresa, funciona y han transcurrido más de 30 días desde la fecha de instalación. - Ahora vamos a capturar una porción del escritorio, click con el botón izquierdo sobre el icono de la barra de tareas Captures/Region, pulsamos OK y designamos un area rectangular de la pantalla con el mouse. El programa cogerá dicha porción y nos la presentará junto con una serie de menus. Vamos al menu Capture/Save as, le damos un nombre, seleccionamos los bpp de la imagen y la guardamos donde queramos, mientras se salva vemos que aparece la cadena 'Flash - Evaluation' sobreimpresa en la imagen y luego desaparece. si miramos la imagen que acabamos de salvar veremos que esta cadena a aparecido en ella, tapando con ello parte de nuestra captura, y esto no nos interesa. Bien sabemos que mensaje muestra por lo que podriamos intentar el mismo metodo que usamos con la cadena anterior, pero no sirve ya que la cadena 'Flash - Evaluation' no aparece en la lista de cadenas del W32Dasm, por lo que debemos pensar en otra solución. Pensemos, el programa imprime una cadena, por lo tanto necesitará llamar a alguna función del GDI de windows para imprimirla en pantalla. ¿ Que funciones de dibujo de texto nos proporciona el GDI de windows ? Unas cuantas pero las siguientes son las más usadas. TextOut,TextOutA DrawText,DrawTextA DrawTextEx,DrawTextExA Nota: La A final indica que es de 32bits. De estas tres funciones la más simple es la primera TextOut, podriamos suponer que el programador que hizo el Flash no quiso complicarse la vida y usó esta función para imprimir el texto. Recuerda, prueba primero lo más sencillo, suele funcionar el 90% de los casos. Pongamos el SoftIce en marcha. Probemos, vayamos hasta el cuadro de dialogo que nos permite introducir el nombre, pongamos uno y activemos el SoftIce (Ctrl+D) ahora ponemos un bpx textouta y un bpx textout (el programa es de 32 bits) y pulsamos g para continuar con la ejecución normal. Pulsamos el boton de OK para salvar y Ops!! estamos de nuevo en SoftIce. La función TextOut tiene un inconveniente, y es que es muy usada por el propio windows para escribir los nombres de los botones y de los menus, por lo que ahora deberemos ir pulsando g unas cuantas veces hasta que desaparezca por completo el cuadro de dialogo, cuando este desaparezca, continuaremos pulsando g y veremos que los nombres de los menus se van escribiendo, cuando se escriba el último 'Help' pulsamos g de nuevo y la proxima vez que entremos en SoftIce será para imprimir la cadena 'Flash - Evaluation' ahora ulsamos F12 hasta que llegemos al codigo fuente de FLASH32.EXE veremos algo así:
* Reference To: GDI32.TextOutA, Ord:0205h
:0041626E | FF1540524300 | Call dword ptr [00435240] | // Llama a TextOutA
:00416274 | 8B1518884500 | mov edx, dword ptr [00458818] | // Estamos aquí
:0041627A | 8B442418 | mov eax, dword ptr [esp+18]
:0041627E | 8B4C2414 | mov ecx, dword ptr [esp+14]
:00416282 | 50 | push eax
:00416283 | 51 | push ecx
:00416284 | 52 | push edx
:00416285 | 56 | push esi
Aquí está la llamada que imprime la cadena 'Flash - Evaluation', podriamos simplemente eliminarla con NOPs, pero esto no funcionaria y recibiriamos un (Protection Fault ya que habria que nopear los pushes previos a la llamada) despues de salvar la imagen (lo he comprobado). Cual es la manera más sencilla de hacer que no se imprima la cadena ? Antes de nada miremos el funcionamiento de la función TextOut segun el API de Windows. BOOL TextOut( HDC hdc, // handle del dispositivo de contexto int nXStart, // coordenada X del texto int nYStart, // coordenada Y del texto LPCTSTR lpString, // puntero a la cadena a imprimir int cbString // numero de caracteres a imprimir ); Pues hay varias: Una opción seria modificar las coordenadas del texto para que estuvieran fuera de la imagen, pero esto implica bastantes modificaciones en el código. La siguiente más sencilla y rápida de ejecución es cambiar el numero de caracteres a imprimir y decirle que imprima 0 caracteres o sea ninguno, esta es la solución. - Habiendo optado por la segunda opción debemos localizar donde se pasa (empuja) la longitud de la cadena como parametro para la función TextOut, como es una pila LIFO (último en entrar primo en salir) el numero de caracteres debera ser el primer PUSH de todos los que hay por encima de la función TextOut. Ahora apuntamos a dirección 0041626E que es donde se llama a TextOut y salimos del SoftIce. Nos vamos al W32Dasm y desensamblamos la copia del archivo original (es el Flash32.exx) , vamos al menu Goto/Code Location e introducimos el offset que nos apuntamos anteriormente (41626E) pulsamos OK y veremos algo asi:.
:0041623C | 8B442418 | mov eax, dword ptr [esp+18]
:00416240 | 6A12 | push 00000012 | // Empuja longitud de la cadena para TextOut
:00416242 | 99 | cdq
:00416243 | 2BC2 | sub eax, edx
:00416245 | 8B1518884500 | mov edx, dword ptr [00458818]
:0041624B | D1F8 | sar eax, 1
:0041624D | 3BC2 | cmp eax, edx
:0041624F | 7D0B | jge 0041625C
:00416251 | 8D8424B0010000 | lea eax, dword ptr [esp+000001B0] | // copia en eax puntero a 'Flash - Evaluation'
:00416258 | 50 | push eax | // empuja puntero a la cadena
:00416259 | 52 | push edx | // empuja coordenada X
:0041625A | EB09 | jmp 00416265
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0041624F(C)
:0041625C | 8D9424B0010000 | lea edx, dword ptr [esp+000001B0] | // copia en eax puntero a 'Flash - Evaluation'
:00416263 | 52 | push edx | // empuja puntero a la cadena
:00416264 | 50 | push eax | // empuja coordenada X
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0041625A(U)
:00416265 | 51 | push ecx | // empuja coordenada Y
:00416266 | 56 | push esi | // este es para la función GetDC
* Reference To: USER32.GetDC, Ord:00FDh
:00416267 | FF159C544300 | Call dword ptr [0043549C]
:0041626D | 50 | push eax | // Pasa el handle
:0041626E | FF1540524300 | Call dword ptr [00435240] | // ESTAMOS AQUI !!!!! llama a TextOut
:00416274 | 8B1518884500 | mov edx, dword ptr [00458818]
:0041627A | 8B442418 | mov eax, dword ptr [esp+18]
:0041627E | 8B4C2414 | mov ecx, dword ptr [esp+14]
Ahora buscaremos todos los los push que hay antes de la llamada al TextOut, sabemos que deben ser un máximo de cinco. En 41626E encontramos el primero. :0041626D 50 push eax -> Pasa el handle el segundo en : :00416265 51 push ecx -> coordenada X el tercero y el cuarto en: :00416258 50 push eax -> Puntero a 'Flash - Evaluation' :00416259 52 push edx -> coordenada Y y el quinto que es el nuestro en: :00416240 6A12 push 00000012 -> 12h = 18 -> longitud de 'Flash - Evaluation' Si no te aclaras examina de nuevo el código detalladamente y comprenderas su funcionamiento. - Bueno ya esta claro lo que hay que hacer o no ? . Claro, reemplazar el push 12 por un push 0. Actuaremos igual que hicimos para modificar el salto anterior, apuntar el offset y sustituir el 6A12 por un 6A0 dentro del ejecutable.Vamos intentalo sólo, es fácil. Una vez hechas las modificaciones, no volveras a ver ningun texto sobre tus capturas. - Como tarea adicional podriamos eliminar el cuadro de dialogo que aparece al salir del programa ya que es molesto y no sirve para nada. Para ello podriamos utilizar la técnica de buscar una referencia a las cadenas que este cuadro muestra, pero no encontrariamos ninguna. Bueno no te preocupes lo intentaremos de otro manera. Examina el cuadro de dialogo por un momento; no es un MessageBox convencional, por lo tanto debe ser un DialogBox, ademas este dialog box no retorna el control a la aplicación hasta que se sale de este. Piensa. Las funciones para la creación de cuadros de dialogos son las siguientes: CreateDialog CreateDialogIndirect CreateDialogIndirectParam CreateDialogParam DialogBox DialogBoxIndirect DialogBoxIndirectParam DialogBoxParam Pero como hemos dicho que el cuadro de dialogo no pasa el control a la aplicación hasta su finalización por parte del usuario, las 4 primeras quedan anuladas. Sólo nos quedan las siguientes. DialogBox DialogBoxIndirect DialogBoxIndirectParam DialogBoxParam Pues a que esperas, ejecuta el programa, activa el SoftIce y pon un bpx DialogBox, bpx DialogBoxIndirect, bpx GialogBoxIndirectParam, bpx DialogBoxParam, pulsa g y ahora sal del Flash32. Boom! el bpx DialogBoxIndirectParam ha surtido efecto, pulsamos F12 una vez y estaremos justo debajo de la llamada a este, veras algo así en el SoftIce:
:00406A3F | A124A24500 | mov eax, dword ptr [0045A224]
:00406A44 | 6A00 | push 00000000
:00406A46 | 6830214200 | push 00422130
:00406A4B | 56 | push esi
:00406A4C | 6805010000 | push 00000105
:00406A51 | 50 | push eax
* Reference To: USER32.DialogBoxParamA, Ord:0093h
:00406A52 | FF15A8544300 | Call dword ptr [004354A8] | // Muestra el cuadro de dialogo
:00406A58 | 85C0 | test eax, eax | // ESTAMOS AQUÍ
:00406A5A | 0F8498080000 | je 004072F8 | // Si no se pulso OK (EAX=0) no saldrá del
:00406A60 | 56 | push esi | // programa
:00406A61 | E88A360200 | call 0042A0F0
:00406A66 | A1FC904500 | mov eax, dword ptr [004590FC]
:00406A6B | 83C404 | add esp, 00000004
:00406A6E | 85C0 | test eax, eax
:00406A70 | 7413 | je 00406A85
:00406A72 | 56 | push esi
Examina el código y veras que este es nuestro hombre, se empujan cinco argumentos a la pila se llama a la funcion que muestra el cuadro de dialogo y se comprueba el valor de EAX, si EAX=1 se pulsó el botón OK y se sale de la aplicación, si se pulsa el botón cancelar, EAX=0 y no se saldrá de la aplicación. Los cinco argumentos que se empujan a la pila son para la función DialogBoxParamA ,fijate que esta función usa la función DialogBoxIndirectParam para crear dicho cuadro. Aquí tienes una descripción del funcionamiento de la función DialogBoxParamA int DialogBoxParam( HINSTANCE hInstance, // handle a la instancia de la aplicación LPCTSTR lpTemplateName, // identifica el cuadro de dialogo HWND hWndParent, // handle a la ventana propietaria DLGPROC lpDialogFunc, // puntero a una función que controla el cuadro de dialogo LPARAM dwInitParam // valor de inicialización ); - Pues ahora se trata de eliminar el cuadro de dialogo pero, ¿ como ?, fácil primero hay que eliminar los 5 push previos ha la llamada a DialogBoxParamA , luego eliminar la llamada y hacer que EAX siempre valga 1. Aquí puedes ver el código modificado.
:00406A3F | A124A24500 | mov eax, dword ptr [0045A224]
:00406A44 | 90 | nop |
:00406A45 | 90 | nop |
:00406A46 | 90 | nop |
:00406A47 | 90 | nop |
:00406A48 | 90 | nop |
:00406A49 | 90 | nop |
:00406A4A | 90 | nop |
:00406A4B | 90 | nop |
:00406A4C | 90 | nop |
:00406A4D | 90 | nop |
:00406A4E | 90 | nop |
:00406A4F | 90 | nop |
:00406A50 | 90 | nop |
:00406A51 | 90 | nop |
:00406A52 | B801000000 | mov eax, 00000001 | // Aquí estaba el Call
:00406A57 | 90 | nop |
:00406A58 | 85C0 | test eax, eax | // Fin de las modificaciones
:00406A5A | 0F8498080000 | je 004072F8
:00406A60 | 56 | push esi
:00406A61 | E88A360200 | call 0042A0F0
:00406A66 | A1FC904500 | mov eax, dword ptr [004590FC]
:00406A6B | 83C404 | add esp, 00000004
:00406A6E | 85C0 | test eax, eax
:00406A70 | 7413 | je 00406A85
:00406A72 | 56 | push esi
- Bueno esto es todo, las modificaciones las dejo a tu cargo para que practiques, recuerda, buscar el offset del primer byte de la instrucción, apuntar las modificaciones desde esta posición y con el editor hexadecimal que prefieras realizar las modificaciones. Que te ha parecido el tutorial ? Es cierto que podriamos haber atacado por otros puntos pero yo le he hecho de la manera que me ha sido más facil. Recuerda un programa puede hacerse de varias maneras, un crack tambien pero siempre es mejor usar la manera más corta y la que implique menos modificaciones.
[ Entrada | Documentos Genéricos | WkT! Web Site ]
[ Todo el ECD | x Tipo de Protección | x Fecha de Publicación | x Orden Alfabético ]
(c) Whiskey Kon Tekila [WkT!] - The Original Spanish Reversers. Si necesitas contactar con nosotros , lee esto antes e infórmate de cómo puedes ayudarnos