TORN@DO presents: cRACKER's n0TES

Sistemas de Protección Comerciales : TimeLOCK



TimeLOCK 3.1 (JaZZ)
¡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: -)





TimeLOCK 3.13 - 3.15 (Marigold)


Yo pasé por alto esta versión cuando apareció primero, así que yo daré algún detalle aquí.

Las Nuevas características son:

La sección del código entera está encriptada.
La sección de .idata está encriptada.
El Checksum de la protección de la imagen de DLL es calculada en memoria (Realmente, no estoy seguro de que esta característica no estaba presente en versiones anteriores. Por lo menos, no creó ningún problema).
* Uso la palabra 'checksum' aquí y debajo en el sentido ' desmenuzar la función'
Desempaquetar no es tan simple como con la versión, además del procedimiento descrito anteriormente que generalmente permanece intacto, nosotros necesitamos restaurar la sección .idata

La restauración de información de la sección de .idata es similar a eso que se usaría después en VBox y se será descrito en otra parte.

Las diferencias son como sigue: 1) La información encriptada es guardada en la sección .idata por él mismo; 2) El primer campo de registro de 26-bytes para un objeto importado siempre contiene el índice de nombre de módulo en el array del nombre (-1 con significado ' previo' nunca es usado).

Consideremos cómo la información necesaria pudiera recolectarse en el caso de TL315INJ.DLL. Las diferencias con TL313INJ.DLL son mínimas.


      :1001830D 8BB52CFEFFFF            mov esi, dword ptr [ebp-1D4] 
      :10018313 8B9D30FEFFFF            mov ebx, dword ptr [ebp-1D0] 
      :10018319 85F6                    test esi, esi 
      :1001831B 742E                    je 1001834B 
  

Aquí [ebp-1D4] contiene una longitud y [ebp-1D0] un indicador para un array de strings terminado en cero, los nombres de los módulos y funciones importados y el array del nombre. Vuelca este array en un archivo.

Luego, nosotros necesitamos una descripción para cada función importada. Esta descripción es un 26(1A)-byte registro largo. Los registros se descifran a veces para unir una función importada. La unión sé empieza ha hacer en un loop 1839A... 18525.


      :1001839A 813DCC9D0410F8000000    cmp dword ptr [10049DCC], 000000F8 
      :100183A4 7523                    jne 100183C9 
      :100183A6 85FF                    test edi, edi 
      :100183A8 8D8564FAFFFF            lea eax, dword ptr [ebp+FFFFFA64] 
      :100183AE 50                      push eax 
      :100183AF 750C                    jne 100183BD 
      :100183B1 E82A7A0000              call 1001FDE0     ; Descifrado del 
      :100183B6 83C404                  add esp, 00000004 ; Primer registro 
      :100183B9 8BD8                    mov ebx, eax 
      :100183BB EB14                    jmp 100183D1 
      
      * Referenced by a Jump at Address:100183AF(C) 
       | 
      :100183BD E82E7B0000              call 1001FEF0     ; Descifrado del 
      :100183C2 83C404                  add esp, 00000004 ; todos los registros siguientes  
      :100183C5 8BD8                    mov ebx, eax 
      :100183C7 EB08                    jmp 100183D1 
      ; Ahora el ebx contiene un indicador al registro para la función importada actual 
      . . . 
      :10018503 8B4316                  mov eax, dword ptr [ebx+16] 
      :10018506 0305F04E0410            add eax, dword ptr [10044EF0] 
      :1001850C 8BC8                    mov ecx, eax 
      :1001850E 8B8560FFFFFF            mov eax, dword ptr [ebp-A0] 
      :10018514 8901                    mov dword ptr [ecx], eax ; Dirección de la función  
      :10018516 83C71A                  add edi, 0000001A        ; es grabada para importar  
      :10018519 FF45CC                  inc [ebp-34]             ; Tabla de Dirección  
      :1001851C 8B4DCC                  mov ecx, dword ptr [ebp-34] 
      :1001851F 398D64FFFFFF            cmp dword ptr [ebp-9C], ecx 
      :10018525 0F8F6FFEFFFF            jg 1001839A 
   

