ESTUDIO COLECTIVO DE DESPROTECCIONES
Última Actualizacion: 25/10/2001

Programa

Como crackear por Estado+Porcino

Capítulo 8

De café con la señorita Ingenería inversa.

Decafé v3.8

W95 / W98 / NT 
Descripción Decafé es un excelente decompilador de Java.Tomad una clase compilada en java (ficheros con extensión *.class) y esta maravilla os devuelve el código fuente.
Tipo Crippleware
Tipo de Tutorial [X]Original, []Adaptación, []Aplicación, []Traducción
Url http://Decafe.hypermart.net
Protección Comprimido con el petite v2.1, Función de salvar inexistente.
Dificultad 1) Principiante, 2) Amateur, 3) Aficionado, 4) Profesional, 5) Especialista 
Herramientas Debugger:Softice v4.1
Editor Hexadecimal: Uedit
Descompresor:Procdump v1.5 con el cliente Petite v2.1
Ayuda del api del Win32:MS Visual C++5.0 o Borland 5.0
Ensambladores:TASM o MASM
Desensambladores:IDA 3.8b y Wdasm 8.3
Detector de compresión: FileAnalizer v15.
Formato PE: PEDaL de Mr.Crimson.
Objetivo Incorporar una función de salvar.
Cracker Estado+Porcino
Grupo Whiskey Kon Tekila
Fecha Noviembre 1999
 


INTRODUCCION
Saludos Familia.
Antes de acabar este año fatídico quiero aportar un granito con un material que me parece muy interesante: La Ingeniería Inversa.
En este capítulo aprenderemos cositas muy interesantes:
Como añadir una rutina de salvado a cualquier programa, como parchear ficheros comprimidos, como chapucear con las cabeceras PE y sobre todo la técnica de redirección, herramienta clave para la Ingeniería Inversa.
CRACKING vs INGENIERÍA INVERSA
La Ingeniería Inversa (II), es el ARTE de poder modificar el comportamiento de un programa para que realice las tareas que deseemos. Esto incluye evitar las protecciones software,impedir que caduque etc. Pero además incluye poder añadir más funcionalidad al susodicho programa.
Uno pensará, bueno, ¿y ésto de la II que tiene que ver con el cracking?.
Pues mucho. El cracking se puede considerar el hermano pequeño de la II.
Con él solo podemos impedir que zonas de código de ejecuten(rutinas de registro) o que no se ejecute (rutinas de protección).Como ves, la funcionalidad es más bien cortita, sólo podemos activar o desactivar código pero nada más. Existen programas que no son crackeables desde el punto de vista del crack (como el ejemplo de este capítulo), pero no es así para la II. Con la II se puede transformar el notepad en un reproductor de mp3 que sea servidor de páginas web y que permita aproximar integrales. Con la II el cielo está abierto para el cracker (mejor dicho ingeniero inverso), y es ahí donde debemos navegar :-)
CAFE DE LOS MUY CAFETEROS
Para practicar la II, nada mejor que un programa que merezca el esfuerzo. Decafé es un excelente decompilador de Java.Tomad una clase compilada en java (ficheros con extensión *.class) y esta maravilla os devuelve el código fuente. Si, habeis leido bien, el codigo fuente. Es una de las ventajas\desventajas de Java, según se mire.En los tiempos que corren y en los futuros, un decompilador de Java será esencial, así que apuntémonos al carro.
El Decafé tiene un par de detalles que lo hacen inicialmente difícil y finalmente incrackeable. Tanto el ejecutable como la librería que lo acompañan están comprimidos con el Petite 2.1, para comprobarlo basta con abrir ambos con un heditor hexadecimal y ver: Compressed by Petite (c)1999 Ian Luc. Para averiguar la versión podemos utilizar algún detector de compresión como el fileAnalizer15.
Así pues, la cosa se pone fea, no lo vamos a tener fácil para crackear, primero debemos descomprimir. Esto lo hacemos fácilmente con la maravillosa herramienta Procdump 1.5. Abrimos el Brahama Server y lanzamos el cliente Petite 2.1.Recuperamos el ejecutable sin demasiados problemas.
Pero, sorpresa, la función de salvar no está activada. Con un poco de suerte, y rogando a +ORC el código de la función estará desactivado y con un poco de cracking la podremos poner en marcha. Joder, pues no ha habido suerte. Si miramos el código, el código para salvar no aparece, mejor dicho, no existe.
Por tanto el Decafé es incrackeable (al igual que otros muchos programas).
LA II AL RESCATE
Traaaaaaaaaaaanquilos. Pensemos un poco. No somos miembros del culto a la II. No nos gustaría retozar con esa moza de la II hasta hartarnos... Sipe, ¿y porqué no añadimos el código que falta?, ¿por qué no construimos nuestra propia rutina para salvar a fichero el código descompilado?, ¿por qué no hacemos realmente II?

