¡El
problema con TimeLOCK 3+ es que rasga fuera
algún código de la app, remendándolo en tiempo
de activación si todas las luces son verdes!
Innecesario decir que esta majadería encripta
los bytes perdidos, así que no encontraremos
esto ' listo_para_parchear' en un dummy DLL o
así... Marigold llego a la conclusión que los
recortes perdidos tuvieron que ser copiados (pero
no explicó cómo) entonces remendó
directamente sobre el exe. Así que yo entendí '
copiado a mano'. Lo que en su caso era aceptable,
porque el recorte no era tan largo (' solo' 0x16E
bytes), está aquí imposible: como verás, una
mejora de TL31INJ.dll (entre otros?) es que el '
la Bolsa de bytes' (tontamente) va creciendo.
Para NetscanTools 3.1 alinea 0x716 (= 1814)
bytes. Mi objetivo es explicar cómo permitir al
hinchado TimeLOCK hacer su trabajo sucio, y
entonces suavemente detenerlo para guardar el
código a un archivo. Así que empecemos el
agrietamiento. Unas líneas del archivo del
ejemplo NSTSTD.EXE desensamblado lo explicarán
rápidamente:
//******************** Punto de Entrada del programa ********
:004FA000 FF74240C push [esp+0C]
:004FA004 FF74240C push [esp+0C]
:004FA008 FF74240C push [esp+0C]
:004FA00C 68D879A084 push 84A079D8
:004FA011 68C1FED07D push 7DD0FEC1
:004FA016 68A29C5D1E push 1E5D9CA2
:004FA01B FF15D4A24F00 call dword ptr [004FA2D4] ---> Esta es la llamada infame
:004FA021 68FFFFFFFF push FFFFFFFF
:004FA026 FFD0 call eax ---> Al devolver eax contiene la dirección
correcta, qué es el punto de la entrada
'real' del objetivo
:004FA028 C20C00 ret 000C ---> si, ¡eso es todo!
Como
uno puede experimentar fácilmente, desviar
4FA01B no conduce a nada, incluso con el eax
correcto, porque esto precisamente es en donde
TimeLOCK remendará. Yo no quise ahondar en el '
pesado ' encriptado de TimeLOCK, comprobando CRC
(verifica su integridad, como la del objetivo)
, todo material aburrido... Parece que tendría
que ser fácil permitirlo hacer el trabajo: -)
1) tienes una versión de funcionamiento de
prueba, entonces salta las próximas 50 líneas
2) como yo, 'quémalo' en el primer día de
prueba adelantando la fecha 1 mes, sólo para ver
lo que pasa, al restaurar el reloj atrás. (No,
caduca para bien :=)
Así que a trabajar con TL31INJ.DLL. Primero
tenemos que desviar la caja de diálogo con el el
botón de 'prueba' puesto gris para siempre. Con
SoftICE lo encontramos fácilmente:
:100081FF 6A00 push 00000000
:10008201 A164A30310 mov eax, dword ptr [1003A364]
:10008206 6840830010 push 10008340
:1000820B 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"TL_DLG_MAIN"
|
:1000820D 687CF60310 push 1003F67C
:10008212 50 push eax
* Ref To: USER32.DialogBoxParamA, Ord:008Eh
--> cuando ret.,eax=1 si aprietas 'try first'
:10008213 FF1530960410 Call dword ptr [10049630]
:10008219 8BF8 mov edi, eax
Así
que bpx en 10008213 (cuidado con la
relocalización, en mi pc era 508213...)
Cuando SoftICE rompe, F10, aprieta cancel,
entonces r eax=1 para simular el apretón de
'try_it'.
Un consejo practico
No intentes remendar en 10008213 para ganar
tiempo. Como puedes ver, ésta es una dirección
absoluta, el loader REMENDARA después de ti, en
caso de relocalización (esto es muy probable),
causando una caída muy probable... Haciendo esto
correctamente tienes que parchear la tabla de
relocalización. Más sobre esto al final.
Desgraciadamente, esto no es bastante, como
Marigold notó con la versión anterior. Ahora
nosotros estamos atrapados en un comienzo de
rutina en 1002B020:
* Referenced by a CALL at Addresses: (a hundred of these follow)
|
:1002B020 83EC20 sub esp, 00000020
:1002B023 B908000000 mov ecx, 00000008
:1002B028 56 push esi
:1002B029 57 push edi
:1002B02A BE28730310 mov esi, 10037328
:1002B02F 8D7C2408 lea edi, dword ptr [esp+08]
:1002B033 F3 repz
:1002B034 A5 movsd
:1002B035 8B44242C mov eax, dword ptr [esp+2C]
:1002B039 8B4C2430 mov ecx, dword ptr [esp+30]
:1002B03D 8D54241C lea edx, dword ptr [esp+1C]
:1002B041 89442420 mov dword ptr [esp+20], eax
:1002B045 8B442418 mov eax, dword ptr [esp+18]
:1002B049 52 push edx
:1002B04A 8B54240C mov edx, dword ptr [esp+0C]
:1002B04E 50 push eax
:1002B04F 894C242C mov dword ptr [esp+2C], ecx
:1002B053 8B4C2414 mov ecx, dword ptr [esp+14]
:1002B057 51 push ecx
:1002B058 52 push edx
* Reference To: KERNEL32.RaiseException, Ord:01C9h
:1002B059 FF15F4950410 Call dword ptr [100495F4]
--> Me temo que no retrocederemos de aquí :-)
:1002B05F 5F pop edi
:1002B060 5E pop esi
:1002B061 83C420 add esp, 00000020
:1002B064 C20800 ret 0008
Para salir de esta trampa, simplemente bpx
1002B020, reinícia todo entero y cuando salte
ensambla un:
ret 0008 (recuerda un parche ' fuerte'
no trabajará correctamente en la
comprobación del CRC...
causando una fallo de página... ¡Qué poderoso
son en Previewsoft)!
Ahora quienquiera que seas, expirado o no, el app
está trabajando, (aunque débilmente
crackeado!).
Apretando F12 una o dos veces tú debe volver
atrás en 4FA021 (mira anteriormente) justo antes
del condenado CALL EAX.
Como puede ver, EAX es ahora 43D680 y esta
situación no contiene ningún largo código
ficticio...
Reiniciamos el proceso entero entonces con un bpm
43D680, sólo para ver cómo y donde el parche
grande es aplicado.
Aterrizamos aquí:
* Reference To: KERNEL32.ReadProcessMemory, Ord:01D8h
|
:10015C23 FF158C940410 Call dword ptr [1004948C]
:10015C29 85C0 test eax, eax
:10015C2B 740B je 10015C38
..... ; algún código aquí
:10015C6A 50 push eax
:10015C6B 8D8D48FFFFFF lea ecx, dword ptr [ebp+FFFFFF48]
:10015C71 E84A140000 call 100170C0
* Referenced by a Jump at Address:10015C5C(C)
|
:15C76 8D45D8 lea eax, dword ptr [ebp-28]
:15C79 50 push eax
:15C7A 8B8548FFFFFF mov eax, dword ptr [ebp+FFFFFF48]
; Esta es la longitud = 0x716
:15C80 50 push eax
:15C81 8B854CFFFFFF mov eax, dword ptr [ebp+FFFFFF4C]
; dónde busca el parche
:15C87 50 push eax
:15C88 8B4DD4 mov ecx, dword ptr [ebp-2C]
--> dónde aplicarlo (=43D680)
:15C8B 51 push ecx
:15C8C 56 push esi
* Reference To: KERNEL32.WriteProcessMemory, Ord:0283h
|
:10015C8D FF1588940410 Call dword ptr [10049488]
--> ¡adelante, parchéalo!
:10015C93 85C0 test eax, eax
Ahora
nosotros tenemos todos los elementos para dar de
puntapiés esta majadería de aspirante a bueno
de TimeLOCK: aprieta F12 para llegar a 4FA021.
Realmente está despejado: nosotros queremos
guardar 716h bytes desde 43D680 a un archivo.
¿Cómo procedes? ¡Bien ensamblemos un pequeño
programa usando win32 API que lo harán para
nosotros! Como parece, el código sobre 4FA028 es
ficticio. Así que Nosotros trabajaremos aquí.
\>A 4FA040
Entonces teclea las instrucciones siguientes (yo
confío en win32 help incluye
archivos para los "pushes" con
CreateFileA y WriteFile):
push 0 ; ficticio pero necesario
push dword ptr 80 ; atributos_archivo_normal (no te olvides de dword ptr o pondrá un
'signed' FFFFFF80 ... me pasé 2 horas en este bug!)
push 02 ; crear_siempre
push 0 ; nulo (campo de seguridad)
push 0 ; archivo no es compartido
push 40000000 ; el archivo es sólo escritura
push 004FA200 ; la dirección del nombre del archivo
call KERNEL32!CreateFileA
push eax ; eax=manipulador. Lo ponemos para cerrar después del manipulador
push 0 ; uno ficticio
push 004FA100 ; dónde guardar el número de bytes escritos
db 68 16 07 00 00 ; Esto es: push dword ptr 0716, no manejé un poner 'real dword'!
push 43D680 ; Guardamos desde aquí
push eax ; el manipulador
call KERNEL32!WriteFile
call KERNEL32!CloseHandle
; El manipulador está aun en la cima de la pila
push ff
jmp 43D680 ¡Adiós!
Bien,
sólo teclea
>EB 4FA200
Y entra la ruta completa del archivo donde los
datos se guardarán, por ejemplo "C:\\bigpatch,0"
y ahora.... g=4FA040. Espero que tu HD no haya
sido formateado, los míos están OK: -)
|