Desempaquetado manual de ASProtect versión 1.05
Construyendo una Tabla de Importación Falsa

student
No Asignado
Julio del 2000

por Tsehp

Octubre del 2000

Traducción de ^[G]oLe[E]^

Gt!! RuLeS
Courtesia de la Página de Rerverser de Ingenieria Inversa
Ligeramente editado
por reverser+
 
There is a crack, a crack in everything That's how the light gets in

actualizada el 02/8/2000

Rating
( )Principiante (x)Intermedio (x)Avanzado ( )Experto
 

 

Desempacado Manual de Asprotect versión 2000
Construyendo una Tabla de Importación Falsa
Escrito Por Tsehp

Introducción

Asprotect es un objetivo muy conocido, es empacador fue estudiado un monton y muy usado como objeto de practica para newbies. Si no sabes nada acerca de empaquetado o empacado, mejora tu conocimiento con los ensayos pasados, entonces puedes regresar, trataré de explicarte los últimos trucos. Acostumbro encontrar este objetivo cuando busco el msgboard del newbie de Sandman. Gracias a un reverser (cracker o revertidor) llamado SV que explicó bien la proteccion en sus terminos, su trabajo me salvo un monton de tiempo.

Importante : Este ensayo puede producir una aplicación funcional con tu versión actual de Windows. Pero la Tabla de Importación que es reconstruida unicamente trabajará en Win NT 4.0/2000, por qué? La versión de commview que crackié está diseñada para win nt4/2000 , en win98 está instalada otra versión con una Tabla de Importación diferente. Así que si quieres desempacarla en Windows 98, no puedes usar la Tabla_de_construcción de archivo que proveo, usa mi método de cualquier forma, el código generará una Tabla funcional para Win 9x.

También usé este método para picturestoexe, esta aplicación no usa exportación ordinal y el objetivo crackeado trabaja completamente en mi windows 2000 y win98.

Este ensayo es provisto para enseñarte una nueva técnica cuando desempacas un objetivo con una Tabla de Importación completamente destruida, así que lee cuidadosamente y practica todo paso a paso.

Herramientas requeridas
Softice 4.05
Icedump
Procdump
Ida 4.10
An hex editor
pe-editor

Ensayo hecho en win 2000.
URL/FTP del Objetivo
http://www.tamos.com/
Esto es Commview 2.1, otro portsniffer.

Ensayo

1) Las rutinas anti-softice

Antes de lanzar esta aplicación, tienes que esconder tu debugger. Este programa usa 2 tipicos trucos anti softice:

-Esta cargado el driver? : bpx createfileA haz "d esp-4"

Commview trata de ver si tres versiones diferentes de SoftICE están cargadas. Le pegarás 3 veces: SIWDEBUG SICE NTICE

Bueno, depende del sistema en el que estás, presiona F1 cada vez, el createfilea debe retornar 0xFFFFFFFF, si no, presiona F12 otra vez y fija tu eip a la dirección apuntada por el jnz abajo, pasarás todas las pruebas.

-El truco boundschecker. SICE usa int3 para sus breakpoints, pero cuando valores especiales son fijados para registrar, especialmente todo ebp conteniendo 'BCHK' 0x4243484b, Entonces, si un int3 es encontrado, el manejador normal de interrupción retorna despues de este Int3 dentro del objetivo, así el código se ejecuta si el SICE está presente. Para evitar esto, presiona F10 varias veces despues de fijar tu eip, ve despacio a través del código hasta que veas el int3 en SICE. Cuando estés allí, cambia tu ebp a algo más que 0x4243484b, entonces el programa correra normalmente hasta que un ultimo chequeo detectado por bpx createfilea, así como arriba.

Para el chequeo final, invierte el jz despues de createfileA, todas las pruebas estan venciadas ahora.

Nota : Solia hacer esto manualmente, porque frogsice no está implementado aun para Win NT, la copia actual en nt llamada Ntall no es del todo funcional, por lo que no pude usar un dispositivo cargado para evitar estas manipulaciones.

2) Localizando el Punto de Entrada.

Si quieres volcar tu programa empacado, debes parar el objetivo aquí, asi todas las secciones serían cargadas. Tengo que admitir que usé directamente la técnica que Eternal Bliss encontró en el Forum de los Newbies. Acá está, intacto:

Pasos:
1) bpx en getprocaddress
2) Una vez rompas, ve la sección .idata por "dd 4E3000".  Esto es encontrado 
haciendo "map32 cv" 3) bpm en el 1er byte (justo rompe acá) y desactiva el breakpoint getprocaddress 4) F5 y deja correr el programa 5) Al romper, desactiva todos los breakpoints 6) F12 4 veces y aterrizaras en un Xor EAX, EAX 7) Comienza rastreando con F10 8) Siempre que te encuentres con un CALL, chequea que unas instrucciones abaja está JMP 9) Si lo es, rastrea sobre él. 10) Si es un ret, tienes que rastrear dentro de ese CALL con F8 11) Entonces camina sobre los 2 CALL subsecuentes 12) Verás que el OEP se movio a alguna parte de EAX 13) Entonces te encontraras con un POPAD 14) Las cosas de JMP aparecen de nuevo como el principio del código desempaquetado. 15) Rastrea en el proximo CALL (el 3ro) y F8 hasta que te encuentres con un ret 16) Continua con eso y aterrizaras en el OEP.

Solo aplica esto y lo encontraras, 0x4de384 en mi sistema. Solo recuerda que encontraras casi todo el tiempo una instrucción POPAD justo antes del salto (jump) final.

Tienes que volcar el exe, usando icedump y procdump para reconstruir el pe (esto no será explicado aquí, si no sabes como hacer esto, solo ve los ensayos pasados sobre empacado/desempacado).

Muy Importante: Usa estas opciones del ProcDump cuando reconstruyas el pe : Structure : desactiva la optimización de la estructura pe Import : no reconstruyas la importación, deja otra opción intacta. Tienes que copiar manualmente la sección .aspr de cv.exe (original) a cv_dumped.exe, usando tu Editor Hex favorito. Como un ejemplo, encontre dentro del offset raw original: 5aa00 longitud 14800 descargado el offset raw : ff400 longitud 14800, esta manipulación copiará la Tabla de importación original.

Pero esta descarga no trabajará, trata de cargar tu exe descargado dentro de ida y notarás que la Tabla de Importación está dañada, algunas direcciónes virtuales en otras secciones tambien son apuntadas a lugares incorrectos. De hecho, tenemos una Tabla de Importación legal dentro de la sección .aspr pero casi todas sus importaciones no están usadas, excepto para loadlibrarya, getmodulehandleA y getprocaddress, el resto está aquí para engañarnos, crackers estupidos ;-)

La protección principal de ASProtect está justo aquí: Algunas importaciones estan bien y apuntan directamente a las direcciones API, algunas otras estan apuntando a la Tabla (localizada en memoria en 0x00CDxxxx) normalmente contiene algunas direcciones de importación desencriptadas y esta tabla originalmente contiene algunas rutinas para desencriptar otras direcciones cuando commview las necesita, aun cuando este programa está empacado.

Bien aca tenemos un gran problema: puedes arreglar manualmente la Tabla de Importación si conviertes todas las direcciones de la tabla al .idata en el lugar correcto.

Así en tu Aplicación descargada y dentro del .idata tienes

4e328c : jmp [cd4950] and cd4950 conteniendo 77db858e (una dirección de importación valida)

Podrías convertir el salto en 4e328c para apuntar directamente a 77db858e.

Gastarias un monton de tiempo (acerca de 520 direcciones) y no trabajará, porque dentro de la tabla cdxxxx , algunas direcciones apuntan a código como este: cd4950 push cd495a call 182f68 (por ejemplo)

Qué está pasando? cuando commview hace call 4e328c (Tabla de Importación) la rutina localizada en cd4950 desencripta la Dirección de Importación correcta EN TIEMPO DE EJECUCIÓN! también puedes tratar de volcar la tabla cdxxxx, el código de desencriptación seguirá estando aquí y definitivamente no trabajará. Esta caracteristica es la mejora real hecha, desde la ultima versión de ASProtect. Actualmente ellos ofrecen la descarga de una versión que no aplica ese tipo de protección, extraño? ;-) "La siguiente cosa para hacer es obtener una Tabla de Importación virgen, ya que la que está dentro de nuestro archivo descargado está corrupta. Así es como trabajaremos: 1. Insertando algún código para construir nuestra Tabla de Importación 2. Volcando nuestra Tabla de Importación al Disco Duro 3. Arreglando la dirección de la Tabla de Importación con un programa autocodificado." gracias blackb ;-) ) la versión previa de ASProtect era mas facil de desempacar, era posible localizar el IAT y volver ponerlo, mi ensayo previo sobre ASProtect proveia algunos saltos de memoria directa dentro de la Tabla de Importación, no generados por un getprocaddress. Esto trabaja pero el objetivo solo se ejecutará en tu pc y si actualizas algunos dll's, las direcciones no son las mismas y tu objetivo se cerrará.

3) Generando nuestra Tabla de Cadenas