La idea es sencilla, necesitamos algo así como:
Pide el nombre del fichero
Crea un archivo con ese nombre
Escribe en el fichero lo que deseamos guardar
Cierra el fichero

Fácil, ¿verdad?, pues manos a la obra.
Lo primero que necesitamos es el código que haga lo que deseemos. Para ello tiramos del API del win32 que podemos encontrar en la ayuda del Mirda$oft 5.0 o en el Borland 5.0. Creamos el código para salvar, se lo añadimos al ejecutable y redirigimos las llamada de salvar a nuestro código. Y hecho esto nos habremos ganado los galones de la II
LA SALVACION GENERICA
Para construir el código que necesitamos nada mejor que un poco de Win32ASM, osea, ensamblador de 32 bits para Windows, aunque de puede usar el IDA, el SICE o si se es hombre en hexadecimal direstamente con los códigos de operación
Para facilitar el trabajo he construido un código genérico y relocalizable para salvar un fichero gobernado por 5 parámetros que después aclararemos.
Es importante tener en cuenta una cosa. El programa que deseemos modificar puede o no tener importadas las funciones que necesitemos. Si las tiene se solucionan muchos problemas, si no las tiene hay que calentarse la perola. En nuestro caso las funciones que vamos a usar no está importadas (basta con ver la sección de "imported" en el desensamblado) ME CAGO EN MI CALAVERA. ¿Como solventamos la papeleta?

Para que no nos tiremos a un puente (o a la novia/mujer/novio/gato/hamster (eso va por ti gordita)) recurramos al API32. Existen dos bonitas funciones que vienen a nuestra ayuda GetmodulehandleA,GetProcAddress. En este momento, descuidadamente nos agenciamos de la polvorienta API32 que tanto utilizamos.
La idea es obtener la dirección de memoria donde se encuentra la librería que posee las funciones que necesitamos. GetmodulehandleA nos dá el handle de la librería y GetProcAddress la dirección de la función deseada.Basta con hacer un "call" a esta dirección y nos olvidamos si la función está o no importada.
En el código adjunto, las llamadas a las funciones se realizan de esta manera. El código es autosuficiente y relocalizable para que pueda ser añadido a cualquier programa. Sólo hay que modificar 5 parámetros:
1º Dirección de inicio de los datos. Basta con modificar la instrucción :0048C0EC con la dirección en la que se pege el código
2º Dirección de la rutina GetmodulehandleA. Modificar :0048C0F7. Para averiguar la dirección exacta. nos vamos al SoftIce ponemos "u GetmodulehandleA"
3º Dirección de la rutina GetProcAddress. Modificar :0048F104 .Para averiguar la dirección exacta. nos vamos al SoftIce ponemos "u GetProcAddress"
4º Parámetro 1º+0x0D0 con la dirección inicial que será salvada en el fichero.Esto lo haremos con la técnica de Infiltación que veremos más tarde.
5º Parámetro 1º+0x0D4 con el número de bytes a salvar.
Esto lo haremos con la técnica de infiltación que veremos más tarde.