Uno necesita parchear código dentro de este loop para guardar todos los registros en un archivo trazado creado con SoftDump. Cuando esta vuelta incluye código de error de manipulación, que nunca trabaja, uno tiene espacio suficiente para este parche. Yo intencionadamente no doy ningún código para este parche de como próximo el paso está reconstruyendo en la sección .idata y requiere del cracker habilidades de programación superiores que esta tarea simple.

Una nota importante sobre el total de control de la imagen. Los creadores de esta protección ciertamente sigue nuestros 14 mandamientos: el checksum nunca es verificado contra su ' correcto ' el valor. En cambio es incorporado dentro de una clave de descifrado, así si uno hace un parcheado suave (el checksum del archivo es otro problema) en el momento inapropiado, el descifrado del array del nombre sale mal y el sistema cae.

Ahora debes tener en cuenta que poner un bpx actualmente significa el cambio de un byte en esta dirección a CC, aunque SoftICE no lo muestra. (Por supuesto, es aplicable a todas las versiones con código checksum comprueban).

Así, para conseguir unos recortes del código anterior, no debes poner breakpoints allí.

Aquí está una llamada a la función que calcula el checksum:

      :100159DF 8D851CFEFFFF            lea eax, dword ptr [ebp+FFFFFE1C] 
      :100159E5 50                      push eax ; Buffer para checksum 
      :100159E6 8D85B4FDFFFF            lea eax, dword ptr [ebp+FFFFFDB4] 
      :100159EC 50                      push eax 
      :100159ED 8D85BCFDFFFF            lea eax, dword ptr [ebp+FFFFFDBC] 
      :100159F3 50                      push eax 
      :100159F4 8D85C4FDFFFF            lea eax, dword ptr [ebp+FFFFFDC4] 
      :100159FA 50                      push eax 
      :100159FB 81F7494C0000            xor edi, 00004C49 ; "LI" <Weijun Li 
      :10015A01 57 	                   push edi 
      :10015A02 81F64A570000 	        xor esi, 0000574A ; "WJ" < iniciales 
      :10015A08 0335EC4E0410 	        add esi, dword ptr [10044EEC] 
      :10015A0E 56 	                   push esi 
      :10015A0F E8ECA50000              call 10020000 
      :10015A14 83C418 	        add esp, 00000018 

Así que, debes caminar hasta el final a través del código o puedes poner bpx 10015A0F, quitándolo a la llegada y poner los breakpoints necesarios después del retorno de esta función.






 
 
 
The cRACKER's n0tES esta dividido dentro de 12 partes principales:
 TX. Notas del Traductor
 00. INDICE
 01. Ensamblador para Cracker (CoRN2)
 02. SoftICE (Menú de arranque , Configuración, Comandos)
       
 1 Menú de arranque
       
 2 Configuración
       
 3 Comandos
 03. Breakpoints & Detalles de API de Windows
       
 1 Programas restringidos
       
 2 Cajas de diálogo
       
 3 Verificando el Tipo de unidad
       
 4 Acceso a archivos
       
 5 Acceso al Registro
       
 6 Cogiendo números de serie
       
 7 Accediendo a Tiempo & Fecha
       
 8 Generando ventanas
 04. Instrucciones de salto
 05. Instrucciones SET
 06. Tips & Trucos para Crackear
       
 1 Programas restringidos
       
 2 Dongles
       
 3 General
       
 4 Configuración de InstallSHIELD
       
 5 Protecciones con Archivo llave
       
 6 Pantallas molestas
       
 7 Límites de Runtime
       
 8 Serials
       
 9 Limites de Tiempo
       
10 Programas Visual BASIC
 07. Ventanas de Mensajes Para los Cracker
 08. Identificando funciones, Argumentos, y Variables (Rhayader)
 09. Los Sistemas de Protecciones de comerciales
       
 1 Armadillo
       
 2 C-Dilla SafeDISC
       
 3 SalesAgent
       
 4 SecuROM
       
 5 softSENTRY
       
 6 TimeLOCK
       
 7 VBox
 10. Bitmanipulation (Cruehead)
 11. Teoría general de Cracking
 12. FAQ

 +A. Cómo contactar conmigo
 +B. ¿Que es lo Nuevo?


 



The cRACKER's n0TES are Copyright 1998-2000 by TORN@DO of ID.
Todo los Derechos Reservados.
Traducido por
Revisado por X-Grimator.