Continuas en la instrucción int3, solo haz un S 0 L FFFFFFFF AC 08 C0 74 E4 y localizaras el loop culpable de construir la Tabla de Importación de ASProtect, hazle un bpmb en el inicio. Encontre en este lugar mientras logeaba el loop usual getmodulehandle/getprocaddress, que cuando eres atrevido, aterrizas despues del CALL en 19a53a.

Aquí está lo que encuentras :

001B:0018A51E  AC                  LODSB
001B:0018A51F  08C0                OR        AL,AL
001B:0018A521  74E4                JZ        0018A507
001B:0018A523  4E                  DEC       ESI
001B:0018A524  56                  PUSH      ESI
001B:0018A525  53                  PUSH      EBX
001B:0018A526  80F802              CMP       AL,02
001B:0018A529  7407                JZ        0018A532
001B:0018A52B  0FB64E01            MOVZX     ECX,BYTE PTR [ESI+01]
001B:0018A52F  41                  INC       ECX
001B:0018A530  EB05                JMP       0018A537
001B:0018A532  B904000000          MOV       ECX,00000004
001B:0018A537  41                  INC       ECX
001B:0018A538  01CE                ADD       ESI,ECX
001B:0018A53A  E8B5FDFFFF          CALL      0018A2F4 <- redirecciona este punto, 
nota la dirección 0x18a2f4.
001B:0018A53F  AB                  STOSD
001B:0018A540  EBDC                JMP       0018A51E <- nota esta dirección también,
es el salto de regreso al loop.

Todo lo que tenemos que haces es encontrar una localidad de memoria libre llena con 0 para que podamos escribir un pequeño código para modificar esta rutina. La dirección 0x180000 será usada como un ejemplo.

Qué estamos haciendo: para reconstruir la Tabla de Importación, generaré algo para hacerlo. Revertí ASProtect para esto y encontre que está construyendo una Falsa Tabla de Importación para el objetivo que interactua con nuestra aplicación.

La Tabla Thunk de Importación se ve como esto, commview llama esto:

402000 call [4ebc38]; 4ebc38=cdec08 ; cdec08=jump kernel32!compareStringA una llamada indirecta a API. o cdec08:push dfef04 , call 18ffe4 ; esta es mas desviada, en tiempo de ejecución esta es llamada, la Tabla generada en CDxxxx llama una rutina de desencripción que alimente la Tabla Thunk de Importación con las direcciones correctas. No pudes encontrar el IAT original antes de que todo esto sea generado primero, porque no existe mas, asi que no puedes usar procdump o un reconstructor de IAT para hacer trabajar la aplicación, tienes que reconstruir todo esta vez.

El IAT será reconstruido en 2 pasos:

1)generar un volcado, viendo esto: <Nombre_del_Modulo>0<Nombre_de_proc/numero_ordinal>0<dirección del objetivo correspondiente para copiar la dirección de la API> por ejemplo:

GetcurrentThreadId0Kernel32.dll068bc4e00 etc.... acerca de 530 grupos generados, esto podria tomar un largo tiempo para hacerlo manualmente. ASProtect debe usar getmodulehandlea y getprocaddress para generar las direcciones correctas para su Tabla Daxxxx, asi que solo encontre las ocurrencias dentro de su código y rastree todos los parametros de función, para obtenerlos de vuelta dentro de mi call fixer.

2)escribir un código en el final de esta descarga para regenerar el IAT thunk real (el luegar donde las direcciones de la API estan normalmente fijadas por el Sistema Operativo en tipo de carga)

Primer paso

NOTA : todas las direcciones son diferentes en cada ejecución de tu objetivo.

Primer parche 18a53a jmp 180000

Después escribe el siguiente código en memoria con SoftICE:

Un Constructor de Tablas de Importación Falsas para commview hace un s 0 l ffffffff ac 08 c0 74 e4, esta busqueda es constante. Redirecciona la llmada justo antes del stosd a algún espacio libre de memoria (aquí en 180000) con un jump 180000, nota que la siguiente opción de direccion , (aquí 195004) nota la dirección llamada y repitela en el inicio de este código (aquí 19ff00) para la ultima parte de este código, el desencriptador, encuentra la dirección para llamar con: s 0 l ffffffff 55 8b ec 81 c4 f8 fe ff ff 53 56, nota la dirección aquí (19ff08), no olvides parchear este desencriptador dentro de ASProtect haciendo un d 19ff08+95 y escribe tres nops 90 90 90, esto hará un ret normal despues de tu llamada. Pon 00 00 50 00 en la dirección 17fff0, justo en el inicio, esto comenzara una copia en 500000 (usando la memoria encargada de commview) no olvides llenar este lugar con 00's, con una longitud de 4000, solo para limpiar este lugar.