Estas dos últimas rutinas (GetmodulehandleA,GetProcAddress) deben estar siempre importadas,aunque creo que se situan siempre en la misma posición de memoria, por lo que sólo habría que suministrar el 2º y 3º parámetro, pero si me equivoco, sed benévolos.

Para averiguar la dirección de GetmodulehandleA y GetProcAddress a las bravas, saltais al Softice y poneis "u GetmodulehandleA" y "u GetProcAddress" y listo, la primera dirección que aparezca es la vuestra. Ahí va esta pequeña maravilla que nos resuelve el trabajo sucio. El código está profusamente explicado. Recomiendo una lectura pausada con un buen trago y una mejor compañia
Tamaño de los bytes a añadir :0x1e0
La zona de ceros entre el nombre de las funciones y el código se usa como buffer para el getsaveopenfilename, como el buffer para guardar el nombre del fichero y como zona de datos para guardar el tamaño y el inicio de fichero. Estructura:
	
[0x48f000,0x48f0D0]  Strings y constantes.	
        :0048C000 Kernel32
	:0048C009 CloseHandle
        :0048C015 CreateFileA 
	:0048C021 WriteFile
	:0048C02B Comdlg32
	:0048C034 GetSaveFilenameA
	:0048C045 lpstrTitle=Save Java Source
	:0048C056 lpstrCustomFilter =Java Source (*.class)  *.class
	:0048C077 Estructura del GetSaveFilenameA
	:0x48f0C8 Dirección GetModuleHandlea 
	:0x48f0CC Direccion GetProcAddress	
	:0x48f0D0 Puntero al principio del fichero
	:0x48f0D4 Tamaño del fichero	
	
[0x48F0D0] Codigo
Pulsa aquí para ver el código en formato *.txt

RELLENANDO EL PAVO
De los 5 parámetros los tres primeros los tenemos directamente rellenos. Nos faltan la dirección de inicio del fichero a salvar y el tamaño para tener el pavo relleno. Debemos bucear en el código hasta encontrarlos. La técnica es sencilla, descompilemos una clase grandota y busquemos una secuencia del texto en memoria con el Softice. Para trabajar dentro de la memoria del proceso, pongamos un "bpx getopenfilenamea" y un par de 'f12' despues llegamos a algo parecido a 'call [ebp+14]'. Esta es la llamada principal a los menús. Si ponemos un bpx en la dirección de 'call [ebp+14]' y pulsamos 'f12' podremos buscar tranquilamente.
Si hombre, usemos eso de "s 30:00 l ffffffff 'Decompiled by Decafé PRO' posamos un delicado bmp xx:xxxxxxxx w en todas las ocurrencias que encontremos y decompilamos de nuevo. Aparecemos aquí:
:00435DA9 8B4C240C                mov ecx, dword ptr [esp+0C];ECX=tamaño del fichero.
:00435DAD 56                      push esi
:00435DAE 8B74240C                mov esi, dword ptr [esp+0C];ESI=Fichero decompilado
:00435DB2 57                      push edi
:00435DB3 8B7C240C                mov edi, dword ptr [esp+0C]
:00435DB7 8BC1                    mov eax, ecx; 
:00435DB9 8BD7                    mov edx, edi
:00435DBB C1E902                  shr ecx, 02
:00435DBE F3                      repz;APARECEMOS AQUIIIIIIIIIIIIIIIII
:00435DBF A5                      movsd
:00435DC0 8BC8                    mov ecx, eax
:00435DC2 8BC2                    mov eax, edx
:00435DC4 83E103                  and ecx, 00000003
:00435DC7 F3                      repz
:00435DC8 A4                      movsb
:00435DC9 5F                      pop edi
:00435DCA 5E                      pop esi
:00435DCB C20C00                  ret 000C
Las direcciones de memoria pueden ser diferentes en tu cacharro. Recordemos a los olvidadizos que el "repz" copia "ecx" bytes desde "esi" a "edi". Así pues es lo que necesitamos, en ecx el tamaño y en esi la dirección de comienzo del código desensamblado. Esta rutina es llamada en ":435e8f call [eax+64]" con "eax=451554". Esta es una típìca llamada rutina por tabla. Es decir, existe una tabla de inicio de rutinas y se llama a la rutina 0x64 de esa tabla. Si buscamos el inicio de la rutina '435da9' en el ejecutable aparece, pero recordad de buscar al revés, la jodienda del uso del formato little-endian es una de las condenas que hay que arrastrar. Así pues, si cambiamos '435da9' por el inicio de nuestra rutina y obtenemos una redirección de una forma muy elegante.

