Tutorial Crackme MadCrack v1 por karmany

Iniciado por karmany, 30 Diciembre 2008, 01:53 AM

0 Miembros y 1 Visitante están viendo este tema.

karmany

INTRODUCCIÓN

Hace unos meses, MadAntrax hizo un crackme curioso, en el que el registro se hacía mediante un keyfile. Como nadie más parece haberse interesando en él, publico ya el tutorial que hice entonces.

Dicho autor es moderador del subforo de Visual Basic y yo he descargado varias de sus colaboraciones, con lo que ya me imaginaba que este crackme iba tener bastante complejidad.

El crackme está compilado con Visual Basic en P-Code, así que este tutorial puede resultar de utilidad para saber analizarlos.
El post original de este crackme es el siguiente:
http://foro.elhacker.net/ingenieria_inversa/madcrack_crackme_v1_by_madantrax-t225985.0.html



TUTORIAL

La verdad que los programas compilados en Visual Basic con P-Code suelen ser más difíciles de analizar. Voy a mostrar cómo examiné este primer crackme de MadAntrax y seguro que para muchos P-Code puede ayudar.

Si utilizamos RDG Packer Detector 0.65 vemos que está empacado con UPX y nos muestra que ha sido compilado con Visual Basic. Si se ejecuta el crackme vemos que aparece un archivo oculto llamado "iexplore.exe" y tenemos un cuadrado de color rojo que para que esté crackeado tiene que estár de color verde, según el autor.

Descompilar UPX es sencillo y en Crackmes y tutoriales hay un link de cómo descomprimir UPX para ReNewbies, realizado por Shaddy.

Yo descomprimí UPX pero al ejecutarlo ví que el archivo "iexplore.exe"(que no le gusta OllyDBG) no aparece y algunas cosas más que no voy a comentar, así que debe de hacer algo el crackme para saber que ha sido descomprimido. Por este motivo sólo debuggeé el crackme directamente desde OllyDBG con un simple plugin para ocultarlo. El OEP es muy sencillo de descubrir: 401130

Por otro lado, como ya tengo el crackme descomprimido con UPX, lo analicé con P32Dasm v2.3 y lo desensambla perfectamente, y se obtiene muchísima información:

VB6 Aplicación detectada ... PCode

Form1 Eventos:
2. splet
3. lel
6. crypt
8. Check_KeyFile

clsCRC Eventos:
2. AddBytes
3. AddString
4. Algorithm
5. Algorithm
6. CalculateBytes
7. CalculateFile
8. CalculateString
9. Value
10. Value
12. Clear


El autor nos deja mucha información.
Hay muchas cosas interesantes, por ej.
00003DE3:  0D   VCallHresult App.Get_Path()
...
00003DEB:  1B   LitStr: "edocyek\"
00003DEE:  0B   ImpAdCallI2 StrReverse()
...
00003DF6:  2A   ConcatStr


Es muy fácil de entender. Primero toma la ruta del crackme. Después de una cadena "edocyek\" hace la inversa (StrReverse) obteniendo "\keycode" y lo une a la ruta. Después con ese archivo hace unas determinadas operaciones y finalmente tenemos un salto (BranchF) que nos pone el cuadrado rojo o verde.

La dificultad de P-Code es que se trabaja con opcodes y puede resultar muy lioso pero con un poco de práctica se entiende todo fácilmente.

Voy a hacer un ejemplo. La subrutina que nos interesa es la que nos pone el cuadrado verde o rojo. Esta subrutina es la Form1 1.8 (Check_KeyFile-->nombre muy llamativo jeje) y comienza en 00003DA0.
He mostrado que nos da la ruta de un archivo denominado "keycode". Y después de esto viene lo más difícil, aparece lo siguiente:

00003E3A:  1B   LitStr: "edocyek\"
00003E3D:  0B   ImpAdCallI2 StrReverse()
00003E42:  23   FStStrNoPop var_D0
00003E45:  2A   ConcatStr
00003E46:  46   CVarStr var_B4
00003E49:  25   PopAdLdVar
00003E4A:  04   FLdRfVar var_A4
00003E4D:  FF3E VarLateMemCallLdRfVar
00003E55:  04   FLdRfVar var_100
00003E58:  0A   ImpAdCallFPR4 Hex()


Lo más difícil es saber qué hace la función VarLateMemCallLdRfVar. Ni P32Dasm ni VB Decompiler nos da información, así que tiene que ser OllyDBG quién nos tenga que ayudar.
Como se observa, la función comienza por los opcodes FF3E y está en el offset 3E4D. Voy a cargar el crackme original en el OllyDBG.
Como el OEP es 401130 pongo un Hardware Breakpoint allí y pulso F9. Ahora estoy parado en el OEP.
Ahora tengo que parar antes de VarLateMemCallLdRfVar que está en 3ED4, por lo tanto como la image base está en 400000 pues la dirección final es 403ED4.
Parado en el OEP, voy a la ventana de dump, botón derecho goto --> 403ED4 (ahí tienes que ver ya los bytes FF 3E) y pongo un Breakpoint --> memory on access. Pulso F9 y se detiene en un