Nota : este call fixer debe estar adaptado a tu objetivo, especialmente para los 3 casos diferentes (nombre_de_proc legal, ordinal y encriptado), las pruebas podrían
ser diferentes, depnediendo de la versión de ASProtect y de la forma en que está implementada dentro del objetivo.

data
17fff0:00 00 50 00 ;comenzamos a generar nuestro volcado en 500000 en memoria

comenzando por ejemplo en 1b:00180000
CALL      19ff00			;ponemos de nuevo el CALL que redireccionamos aquí
PUSHAD					;Mejor los guardamos
CMP       DWORD PTR [0012FDF3],00	;12fdf3 apunta al nombre_del_proc, de otra manera 
					es un ordinal o uno encriptado (*2)
JZ        00180065			;Va al procedimiento ordinal/encriptado
PUSH      0012FDF3			;copiar desde (*1)
1b:180014 PUSH      DWORD PTR [0017FFF0]		;Copia a
CALL      78281E39 			;llamar a lstrcpy (tu dirección podría diferir)
PUSH      DWORD PTR [0017FFF0]		;Solo para ver
CALL      78291334			;de cuanto es esta cadena
INC       EAX
INC       EBX
ADD       [0017FFF0],EAX		;fijar el puntero de memoria al siguiente lugar,
					para la cadena nombre_del_proc
PUSH      EBX				;ebx apunta a la cadena nombre_del_modulo (resulta 
					de call 19ff00) (*3)
PUSH      DWORD PTR [0017FFF0]		
CALL      78281E39			;copiar otra vez
PUSH      DWORD PTR [0017FFF0]
CALL      78291334			;chequear la longitud
INC       EAX
ADD       [0017FFF0],EAX		;ajustar el offset de la Tabla
MOV       ECX,[0017FFF0]		;ecx contiene un puntero a nuestra siguiente
					localidad de nuestra tabla para fijat la dirección 
					del IAT
MOV       [ECX],EDI			;edi siempre contiene la dirección del objetivo 
					donde tenemos que poner la dirección de la API
ADD       DWORD PTR [0017FFF0],05	;fijar el offset al siguiente grupo
POPAD					;obtner los registros de vuelta
JMP       00195004			;y continuar el loop de ASProtect
1b:180065 CMP       ECX,00		;si ecx<>0 el nombre_del_proc es un # ordinal
JNZ       00180079			;así nosotros vamos al procedimiento ordinal
PUSH      DWORD PTR [EAX+01]		;para pasar el parametro correcto al procedimiento 
					de desencripción de Asprotect, normalmente 
					llamado rutina
CALL      0019FF08			;desencriptar el nombre_del_proc (*4)
PUSH      0012FDEC			;fijar la cadena nombre_del_proc que está 
					desencriptada
JMP       00180014			;tenemos la cadena nombre_del_proc  desencriptada, 					continuemos dentro de mi fixer
1b:180069 SUB ESI,4		        ;ESI apunta aquí al numero ordinal de exportación 
					(*5)
PUSH      ESI				;fijar el puntero al ordinal, y lo copiamos dentro
					de la tabla
JMP	  180014			;tenemos el ordinal, copiemoslo dentro de la tabla

(*1) y (*3) esta dirección 12fdf3 fue encontrada mientras moraba dentro del CALL 19ff00, es empujado con el 1 en (*3) justo antes de una llamada a las secuencias getmodulehandleA y getprocaddress.

(*2) Revisé este valor varias veces despues del CALL 19ff00, es una constante.

(*4) Esta dirección la encontré mientras miraba dnetro de los saltos originales en el IAT, algunos saltos llaman directamente a las APIS, las encriptadas siempre comienzan por empujar xxxxxx, llamando esta dirección.

(*5) El mismo método que (*1) Escribí la localidad de memoria y lo hice muy atrevido, ESI siempre es +4 despues de esta dirección en este caso. Pon un bmpb en el POPAD despues del CALL que redireccionaste, se activará cuando la copia este terminada. Finalmente vuelca tu talba para usarla despues.

 

PAGEIN D 500000 3ba0 (por ejemplo) solo mira dentro de la memoria desde 500000 abajo hasta que encuentres el final de la Tabla, aquí tenemos los 3 componentes necesarios para reconstruir la Tabla de Importación de commview, el nombre_del_proc o numero ordinal, el nombre de su dll y la dirección del objetivo para copiar la dirección importada.

Shortcut para probar tu commview volcado:

Si eres perezoso, tienes aquí el resultado final: la Tabla volcada con el reconstructor añadido en el final. Solo toma tu commview volcado, tienes que realinearlo para que los offset del RVA = a los offsets raw, agregar una nueva sección (longitud = 3c0e) en el final del objetivo, pegar este archivo en la nueva sección y cambiar el punto de entrada del commview en 530b45 (130b45 en procdump, la imagenbase es en 400000) y ver que está pasando con softice, todo está explicado en las siguientes lineas.

4)Fijando el Reconstructor

Ahora que tienes tu Tabla volcada y tu commview volcado, necesitamos agregar esta Tabla en el final de tu objetivo volcado, para facilitar tu trabajo el commview volcado debe tener los offsets RVA correspodiendo con los offsets raw, usa pe-editor para agregar una nueva sección con 4000 de longitud, aquí están los resultados:

para las secciones:

Tu tabla volcada consiste de casi 500 grupos de tres numero : nombre de modulo, nombre de procedimiento u ordinal y direcciones para copiar el resultado.

Tengo que códificar un reconstructo en el final de la tabla volcada:

Globalmente toma los primeros 2 números: nombre del módulo y nombre del proc/ ordinal, usa getmodulenameA y getprocaddress para obtener la dirección de la función en memoria y copia esta direccion en commview, aquí está el listado completamente explicado.

00530AE7                 db  4Fh ; O  AQUÍ ESTÁ EL ÚLTIMO MIEMBRO DE TU TABLA VOLCADA,
				  ves openSCManagerA,
00530AE8                 db  70h ; p  advapi32.dll y 004e3994 es la última dirección
				  para copiar dentro de commview,
00530AE9                 db  65h ; e  4e3994 corresponde al último thunk del IAT original 
				  de commview.
00530AEA                 db  6Eh ; n
00530AEB                 db  53h ; S
00530AEC                 db  43h ; C
00530AED                 db  4Dh ; M
00530AEE                 db  61h ; a
00530AEF                 db  6Eh ; n
00530AF0                 db  61h ; a
00530AF1                 db  67h ; g
00530AF2                 db  65h ; e
00530AF3                 db  72h ; r
00530AF4                 db  41h ; A
00530AF5                 db    0 ;  
00530AF6                 db  61h ; a
00530AF7                 db  64h ; d
00530AF8                 db  76h ; v
00530AF9                 db  61h ; a
00530AFA                 db  70h ; p
00530AFB                 db  69h ; i
00530AFC                 db  33h ; 3
00530AFD                 db  32h ; 2
00530AFE                 db  2Eh ; .
00530AFF                 db  64h ; d
00530B00                 db  6Ch ; l
00530B01                 db  6Ch ; l
00530B02                 db    0 ;  
00530B03                 db  94h ; ö
00530B04                 db  39h ; 9
00530B05                 db  4Eh ; N
00530B06                 db    0 ;  
00530B07 unk_530B07      db    0 ;               ; DATA XREF: comienzo+85o
00530B08                 db    0 ;  
00530B09                 db    0 ;  
00530B0A                 db    0 ;  
00530B0B                 db    0 ;  
00530B0C                 db    0 ;  
00530B0D                 db    0 ;  
00530B0E                 db    0 ;  
00530B0F                 db    0 ;  
00530B10                 db    0 ;  
00530B11                 db    0 ;  
00530B12                 db    0 ;  
00530B13                 db    0 ;  
00530B14                 db    0 ;  
00530B15                 db    0 ;  
00530B16                 db    0 ;  
00530B17                 db    0 ;  
00530B18                 db    0 ;  
00530B19                 db    0 ;  
00530B1A                 db    0 ;  
00530B1B                 db    0 ;  
00530B1C                 db    0 ;  
00530B1D                 db    0 ;  
00530B1E                 db    0 ;  
00530B1F                 db    0 ;  
00530B20 dword_530B20    dd 0                    ; DATA XREF: comienzo+ACw
00530B20                                         ; comienzo+B9r
00530B24                 db    0 ;  
00530B25                 db    0 ;  
00530B26                 db    0 ;  
00530B27                 db    0 ;  
00530B28 adr_lstrlen     dd 0                    ; DATA XREF: comienzo+18w
00530B28                                         ; comienzo+32r ...
00530B2C                 db    0 ;  
00530B2D                 db    0 ;  
00530B2E                 db    0 ;  
00530B2F                 db    0 ;  
00530B30                 db    0 ;  
00530B31 aLstrlen        db 'lstrlen',0        ; DATA XREF: comienzo+Co ;Escribir lstrlen 
para recuperar está dirección de procedimiento en tu reconstructor.
00530B39                 align 4
00530B3C lpProcName      dd 0                    ; DATA XREF: comienzo+2Cw
00530B3C                                         ; comienzo+51r ...
00530B40 current         dd 0                    ; DATA XREF: comienzo+22w
00530B40                                         ; comienzo+27r ...
00530B44                 db    0 ;  
00530B45 
00530B45 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R U T I N A ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
00530B45 
00530B45 ; este programa usa una tabla pegada arriba:
00530B45 ; <nombredelproc>0<nombredelmódulo/ordinal de exportación >0<dirección para copiar 
en la Tabla Thunk de Importación>
00530B45 ; obtiene las direcciones reales para poner en la Tabla Thunk 
de Importación de la Aplicación
00530B45 
00530B45                 public start
00530B45 start           proc near
00530B45                 mov     eax, offset aKernel32_dll ; obtiene un offset a
kernel.dll, en el inicio de la tabla
00530B4A                 push    eax             ; lpModuleName
00530B4B                 call    ds:GetModuleHandleA
00530B51                 push    offset aLstrlen ; obtiene offset a la cadena lstrlen 
00530B56                 push    eax             ; hModule
00530B57                 call    ds:GetProcAddress
00530B5D                 mov     ds:adr_lstrlen, eax
00530B62                 mov     eax, offset aGetcurrentthre ; posiciona el offset en 
el comienzo de la tabla
00530B67                 mov     ds:current, eax ; es un nombredeproc, lo guardamos 
						   temporalmente