Existe un problema con ficheros decompilados grandes, ya que el valor de tamaño que calculamos es menor del real, así que debemos ir a otro sitio a por los valores reales. Buceando un poco llegamos a la llamada en :4142a8 que realiza todo el trabajo sucio de la decompilación en la librería comprimida. Mas abajo en :4144bb descubrimos en "eax" el tamaño del fichero y en "ecx" el comienzo del fichero a salvar. Así que colocaremos nuestros hocicos impúdicos en estos lares. Seguro que escarbando en la pila tras la llamada a la librería en :4142a8 descubrimos estos mismos parámetros, pero en :4144bb tienen un luminoso encima :-)
Una vez que sabemos donde están los "regalos" debemos de copiarlos en nuestra zona de datos. Si, esa zona que reservamos en el buffer del getopenfilenamea.
Tenemos que añadir algo así como:
BE 00 F0 48 00	mov esi, 48F000h;Dirección base de la zona de datos.
8D 7E D4		lea edi, [esi+d4h];
8B 7C 24 0C		mov [edi],eax;Copiamos el tamaño.
8D 7E D0		lea edi, [esi+d0h];
8B 7C 24 06		mov [edi],ecx;Copiamos la dirección de inicio del fichero  
DESEMPAQUETANDO LOS REGALOS
Todo esto está muy bonito pero, la vida es como una caja de bombones
Nuestro programilla está envuelto con el empaquetador de ejecutables Petite 2.1. Por tanto no podemos modificar ni un sólo byte sin que todo se vaya a la mierda, adios a nuestros juegecitos con el getopenfilenamea.

El por qué los programadores utilizan un empaquetador hay que buscarlo en motivos de seguridad más que en reducir el tamañó del ejecutable. Inicialmente no podemos parchear un programa empaquetado, así que pensemos. O mejor aún, leamos el excelente artículo de Mr.Crimson del grupo español de crack [WkT!] donde nos enseña hábilmente a evitar los empaquetadores. La idea básica es parchear el código del desenpaquetador para que salte a nuestras rutinas después de hacer su trabajo. Recomiendo, la lectura del fichero de texto que viene con el cliente del Petite 2.1 para el ProcDump donde nos enseña a entender el funcionamiento del desenpaquetador. Nuestra aproximación será modificar el ejecutable para añadir el código que parchea el desenpaquetador con el objeto de obtener el control cuando el programa esté operativo. Necesitamos bastante espacio, la idea es unir el código de parcheo del empaquetador y el código para salvar. Para añadir gran cantidad de código debemos añadir una nueva sección a la cabecera PE o aprovechar los huecos.

