ESTUDIO COLECTIVO DE DESPROTECCIONES | ||
WKT Tutorialz Site | ||
Programa | Reversing with ToPo v1.0 | W95 / W98 / NT |
Descripción | Pequeña utilidad para ampliar ejecutables y DLLs | |
Tipo | Herramienta win32ASM para Ingeniería Inversa | |
Url | http://i.am/MrCrimson | |
Protección | Ninguna. Freeware cortesía de MrCrimson/[WkT] | |
Dificultad | 1) Principiante, 2) Amateur, 3) Aficionado, 4) Profesional, 5) Especialista | |
Herramientas | Uedit y (opcionalmente) SoftICE | |
Objetivo | Ampliar las posibilidades de cracking | |
Cracker | MrCrimson/[WkT!99] | |
Fecha | 23 de Octubre de 1999 |
Introducción |
Los esquemas de protección de software pueden dividirse en dos grandes grupos. Los que se apoyan en dispositivos de hardware y los que lo hacen exclusivamente en el software. Los metodos soft pueden a su vez dividirse en aquellos en los que la limitación de la versión es condicional (Serial, fecha limite, numero de usos) y en los que es incondicional (opciones físicamente eliminadas del codigo) Salvo la elegante alternativa de los KeyMakers y los RegPatches, el resto de las desprotecciones exige que se realicen CAMBIOS en ficheros binarios, ya sean datos o instrucciones de codigo. Una regla de oro del crackista (que palabro!) consiste en que
la modificación binaria propuesta debe PARCHEAR los contenidos existentes
SIN AÑADIR un sólo byte.
"...sólo modificar en el fichero los bytes existentes y además en mínimo número..." Sin embargo, hay un "paquete" de situaciones en las que esta restricción se hace un tanto insoportable y que podría responder a la siguiente clasificación:
Pero cómo se consigue expandir el área de código de un programa en una forma segura y estable...? La respuesta tiene nombre de bicho: ToPo v1.0. |
ToPo: Arreglando el cuarto de invitados |
ToPo v1.0 es una utilidad que permite añadir a un ejecutable (o DLL) una extensión vacía para ser rellenada con código fresco. Podemos añadir típicamente una decena de estas "extensiones ortopédicas" dependiendo de la estructura interna del fichero. Entonces podremos hexeditar y añadir nuevas rutinas, parchear el código en memoria, reconstruir código incompleto, diseñar emuladores de dongle, trainers para juegos...y todo ello sin limitación de espacio! (~ 10 Mb) El principio en que se basa la herramienta es muy simple. La estructura del formato PE (ejecutables y librerías Win32) consiste en una colección de cabeceras con multitud de datos (muchos no usados para nada). Entre las cabeceras más importantes están las llamadas cabeceras de sección. Son paquetes de 40 bytes donde se definen las características de los bloques de datos del programa (código, constantes, iconos, punteros, etc). La zona en que habitan estas cabeceras suele disponer de espacio libre para añadir del orden de 10 nuevas y nada impide que un programa tenga mas de una seccion de código (como ejemplo sirvan los empaquetadores en los que la rutina de desempaquetado suele alojarse en una sección propia). Así las cosas podemos DECLARAR una nueva sección del tamaño que nos apetezca y AÑADIRLA al final del fichero sin ningún tipo de problemas. El nuevo invitado tendrá un "segmento" de direcciones a las que (y desde las cuales) se podrá acceder al resto de la imagen del fichero en memoria. Reinventando los virus, MrCrimson? bueno cada cual es
libre de inocular lo que le parezca... personalmente prefiero darle aplicaciones
constructivas como el CrAcKiNg!
|
ToPo: Bichos en el jardín |
Este es el cuadro de diálogo de la herramienta perforadora. El usuario solo tiene que seleccionar su fichero víctima (32 bits only, plz) e indicar cuantos bytes necesita para escribir su código. El click en "Do It!" informa acerca del éxito del resultado y de donde puede localizarse el nuevo inquilino (tanto en memoria como en fichero). Las opciones permiten:
|
Ejemplo (1): Adición de código nuevo |
Como víctima utilizaremos un programa del que todos disponemos: el bloc de notas (ejecutable: "notepad.exe" alojado en "\windows"). Vamos a añadir un trozo de código de 100 bytes con una llamada API. Para ello haz una copia en otro directorio y arranca ToPo v1.0:
Vamos a hacer que el NOTEPAD genere una especie de splash precaria esperando confirmación antes de arrancar. Todos conoceis ya la sintaxis de la función MessageBox: push Estilo
Como estilo elegimos el más simple: un simple botón "OK"
(valor 0)
Ahora, la forma más fácil de proceder consiste en arrancar
Winice y con el comando "A"
-Escribimos todas nuestras constantes y variables a partir del 3er byte.
(*) el número exacto dependerá del tamaño de los datos). Por ejemplo: :40C000 jmp 40C005
el offset :40C002 contiene la cadena "hola" y podemos usarlo como argumento en nuestras llamadas a función. De esta misma forma se definen variables y constantes en general (el segmento ".topo" tiene atributos de leible, escribible y ejecutable!). No os preocupeis si Winice o W32Dasm interpretan las variables así definidas como instrucciones de código inexistentes. Es normal. Intentan desensamblar lo inensamblable... Después escribimos los pushes, la llamada a MessageBox y dejamos el resto como está (una sucesión de NOPs hasta el JMP [original_entrypoint]. Copiamos con buena letra el código ensamblado resultante en un papelito y abandonamos Winice no sin antes haber borrado lo escrito restaurando los NOPs originales. Ahora hexeditamos (Uedit) el notepad.exe, nos vamos al offset donde comienza la sección ".topo" y tecleamos el churro de bytes. Cerramos y ejecutamos notepad obteniendo la ventana esperando confirmación para iniciar el "Bloc de Notas". En este ejemplo, el código añadido tiene este aspecto: //******************** Program Entry Point ********
:0040C03D 6A00
push 00000000 ; estilo 0
* Reference To: USER32.MessageBoxA
La llamada a MessageBox parece un tanto misteriosa (offset :407430) pero los bytes que componen la instrucción pueden obtenerse fácilmente ensamblando desde Winice la linea: call dword ptr[MessageBoxA] NOTA: En la primera versión
de este tute un descuido me llevo a codificar esta llamada mediante:
Una vez completado ejecutamos notepad y obtendremos una ventana con una mesaje chorra esperando un click en el OK para proseguir con el "bloc de notas". Este ejemplo ha mostrado como INCRUSTAR un trozo de código de ~100 bytes donde aparentemente no cabría un alfiler. :o) |
Ejemplo (2): Parcheador de Empaquetados Universal |
Por lo general, los empaquetadores/encriptadores de ficheros operan según una idea común. El código util está cifrado de manera que desensamblando no se puede analizar su comportamiento. En el momento de la ejecución entra en juego una rutina que escribe en memoria la versión no-encriptada y a partir de ese momento todo transcurre como si de un ejecutable normal se tratara. La forma de atacar a estos programas tan poco comunicativos se basa en cargadores o loaders. Un cargador es un programa capaz de cargar en memoria otros ejecutables y detenerse antes de comenzar su ejecución de manera que puede aprovecharse la ocasión para realizar los oportunos parcheos. Sin embargo son fáciles de engañar y tienen problemas para "seguir la pista" a nuevos threads (al menos los que he podido examinar). ToPo no tiene este tipo de problemas porque genera un "enemigo interior"
que puede actuar justo después del desencriptado del código
cualquiera que sea el algoritmo. Como ejemplo veremos como funciona con
un par de empaquetadores de élite.
(a) UPX v0.84 Intentamos repetir la gracia anterior con una versión de Notepad.exe
empaquetada con UPX.
C:\> upx -9 notepad.exe y ya está. Pfff....reducido a la mitad de tamaño!. Me encanta este packer :o) Ahora debemos añadir nuestra burbuja pero esta vez NO queremos
redirección del entrypoint ya que este hace referencia al comienzo
de la rutina de descompresión y no
A partir de aqui todo se reduce al caso anterior. Disponemos del código
desempaquetado en memoria ANTES de comenzar la ejecución. Añadimos,
como antes, nuestras "strings", los pushes y la llamada a messagebox (no
copiar directamente porque las direcciones relativas no son las mismas).
Por ultimo cerramos con un JMP al entrypoint de notepad :401000.
(b) ASPack v1.08.03
Este packer presenta algunas diferencias con el anterior. La compresión no es tan buena pero a cambio establece "potentes" medios de protección del código empaquetado. Siguiendo el ejmplo anterior intentaremos ejecutar nuestra lamer-splash al comienzo de la ejecución del notepad. Con las pautas ya explicadas (BPM a la primera instruccion del notepad, :401000) intentamos cazar el final de la rutina de descompresión para saltar desde allí a nuestra fortaleza de código en blanco. Y facilmente la encontramos en: .........................
Cuando abrimos "notepad.exe" con Uedit para buscar este trozo de código
descubrimos que NO ESTA. Impresionante. La rutina que desencripta esta
también encriptada.
:40C0AE REPZ MOVSD
Este código SI esta accesible (bueno estaría que no) y perfectamente editable. Vamos pues con Uedit y modificamos la instrucción en :40C0b7 según: :40C0B7 JMP 40F000 <---salto a la sección ".topo" No debemos preocuparnos por las modificaciones que hacemos para acceder
al ".topo" porque antes de regresar restauraremos todo.
;Parcheamos el codigo en :40C554 por "jmp
40f032"
:0040F000 mov dword ptr [0040C554], 002AD9E9
;Restauramos el contenido en :40c0b7 a su
:0040F011 mov dword ptr [0040C0B7], 50B5858B
;regresamos a :40c0b7 como si nada hubiera
:0040F024 jmp 0040C0B7 Perdidos...? Recapitulemos: hemos parcheado con Uedit la rutina que
desempaqueta al desempaquetador del codigo. El objeto del parche es establecer
un acceso a ".topo" que
La segunda mitad de ".topo" contiene el siguiente codigo más familiar: :0040F032 60
pushad ;por seguridad
; strings usadas para la ventana messagebox
:0040F070 6A00
push 00000000 ;estilo 0
* Reference To: USER32.MessageBoxA
;Restauramos las instrucciones que habia antes
del salto
:0040F084 C70554C540008944241C mov dword ptr [0040C554],
1C244489
Y así acaba esta historia.
|
Conclusión |
La técnica ilustrada resuelve dos inconvenientes clásicos
del Arte del Cracking. Por una parte la tradicional limitación de
espacio que nos impide en ocasiones generar productos más creativos.
Por otro lado se trata de una estrategia "en caliente" puesto que trabaja
desde dentro del código como una parte más del programa original.
Como inconveniente citar el hecho de que cambia el tamaño de
fichero y por tanto los clasicos parcheadores de diferencias no trabajarian
con éxito.
Eso es todo por el momento. Este tutorial era originalmente más
largo pero creo que con los ejemplos propuestos queda claro lo que se puede
hacer con esta técnica.
Los ejemplos de este tute están aquí (47kb): ejemplos.zip
Up The Hammer!
|
[ Entrada | Documentoz GenΘricoz | WKT TEAM Main Site ] |
[ Todo el ECD | x Tipo de Protecci≤n | x Fecha de Publicaci≤n | x orden AlfabΘtico ] |