00530B6C 
00530B6C loc_530B6C:                             ; CODE XREF: comienzo+8Fj
00530B6C                 mov     eax, ds:current
00530B71                 mov     ds:lpProcName, eax ; guardar este offset de nombredeproc 
en el lugar correcto
00530B76                 push    eax
00530B77                 call    ds:adr_lstrlen  ; calcular la longitud de la 
cadena nombredeproc
00530B7D                 cmp     eax, 1          ; es un ordinal de importación?
00530B80                 jz      short loc_530BDB ; ir al tratamiento del ordinal
00530B82                 inc     eax
00530B83                 add     ds:current, eax ; ajustar el offset actual a la siguiente 
cadena
00530B89                 mov     ebx, ds:current ; ahora es un nombredemódulo, 
obtenemos la dirección
00530B8F                 push    ebx             ; lpModuleName
00530B90                 call    ds:GetModuleHandleA ; calculatar el manipular 
de nombredemódulo para getprocaddress
00530B96                 push    ds:lpProcName   ; obtener el nombredeproc previo para
calcular la dirección real
00530B9C                 push    eax             ; hModule
00530B9D                 call    ds:GetProcAddress
00530BA3                 nop
00530BA4 
00530BA4 loc_530BA4:                             ; CODE XREF: comienzo+C7j
00530BA4                 mov     ebx, eax        ; guardar el nombredeproc para la 
tabla de importación en ebx
00530BA6                 push    ds:current
00530BAC                 call    ds:adr_lstrlen  ; calculatar la longitud del 
nombredemódulo
00530BB2                 inc     eax
00530BB3                 add     ds:current, eax ; actualizar el offset actual, ahora 
apunta a la dirección de la Tabla Thunk de Importación de la aplicación
00530BB9                 mov     ecx, ds:current
00530BBF                 mov     eax, [ecx]      ; obtener la dirección de la aplicación
00530BC1                 mov     [eax], ebx      ; guardar la dirección del nombredeproc en la Tabla Thunk de Importación
00530BC3                 add     ds:current, 5   ; actualizar el offset actual para
que apunte al siguiente nombredemódulo
00530BCA                 cmp     ds:current, offset unk_530B07 ; Estamos en el final
de la tabla?
00530BD4                 jl      short loc_530B6C ; repetir a la siguiente dirección
de la Tabla de Importación 
00530BD6                 jmp     loc_4DE384      ; Saltar al PE de la aplicación
00530BDB ; ---------------------------------------------------------------------------
00530BDB 
00530BDB loc_530BDB:                             ; CODE XREF: comienzo+3Bj
00530BDB                 xor     edx, edx
00530BDD                 mov     ecx, ds:lpProcName ; obtener el offset del ordinal 
de importación
00530BE3                 mov     dl, [ecx]       ; obtener el número ordinal 
00530BE5                 inc     eax
00530BE6                 add     ds:current, eax ; actualizar el offset actual para que
apunte al nombredemódulo
00530BEC                 mov     eax, ds:current
00530BF1                 mov     ds:dword_530B20, edx ; guardar el ordinal
00530BF7                 push    eax             ; lpModuleName
00530BF8                 call    ds:GetModuleHandleA ; obtener el manipulador del
nombredemódulo
00530BFE                 mov     edx, ds:dword_530B20 ; recuperar el ordinal exportado
del nombredeproc
00530C04                 push    edx             ; lpProcName
00530C05                 push    eax             ; hModule
00530C06                 call    ds:GetProcAddress ; obtener la dirección del ordinal 
exportado, 
kernel32 
comparestringa es 25 por ejemplo
00530C0C                 jmp     short loc_530BA4 ; guardar la dirección de nombredeproc 
para la Tabla de Importación en ebx
00530C0C start           endp
00530C0C 
00530C0C