En este momento es cuando sacamos esos apuntes del formato PE y un visor de este jodio formato. De nuevo recurrimos a Mr.Crimson y su utilidad PEDAL para poder mirar y entender algo (aunque se puede usar otra herramienta). Tenemos 4 secciones: .text,.rscr,.petite y una fantasma sin nombre y tamaño 0.La solución es clara, usaremos esta sección sin nombre para acomodar nuestro código de parcheao del desenpaquetador y también nuestro código para salvar el fichero desensamblado. Si no tuvieramos esta sección fantasma podemos añadir una, como se explica en el artículo de c0v3rt+ "Adding sections to PE Files" o bien usar de nuevo otra herramienta de Mr.Crimson llamada TOPO (prolífico este ente,¿verdad?) ep8topo.txt
Inicialmente la seccion tiene las siguientes características:
Nombre:vacio
Relative Virtual Address(RVA)=8C000
Size=0
Pointer to Raw Data (Offset)=0
Flags:C2000080
Queremos añadir 768 bytes que hexa es 0x0300,al final del fichero en la posición 0x04e824. Así pues abramos el ejecutable para realizar estos cambios hasta obtener:
Nombre:E+P
Relative Virtual Address(RVA)=8C000
Size=0x0300
Pointer to Raw Data (Offset)=4E824
Flags:E8000060 (Objeto de código,inicializado,no paginable,de lectura, de escritura,ejecutable)
Hay que ajustar un par de parámetros más como son el tamaño del código (Size of Code) y el tamaño de los datos no inicializados (Size initializated data) .Todos ellos hay que incrementarlos con el tamaño del código añadido.Los cambios son:
Size of code:0x4CE00 pasa a 4D100
Size initializated data:3A000 pasa a 3A300
Nuestro código empieza en 0x48c0d4.






Con esto ya tenemos espacio para trabajar, resta la parte más interesante, la Redirección.
REDIRECCION
Ésta es la técnica básica que se debe aplicar en ingeniería inversa. Recordemos que el código que queremos modificar no es nuestro, por tanto no es probable que haya sitio para poner nuestros "añadidos". Es por esto que debemos procurarnos el sitio adecuado y desviar el flujo de control a nuestro código y despues seguir normalmente.Esta es la técnica básica: localizar el código que deseamos modificar (normalmente porque posee alguna variable interesante copiar o modificar) y colocamos un salto a nuestro código.Esto es la redirección. Normalmente el salto es de tipo far, osea, que ocupa 5 bytes, esto implica que debemos cambiar 5 bytes del código original aunque esto corrompa el código restante. Pero no importa porque no se ejecutará corrompido. Vemos un ejemplo (los códigos de operación no son los reales, pero seguro que ni siquiera os dais cuenta :-))):
:40c0c0 8B D7           mov edx, edi
:48c022 66 C7 06 56 33  mov word ptr [esi],5e56;
:48c027 c0 E9 D3 45 00  mov esi,45D3F9
Queremos colocar un salto en :40c0c0 a:48aabb que en hexa es "e9 de fe aa b7" por ejemplo, con lo que nos queda:
:40c0c0 e9 de fe aa b7  jmp 48aabb
:40c0c5 56              push esi
:40c0c6 33 c0           xor ax,ax
:40c0c8 E9 d3 45 00     jmp 500
Como podeis apreciar el código a partir de :40c0c5 no se parece ni remotamente al original. Está corrupto y si lo intentamos ejecutar a lo vivo nos revienta en las narices. Así pues, debemos borrar el estropicio dejando las cosas como estaban.Esto es lo último que debe hacer nuestro código, borrar nuestras zarpas. Siguiendo en el ejemplo:
:48aabb 40 		inc eax; Aquí comienza nuestro fabuloso código capaz de sodomizar a la protección más jodida.
...
...
:48FFEF         push esi;Guardamos el registro ya que lo vamos a usar
:48FFF0         mov esi,40c0c0; Dirección donde insertamos nuestro salto
:48FFF4         mov dword ptr [esi],c766d788 ;Primero 4 bytes del :40c0c0 original pero al revés. 
:48FFF8         mov byte ptr [esi+4],06;Último byte a restaurar del original.Así habremos borrado todo rastro de infiltración
:48FFFA         pop esi;Recuperamos el valor original
:48FFFB         jmp  40c0c0;Volvemos al pùnto donde bifurcamos, con la segiridad que todo está impecable

