FabriCAD Suite v3.0 - Tutorial

Este objetivo en especial me sirvio hace poco como un buen ejercicio de abstract dongle reversing(ingenieria inversa?),tu sabes,crackear esto a primera vista parece como un aburrido parcheado de los normales .exe´s.de hecho practicamente se puede hacer asi,ahora (haciendolo al reves,invirtiendolo?) es la mejor manera para aprender y hacer los mejores cambios a un programa.

FabriCAD son una clase de programas,de acuerdo con lo que dicen en su manual,hay 3 limitaciones(todas las restricciones en el numero de elementos(beam,braces and columns).Espiando la referencia String, no podemos olvidarnos de los Check(ahora os mostrare 1 ejemplo,pero hay muchos mas)

:004CD894 CALL 005B7F36 <-- CALL protection_and_other_unrelated_routines.
:004CD89C CMP DWORD PTR [EAX+0xFC], 0 <-- Check_flag.
:004CD8A3 JZ 004CD914 <-- Jump_past_nag_user.
:004CD8A8 CMP DWORD PTR [EAX+28], 0xA <-- Else_check_columns.
:004CD8AC JL 004CD914 <-- Demo_user_okay.

 

Bueno,ahora esta claro que queremos echarle un vistazo a la CALL que establece esta flag,y ahora es su final,hay 800 sitios donde se hace alusion a esta flag( esa es mi estimacion a ojo,sin contarlas),entonces que es lo que haria un cracker vago ,bueno, simplemente buscaria los opcodes para esta flag(83 B8 FC 00 00 00 00) y los sustituiria por(C6 8B .. .. .. .. EB) para ajustar la flag a 0 y forzar el salto inmediatamente despues .Eso posiblemente funcione,pero no es la mejor manera porque hay muchas referencias para esta flag,las cuales no corresponden con las de la simple y bonita String Ref. 

 La manera de proceder es hacer pinpoint al codigo que ajusta esta flag,entonces estableceremos un bpm en la localizacion single byte (la cual cambia/se apaga?) a ser 62CB14, excepto relocalizacion/redireccionamiento.Ahora encontraremos la proteccion real :

:004E70AF CALL RESecure42 . Ord:0001h <-- Returns EAX=7.
:004E70B4 CMP EAX, 7
:004E70B7 JNZ 004E70D7 <-- Jump_good.
:004E70B9 MOV ECX, DWORD PTR [EBP-10] <-- Grab pointer.
:004E70BC ADD ECX, 0xFC <-- Retrieve our magic flag.
:004E70C2 MOV DWORD PTR [EBP-14], ECX <-- Store pointer.
:004E70C5 MOV DWORD PTR [ECX-4], 0 <-- Another_bad_flag.
:004E70CC MOV DWORD PTR [ECX], 1 <-- Move_bad_flag.

En este momento yo ya sabia que me estaba enfrentando con un Hardlock dongle (\\.\HARDLOCK.VxD),una mirada rapida al status de de los codes API nos revela 7 = no lock connected,bueno,vamos a tracear la ddl,la proxima parte desafia la s creencias.

:xxxx9DE6 PUSH 10019508 <-- "Hasp".
:xxxx9DEB MOV ESI, DWORD PTR [100692B4] <-- MSVCRT._mbscmp
:xxxx9E02 MOV EAX, DWORD PTR [EBP-14] <-- "Demo".
:xxxx9E05 PUSH EAX <-- Onto the stack.
:xxxx9E06 CALL ESI
:xxxx9E0B TEST EAX, EAX
:xxxx9E0D JNZ xxxx9E1E
:xxxx9E0F MOV DWORD PTR [10037ABC], 0 <-- Return flag.

.....and now for more flag setting.

:xxxx9E1E PUSH 10019500 <-- "NetHasp".
:xxxx9E30 MOV DWORD PTR [10037ABC], 
<--Necesito comentar lo siguiente,

que sucede cuando hat una checking routine realmente ineficaz,para no menos que 8diferentes dispositivos para protecciones(los otros son Glenco, NetGlenco, GlencoNetwork, Sentry, NetSentry & SentinelLM),al final la demo sera checkeada y entonces es nuestro retorno a ajustar a 7.Este codigo necesita un parcheado,yo elegi utilizar "Hasp",pero cualquiera de los demas parcheadores posiblemente tambien servira,mientras nuestra insistencia se mantenga .Parcheé el codigo apropiadamente ,esperando que funcionara,y entonces apareció un problema,un GPF,aparentemente existe algun tipo de rutina de checkeo entrometida que detectó mi parcheado,esta rutina es bastante rara,y felizmente te deja NOP out ambos el TEST y decidir el JNZ,que es exactamente lo que haria un cracker vago.Soy un poco pedante,hasta cuando parcheo,yo realmente queria cambiar la "Demo" a "Hasp" antes de la CALL ESI y evitar usar NOP's juntos.

A little harmless foray into PE patching

Podemos ver de un listado de W32Dasm que hay una cantidad de espacio libre al final del de la seccion de .reloc ,entonces la idea es la siguiente,insertaremos un JMP en nuestra pequeña rutina,editaremos la "Demo" al "Hasp" en la memoria y entonces hacemos CALL ESI (the compare) antes de saltar hacia atras,para esto necesitaras hacer un parcheado seguro del PE,incrementando el tamaño virtual de .reloc ,pasndo asi de 0x2518 a 0x2600(el tamaño crudo de las secciones)Asi es como queda el nuevo codigo

 :xxxx9EE6 far JMP xxxxBB5F (E9 74 1C 07 00)
:xxxxBB5F MOV DWORD PTR [EAX], 0x70736148 (C7 00 48 61 73 70) <-- "Hasp".
:xxxxBB65 CALL ESI (FF D6) <-- Now compare them.
:xxxxBB68 ADD ESP, 8 (83 C4 08) <-- Correct the stack.
:xxxxBB67 far JMP xxxx9EEB (E9 7C E3 F8 FF) <-- Jump back.

Bueno,te estaras preguntando porque no utilice CALL,la respuesta es facil,introduciendo un CALL con la "Demo" pointer ya empujada en el stack yo hubiera estado haciendo el trabajo.Por supuesto ahora me doy cuenta que con esta demo string es una llave de registro,BUH!,por eso el ultimo parcheado enterito era completamente innecesario,si embargo es divertido para añadirlo a vuestras rutinas :-.Bueno,volvemos a fabricad.exe 

:004E70D7 CALL RESecure42 . Ord:0003h <-- Returns EAX=0.
:004E70DC TEST EAX, EAX
:004E70DE JNZ 004E7118 <-- Evidently good.

Ord:0003h es tambien una exportacion muy interesante como el valor devuelto por Ord:0001h es utilizado en un procedimiento de switch,como yo elegi emular a Hasp,finalizamos en un territorio familiar,La rutina HASP con servicio de code checks (xxxx5059). Services 1, 5, 2 (seed codes from a large table), 6, 3 & 50.

Esta es una rutina de checkeado bastante buena,aunque el checkeado de las palabras es flojillo.El servicio 2(HaspCode) es donde esta el meollo de la cuestion,la proteccion escoge un codigo seed (semilla?) el cual va asociado con con un indice valor de 0-0x7A0,entonces pasa a un 2k lookup table de los codigos de retorno requeridos .De hecho,esta table causa problemas,lo hiciera el encargado de la proteccion intencionadamente o no.El problema es este,cuando empece a codificar mi rutina de emulacion para Service 2 tuve 2 opciones ,insertar mi rutina HaspCode generica o utilizar la table.Ahora que mi programa HASPKill utiliza el primero/antiguo ,estaba poco dispuesto a exponer mi codigo de servicio2 ASM (aunque para ser honesto eso no es realmente tan duro que lo hagas tu mismo),en vez de eso yo hubiera hecho lo siguiente : 

PUSH ESI
PUSH EDI <-- Save on the stack (note I don't use EAX-EDX as these will hold the return codes).
MOV ESI,[ESP+xx] <-- Get the table index (somewhere offset from the stack).
MOV EDI, start_of_table <-- Start of the table.
ADD EDI,ESI <-- Add the index.
MOV EAX,EBX,ECX,EDX, DWORD PTR [return_codes] <-- Get the correct return codes.
POP EDI
POP ESI <-- Restore.
RET <-- Return from emulation.

Por supuesto que esto parece realmente sensible,pero hay un pequeño defecto en el problema de la relocalizacion/reubicacion.Echale un vistazo al codigo de checkeado del dll

:xxxx76A8 CALL xxxx5033 <-- hasp().
:xxxx76B0 MOV ECX, DWORD PTR [EBP+00] <-- First return code.
:xxxx76B3 CMP DWORD PTR [EDI+10018A5C], ECX <-- Check return code.
:xxxx76B9 JNZ 100076E8

Entonces ves que MOV EDI, 10018A5C es un iff valido(la terminologia matrematica lee" if" y solo" if")la ddl no esta reubicada(pero se reubica mas a menudo que no).Bueno,vamos al trapo,es sencillo,puedes utiizar EBP como una direccion relativa a la table,por eso en vez de MOV EDI, start_of_table utilizamos LEA EDI, [EBP+required_offset].Esto soluciona el problema para mas seguridad,mencionare los checks del servicio 3

0,1,2,0xF,0x37,son las posiciones verificadas, como codigos de retorno aseguraran tu felicidad:-).

Conclusion,he trbajado mas de loque queria en este crack,simplemente podriamos haberlo parcheado todo utilizando NOP's,desordenado pero posiblemente efectivo ,pero esto no es tan satisfactorio como emular completamente el ddl.Mientras tu lees esto,el crack de alguna descripcion deberia estar saliendo a la escena,te recomiendo que pruebes este tu mismo.Naturalmente tambien podrias borrar la string de la "demo",editando la correspondiente llave de registro.

Addendum - Staad Suite.Unas pocas semanas despues de escribir este tutorial,tuve la oportunidad de estudiar la suite de programas a los que Fabricad pertenece,y adivina,todos usan la misma HASP dongle,la primera palabra del dongle(index 0) ,actua como un interruptor de control para la suite entera(es una proteccion muy buena usando 3 tables y otras palabras dongle),yo utlice la fuerza bruta 9F77 para que fuera valida para todos los modulos,otras posiciones fueron tambien verificadas por varios componentes utilizando varias secuencias de TEST AH,xx .

Fui capaz de recuperar/recubrir como 10 palabras mas teniendo acceso a la suite ,por supuesto eso no hace la mas minima diferencia si tu estas trabajando con mi ejemplo de arriba :-). ------------------------------------------------------------------------------- Dongles Return to Main Index -------------------------------------------------------------------------------- 1999 CrackZ. 4rth September 1999.

www.000webhost.com