Cuando termines, arma SoftICE con un bpx getversion, lanza commview (desde su directorio original) en el 3er golpe, haz un bpx en 530b45 para que puedas chequear si trabaja el reconstructor. Si todo va bien, el reconstructor debe generar direcciones de API validas hasta la ultima dirección de commview en 4e3994.

Trabaja, felicitaciones, has construido una Falsa Tabla de Importación dentro de tu commview.  volcado

Cuando el reconstructor termina su trabajo, salta al Punto de Entrada de commview 4de384.  

Saldrá directamente, porque hay un chequeo CRC, tenemos que parchear este codigo dentro del commview volcado;
004DE3B9                 call    sub_4524A0
004DE3BE                 mov     eax, [ebp+var_10]
004DE3C1                 call    sub_465118
004DE3C6                 cmp     eax, 6F200h
004DE3CB                 jz      short loc_4DE3D2 <- parchear a jmp 4de3d2
004DE3CD                 call    sub_403BB4

No olvides una cosa, aún hay un truco anti SoftICE. Reactiva el bpx createfilea, haz "d esp->4"; presiona F12 cuando llega, entonces invierte el jz que sigue.

Lanzalo de nuevo, ahora está trabajando y estas listo para continuar revirtiendo este invalido exe con tiempo de prueba.

5) Qué queda para crackear?

Ahora termina el trabajo real, podemos parchear lo que se querramos. Te daré los parches facilmente, solo porque esta sección no fue la parte principal de mi ensayo, esto seguramente te salvara de algun trabajo. Para terminar su agonia, terminamos con:

-Rutina Anti SoftICE : una tipica, justo despues del bien conocido createfileA :

0046573E                 call    sub_406D0C (createfileA con driver de SICE como argumento)
00465743 
00465743 crack5:
00465743                 cmp     eax, 0FFFFFFFFh es cargado?
00465746                 jz      short loc_465750 <- parchear esto a jump
00465748                 push    eax
00465749                 call    sub_406CEC
0046574E                 mov     bl, 1

-El limite de Tiempo: usualmente lo encuentras despues de un bpx a getlocaltime, y 
rastreando despues.
004D8D5B                 call    sub_44EB74 ; este call contiene una llamada a getlocaltime
004D8D60 
004D8D60 loc_4D8D60:                             ; CODE XREF: sub_4D899C+386j
004D8D60                 mov     eax, ds:dword_4E051C
004D8D65                 cmp     byte ptr [eax], 0 ;Está terminado el tiempo del trial?
004D8D68 
004D8D68                 jnz     short loc_4D8DB8 <- fuerza esto a jump
004D8D6A                 mov     eax, ds:dword_4E0378
otro lugar:
004D8D60 loc_4D8D60:                             ; CODE XREF: sub_4D899C+386j
004D8D60                 mov     eax, ds:dword_4E051C
004D8D65                 cmp     byte ptr [eax], 0
004D8D68 
004D8D68 crack4:                                 ; Tiempo limite, fuerzalo a jump
004D8D68                 jmp     short loc_4D8DB8
y también:
00489688 crack6:                                 ; arreglo para el tiempo de prueba, 
						 parchealo a jump
00489688                 jmp     short loc_48968E
0048968A ; ---------------------------------------------------------------------------
0048968A                 mov     byte ptr [ebp-1], 1
0048968E 
0048968E loc_48968E:                             ; CODE XREF: sub_4894A0+72j
0048968E                                         ; sub_4894A0+7Cj ...
0048968E                 cmp     [ebp+var_1], 1
00489692                 jnz     short crack7    ; Arreglo al tiempo de prueba
00489694                 mov     ds:byte_4E1C19, 1
0048969B 
0048969B crack7:                                 ; CODE XREF: sub_4894A0+1F2j
0048969B                 mov     eax, 120020h    ; arreglo al tiempo de prueba, fuerza 
						   este valor y nopea