Es importante dejar todos los registros como antes de la redirección para no tener efectos laterales. Además es vital que en el encabezado PE la sección donde valos a colocar el jmp tenga activado el flag de escritura, sino, nuestro programa cascará en mov dword ptr [esi],c766d788. ¡Oido al parche!esta técnica es cojonuda para reventar al softice,engañar al Ida, joder el Dasm o volver loco al un cracker medio.
REDIRECCION APLICADA A COMPRESORES
Cuando nos enfrentamos a un programa comprimido que deseamos modificar debemos optar por dos opciones:

a) Descomprimir el ejecutable y parchearlo normalmente. Esto puede originar problemas: por ejemplo si el ejecutable utiliza librería que tambíen están comprimidas (como en el Decafé). Además de problemas de cálculo del punto de entrada al ejecutable o problemas de cálculos de saltos y llamadas a rutinas que pueden estar desplazados.
b) Parchear el ejecutable. Nos ahorramos todos los problemas anteriores, pero aparecen otros nuevos.Debemos esperar a que la rutina de descompresión acabe su trabajo antes de parchear, para ello debemos redirigir justo antes del salto a la primera instrucción del programa descomprimido. Calcular el punto exacto puede resultar complejo . Las cosa se complican si la rutina de descompresión descomprime por niveles, como es nuestro caso del Petite en el Decafé.

La píldora roja es la que conduce al conocimiento, traguemos saliva y cojamos la opción b)
REDIRECCION APLICADA AL COMPRESOR PETITE 2.1
Tanto el ejecutable como la librería que utiliza el Decafé están comprimidos con el Petite 2.1.Podemos tener una descripción del funcionamiento del Petite con la doc que acompaña el Brahama Client para el petite 2.1 del Procdump. Las cosas nos son sencillas. El compresor utiliza 4 niveles de descompresión. Cada nivel descomprime el siguiente y sólo al final queda al descomprimido todo el programa y se conoce el salto a la primera instrucción. En tal caso debemos aplicar reiteradamente redirección en cada nivel.La primera vez se hace a pelo sobre el ejecutable, estamos en el nivel 1 y el código de este nivel no necesita ser descomprimido.En nuestra 1º redireccíon ya debe estar el 2º nivel descomprimido, por tanto el código a añadir es otra redirección. Cuando llegemos a esta 2º redirección, el 3º nivel ya estará descomprimido, por lo que el código a añadir es la redirección para el 3º nivel.En la 3º redirección el 4º nivel estará visible y también el salto a la primera instrucción del programa completo, por lo que el código a añadir redigirá el salto a la 1º instrucción. Esto es lo que en principio deberíamos hacer, pero el primer nivel descomprime el 2º y 3º nivel (pero no el 4º), así que podemos redirigirlos sin esperar más.

Para complicar las cosas, el petite utiliza un checksum del encabezado PE para descomprimir el resto de niveles.Pero da la casualidad que el PE lo hemos tenido que modificar para hacernos sitio para nuestras redirecciones, por tanto el checksum no coincide ni rezando. Habrá que corregir esto para calcular el checksum correcto. A partir del código aquí expuesto es sencillo extrapolar para parchear cualquier ejecutable comprimido con el petite . Tomamos como partida la doc del petite. Existe una diferencia comprensible de direcciones entre la doc que disponemos y las direcciones reales del Decafé. Enumeremos incialmente las direcciones donde aplicar redirección:

La primera redirección se realiza a pelo sobre el ejecutable ya que no está encriptado.
 :0040c112 (doc petite)
 :0048a112 (Decafé)     push    00406212;Redirigimos a nuestro código con jmp 48c023.
 
En este punto, despúes de descomprimir el 2º nivel recogemos el control en 48c023, donde aplicamos redirección en:
 :0040634c (doc petite)
 :0045d3ba (Decafé)     xor [ecx],ebx;Redirigimos a nuestro código con jmp 48c058
 