MOV AL,BYTE PTR DS:[ESI+2]

que está dentro de MSVBVM60.dll. Estamos justo antes de la llamada a VarLateMemCallLdRfVar.

Ahora simplemente hay que ir traceando con F7 hasta llegar a una Call ... y si miramos la pila observaremos algo parecido a esto:

0013F7EC   00402694  UNICODE "CalculateFile"
0013F7F0   00000001
0013F7F4   0013F804
0013F7F8   80000003
0013F7FC   0013F8D4
0013F800   0013F920
0013F804   00000008
0013F808   00000000
0013F80C   00174EF4  UNICODE "C:\Documents and Settings\usuario\Escritorio\keycode"


Como se observa, la función a la que hace referencia es a "CalculateFile"

Ya he mostrado cómo acceder desde el OllyDBG a cualquier opcode que nos muestre VB Decompiler Lite, así que cada uno ya puede examinar el código que quiera. Se pierde bastante tiempo sabiendo lo que hace cada cosa... también me ha costado a mi.

Si vamos ahora a VB Decompiler veremos que "CalculateFile" llama a la subrutina "CalculateBytes" y ésta última a su vez llama a la subrutina "AddBytes", que es la importante que interesa.

Ésta (AddBytes) tiene una función muy conocida y muy curiosa:

loc_4039A9: ImpAdCallFPR4 CallWindowProc(%x1, %x2, %x3, %x4, %x5)

A la que se le pasan 5 parámetros.
Ya sabéis parar antes de esta CallWindowProc, así que vamos a hacerlo.

Cuando estéis ahí, poner un BP en CallWindowProcA, F9 y mirar la pila:
0013EAB4   660FD37B  /CALL to CallWindowProcA from MSVBVM60.660FD379
0013EAB8   0016E130  |PrevProc = 0016E130
0013EABC   00160628  |hWnd = 00160628
0013EAC0   00174E58  |Message = MSG(174E58)
0013EAC4   00176C48  |wParam = 176C48
0013EAC8   00000004  \lParam = 4


Hay que observar ese interesante PrevProc = 0016E130, así que vamos en la ventana de desensamblado a esa dirección y nos encontramos con lo siguiente:

0016E130    55              PUSH EBP
0016E131    89E5            MOV EBP,ESP
0016E133    57              PUSH EDI
0016E134    56              PUSH ESI
0016E135    50              PUSH EAX
0016E136    53              PUSH EBX
0016E137    51              PUSH ECX
0016E138    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]
0016E13B    8B00            MOV EAX,DWORD PTR DS:[EAX]
0016E13D    8B75 0C         MOV ESI,DWORD PTR SS:[EBP+C]
0016E140    8B7D 10         MOV EDI,DWORD PTR SS:[EBP+10]
0016E143    8B4D 14         MOV ECX,DWORD PTR SS:[EBP+14]
0016E146    31DB            XOR EBX,EBX
0016E148    8A1E            MOV BL,BYTE PTR DS:[ESI]
0016E14A    30C3            XOR BL,AL
0016E14C    C1E8 08         SHR EAX,8
0016E14F    33049F          XOR EAX,DWORD PTR DS:[EDI+EBX*4]
0016E152    46              INC ESI
0016E153    49              DEC ECX
0016E154  ^ 75 F2           JNZ SHORT 0016E148
0016E156    8B4D 08         MOV ECX,DWORD PTR SS:[EBP+8]
0016E159    8901            MOV DWORD PTR DS:[ECX],EAX
0016E15B    59              POP ECX
0016E15C    5B              POP EBX
0016E15D    58              POP EAX
0016E15E    5E              POP ESI
0016E15F    5F              POP EDI
0016E160    89EC            MOV ESP,EBP
0016E162    5D              POP EBP
0016E163    C2 1000         RETN 10


Éste es todo el código que utiliza para obtener un CRC del archivo "keycode". Después hace ya una última operación que es un NOT.

¿Y con qué se compara?
Bueno, es también bien fácil...

Subrutina Check_KeyFile
...
00003E7D:  3A   LitVarStr: "2@G855G"
00003E82:  4E   FStVarCopyObj var_B4
00003E85:  04   FLdRfVar var_B4
00003E88:  10   ThisVCallHresult --> %x2 = crypt(%x1) ;aquí está el truco
00003E8D:  04   FLdRfVar var_F0
00003E90:  FB33 EqVarBool =
00003E92:  36   FFreeVar var_B4 var_F0
00003E99:  1C   BranchF   00003EAA


Con toda esta explicación pienso que ya están destripadas las entrañas del crackme, espero que se entienda.
Yo a partir de este momento creé un programa en ensamblador que fuera examinando CRC's y descubrí que si el archivo keycode tiene los siguientes caracteres: "4R)@" queda el cuadrado perfectamente de color verde... objetivo logrado.


Un saludo
karmany
09 - septiembre - 2008