004896A0                 nop
004896A1                 mov     ds:byte_4E1C1A, 1
otros parches, de otra forma, sale aleatoriamente
004DA57C                 mov     eax, ds:dword_4E02EC
004DA581                 cmp     byte ptr [eax], 1
004DA584 
004DA584 crack9:
004DA584                 jmp     short loc_4DA5AB ;parchalo a jump
004DA586 ; ---------------------------------------------------------------------------
004DA586                 call    sub_4D03AC
004DA58B                 lea     ecx, [ebp-4]

004D8F3B loc_4D8F3B:                             ; CODE XREF: CODE:004D8F11j
004D8F3B                 call    sub_4894A0
004D8F40                 test    al, al
004D8F42 
004D8F42 crack10:
004D8F42                 jmp     short loc_4D8F7D ;parchalo a jump
004D8F44 ; ---------------------------------------------------------------------------
004D8F44                 mov     eax, ds:dword_4E02EC
004D8F49                 cmp     byte ptr [eax], 1

call    sub_4894A0
004DA8D9                 test    al, al
004DA8DB 
004DA8DB crack11:                                ; parchalo a nop
004DA8DB                 nop
004DA8DC                 nop
004DA8DD                 call    sub_4D085C
004DA8E2                 retn

-mitad de los paquetes desplegados: una forma facil con IDA, solo encuentra la referencia a la cadena:
0048B5A4                 push    offset loc_48BB1C
0048B5A9                 push    dword ptr fs:[eax]
0048B5AC                 mov     fs:[eax], esp
0048B5AF                 cmp     byte ptr [ebx+5Fh], 0
0048B5B3 
0048B5B3                 nop ; nopea esos para que nunca salte a 48b5c2, adivinas por que?
0048B5B4                 nop
0048B5B5                 lea     edx, [ebp-14h]
0048B5B8                 mov     eax, [ebx+22h]
0048B5BB                 call    sub_48A7C0
0048B5C0                 jmp     short loc_48B5CF
0048B5C2 ; ---------------------------------------------------------------------------
0048B5C2                 lea     eax, [ebp-14h]
0048B5C5                 mov     edx, offset aDataThisEvalua ; "DATA:THIS EVALUATION VERSION 
                         DISPLAYS O"...
0048B5CA                 call    sub_403E08

tienes 2 lugares mas para hacer lo mismo, encuentralos y corrige el *bug*.
-La molesta nag cuando sales de commview:  la encontre despues de un bpx to createwindowsexa, tienes que presionar F12 un monton de veces para encontrar esta rutina:

00459718 loc_459718:                             ; CODE XREF: sub_45969C+6Cj
00459718                                         ; sub_45969C+70j
00459718                 mov     eax, [ebp+var_C]
0045971B                 mov     edx, [eax]
0045971D                 nop <- Tienes que nopear este call para evitar la nag
0045971E                 nop
0045971F                 nop
00459720                 nop
00459721                 nop
00459722                 nop
00459723                 mov     [ebp-8], eax
00459726                 xor     eax, eax
00459728                 pop     edx
00459729                 pop     ecx
0045972A                 pop     ecx
0045972B                 mov     fs:[eax], edx
0045972E                 push    offset loc_459743
00459733 
00459733 loc_459733:                             ; CODE XREF: CODE:00459741j
00459733                 mov     eax, [ebp+var_C]
00459736                 call    sub_403024
0045973B                 retn

Ahora puedes disfrutar tu nuevo portsniffer, auto reconstruido por él mismo, justo como debería ser siempre.


Notas Finales

Necesito tu reatroalimentación sobre este ensayo, asi que escribe tus comentarios en el msgboard : http://www.insidetheweb.com/mbs.cgi/mb155985

Puedes unirte a todos los forums de reversers en sandman, donde tuve esta idea: http://www.insidetheweb.com/mbs.cgi/mb628842

O en el msgboard de fravia, para intermedios y avanzados: http://www.insidetheweb.com/mbs.cgi/mb155985

Gracias a Eternal Bliss ,r!sc y SV por su trabajo preliminar en este interesante objetivo.

+Tsehp



Ob Duh
No te molestaré explicando que deberias comprar este programa objetivo si intentas usarlo por un periodo mas largo que el permitido. Deberias ROBAR este software en cambio? no necesitas crackear su esquema de protección del todo: lo encontrarás en la mayoria de Sites de Warez, completo y ya registrado, adiós, no regreses.

Estas muy dentro de reverser's page de ingerieria inversa, escoge tu camino hacia afuera:


redhomepage redlinks redsearch_forms red+ORC redhow to protect redacademy database
redreality cracking redhow to search redjavascript wars
redtools redanonymity academy redcocktails redantismut CGI-scripts redmail_reverser
redIs reverse engineering legal?

www.000webhost.com