En este punto, despúes de descomprimir el 3º nivel recogemos el control en 48c058, arreglamos los checksum y aplicamos redirección en:
 :0040637e (doc petite)
 :0045d3ec (Decafé)     xor ebx,[esi];Redirigimos a nuestro código con jmp 48c09b
 
En este punto, despúes de descomprimir el 4º nivel recogemos el control en 48c09b, y aplicamos redirección en:
Esta es la teoría, veamos la praxis: Hay una pequeñas diferencias con lo expuesto, ya que en la 1º redirección podemos colocar la 2º y 3º redirección. La 4º no porque aún no está descomprimida. Los sucios detalles los podeis apreciar currando un poco con el petite.

:0048C023 56				               push    esi;Primera redirección
:0048C024 BE F9 D3	45 00			       mov     esi, 45D3F9h;Parcheamos la comprobación de la integridad de la cabecera PE
:0048C029 66 C7 06	EB 08			       mov     word ptr	[esi], 8EBh
:0048C02E BE BA D3	45 00			       mov     esi, 45D3BAh;Colocamos la 2º redirección
:0048C033 C7 06 E9	99 EC 02		       mov     dword ptr [esi],	2EC99E9h
:0048C039 C7 46 04	00 31 59 08		       mov     dword ptr [esi+4], 8593100h
:0048C040 BE EC D3	45 00			       mov     esi, 45D3ECh;Colocamos la 3º redirección
:0048C045 C7 06 E9	AA EC 02		       mov     dword ptr [esi],	2ECAAE9h
:0048C04B C7 46 04	00 C6 04 49		       mov     dword ptr [esi+4], 4904C600h
:0048C052 5E				               pop     esi
:0048C053 E9 7C 12	FD FF			       jmp     loc_0_4602D4;Volvemos al punto donde colocamos la 1º redirección
:0048C058			       ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
:0048C058 56				               push    esi;Segunda redirección
:0048C059 BE 00 A1	48 00			       mov     esi, 48A100h
:0048C05E C7 06 72	75 85 99		       mov     dword ptr [esi],	99857572h;Arreglamos el checksum
:0048C064 C7 46 04	F8 D4 BC F7		       mov     dword ptr [esi+4], 0F7BCD4F8h
:0048C06B C7 46 08	D1 71 D6 83		       mov     dword ptr [esi+8], 83D671D1h
:0048C072 C7 46 0C	B2 41 22 95		       mov     dword ptr [esi+0Ch], 952241B2h
:0048C079 BA 93 D2	45 00			       mov     edx, 45D293h
:0048C07E BB 52 B5	DA 6A			       mov     ebx, 6ADAB552h
:0048C083 BE BA D3	45 00			       mov     esi, 45D3BAh;Arreglamos el código para volver correctamente
:0048C088 C7 06 31	19 31 59		       mov     dword ptr [esi],	59311931h
:0048C08E C7 46 04	04 31 59 08		       mov     dword ptr [esi+4], 8593104h
:0048C095 5E			            	       pop     esi
:0048C096 E9 1F 13	FD FF			       jmp     loc_0_4603BA;Volvemos al punto donde colocamos la 2º redirección
:0048C09B			       ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
:0048C09B 56				               push    esi;Tercera redirección redirección
:0048C09C BE EC D3	45 00			       mov     esi, 45D3ECh;Arreglamos el código para volver correctamente
:0048C0A1 C7 06 33	1E D3 C3		       mov     dword ptr [esi],	0C3D31E33h
:0048C0A7 C6 46 04	83			       mov     byte ptr	[esi+4], 83h
:0048C0AB BE 0B A1	48 00			       mov     esi, 48A10Bh;Colocamos la 4º redirección
:0048C0B0 C7 06 E9	B0 1F 00		       mov     dword ptr [esi],	1FB0E9h
:0048C0B6 C6 46 04	00			       mov     byte ptr	[esi+4], 0
:0048C0BA 5E				               pop     esi
:0048C0BB E9 2C 13	FD FF			       jmp     loc_0_4603EC;Volvemos al punto donde colocamos la 3º redirección
:0048C0C0			       ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
:0048C0C0 56				               push    esi;Parches a aplicar al programa descomprimido
:0048C0C1 BE 4C 00	45 00			       mov     esi, 45004Ch
:0048C0C6 C7 06 1F	C2 48 00		       mov     dword ptr [esi],	48C21Fh;Redirigimos el botón de salvar a nuestra rutina de salvado.
:0048C0CC BE 64 00	45 00			       mov     esi, 450064h
:0048C0D1 C7 06 1F	C2 48 00		       mov     dword ptr [esi],	48C21Fh;Redirigimos el botón de salvar como a nuestra rutina de salvado.
:0048C0D7 BE B1 44	41 00			       mov     esi, 4144B1h
:0048C0DC C7 06 E9	36 7C 07		       mov     dword ptr [esi],	77C36E9h;Colocamos una redirección para guardar el tamaño y el inicio del fichero desensamblado
:0048C0E2 C6 46 04	00			       mov     byte ptr	[esi+4], 0
:0048C0E6 5E				               pop     esi
:0048C0E7 E9 04 D5	F8 FF			       jmp     loc_0_41C5F0;Volvemos al punto donde colocamos la redirección
:0048C0EC			       ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
:0048C0EC 57				               push    edi
:0048C0ED BF 40 C1	48 00			       mov     edi, 48C140h;Apuntamos a nuestra zona de datos para guardar tamaño e inicio del fichero
:0048C0F2 8D BF D0	00 00 00		       lea     edi, [edi+0D0h];
:0048C0F8 89 0F			            	       mov     [edi], ecx;Guardamos la dirección de inicio del fichero decompilado
:0048C0FA 83 C7 04				       add     edi, 4
:0048C0FD 89 07				               mov     [edi], eax;Guardamos el tamaño
:0048C0FF BF B1 44	41 00			       mov     edi, 4144B1h;Arreglamos el código para volver correctamente
:0048C104 C7 07 50	51 8D 4A		       mov     dword ptr [edi],	4A8D5150h
:0048C10A C6 47 04	50			       mov     byte ptr	[edi+4], 50h
:0048C10E 5F				               pop     edi
:0048C10F E9 9D 83	F8 FF			       jmp     loc_0_4174B1;Volvemos al punto donde colocamos la redirección
LIMITACIONES Y TRABAJOS FUTUROS
Nuestro objetivo primario está conseguido, el condenado Decafé salva, pero con algunas limitaciones, poco importantes. Si decompilais varios ficheros y los teneis a la vez en pantalla, al salvar siempre salva el primero.Es más, si en la misma ejecución decompilais varios ficheros, cerrais todas las ventanas y decompilais de nuevo, siempre se salvará el 1º fichero decompilado. Resumiendo: sólo sirve para decompilar y salvar un sólo fichero por ejecución. Es un poco latoso, pero creo que perdonable. Tampoco está resuelto el tema de "salvar como" la primera vez y "salvar" el resto de veces, simpre que se salve se pide el nombre de fichero. Esta limitación es un poco estúpida. El copy/paste con el clipboard está desactivado, se deja como tarea para el alumno avezado estudiar este problema y realizar los oportunos cambios.
AGRADECIMIENTOS

[WkT!] y a todos sus colores, especialmente a Mr.WhiTe por su apoyo constante, a Mr.Crimson por sus tutoriales y herramientas , a Mr.Pink por su soporte técnico, a c0v3rt+ por su estupendo tutorial y finalmente a la gordita y al peluo por estar conmigo en los momentos más duros del Festival Erótico de Barcelona :-)
Recordad, buscad la fuente, buscad a +ORC.

estadoporcino@hotmail.com

 

[ 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