<< O n
t h e w a y >> ( D o
y o u r e m e m b e r J a c k K e r
o u a c k ? )
Crackear un archivo empacado empleando este
método es sencillo con Snippet Creator, una herramienta
hecha para injertar código nuevo en archivos ejecutables
con formato PE. Así que consigamos este programa,
corrámoslo y creemos un proyecto nuevo: File\New
project. Este comando desplegará una ventana
donde podrás seleccionar el archivo que deseas cambiar
o desproteger y dar un nombre al proyecto. Cuando creas
un programa, Snippet Creator crea un subdirectorio con el
nombre que tú eliges y un archivo .INI que salva
la información y permite reabrir el proyecto.
1. Final de la rutina
desempacadora: Desplazamiento 1 - VA1 (Virtual Address 1)
Nuestro objetivo será api32 v2.4. Para
registrar este programa y obtener todas sus funciones podemos
buscar y calcular su serial. Pero he visto que esto puede
resultar un trabajo largo y arduo. A veces es preferible
(menos trabajo - mejor resultado, +ORC) parchar el archivo
ejecutable cuando se pueda. Tomaremos este camino.
Primero tenemos que ubicar el final de la
rutina que desempaca el archivo. Cargamos el programa con
SoftIce y bajamos de alguna manera (usando la tecla F10,
y ocasionalmente F5 y F9 para evitar los bicles [ loops
] ) hasta 00 41 B5 D2.
Esta instrucción es un salto [ jump
] al punto de entrada original del programa en la sección
.text:
:0041B5BD
8B 64 24 14
mov esp, dword ptr [esp+14]
:0041B5C1 5E
pop esi
:0041B5C2 8B FE
mov edi, esi
:0041B5C4 81 C6 D7 15 00 00
add esi, 000015D7h
:0041B5CA 6A 05
push 00000005h
:0041B5CC 59
pop ecx
:0041B5CD F3
repz
:0041B5CE A4
movsb
:0041B5CF 61
popad
:0041B5D0 66 9D
popf
:0041B5D2 E9 E9 9F FE FF
jmp 004055C0h ; <- Salto al punto de entrada
original
La instrucción en la dirección
00 41 B5 D2 es donde termina el cargador interno del programa
empaquetado. Llamamos a esta dirección VA1.
En esta dirección tendremos que escribir
una instrucción de seis bytes que tiene la forma:
1: push
address_of_snippet
2: ret
Estas instructiones entregarán el control
al recorte. Un código con esta forma tiene un tamaño
de seis bytes. En octal:
1: 68 zz yy xx 00
2: C3
El código octal 68h es la instrucción
empujar a la pila [ push ] un dato dword. El resto
de la instrucción es un número hexadecimal
de 32 bits que será empujado a la pila: 00 xx yy
zz h; este número es la dirección a la que
saltará el programa con la siguiente instrucción.
Así que la instrucción 1 será en ensamblador:
push 00 xx yy zz h
El código octal C3h corresponde a la
instrucción en ensamblador 'RET'. Esta instrucción
hace que el programa salte a la dirección a la que
apunte el registro SP o ESP (el puntero de pila). En este
caso es la dirección 00 xx yy zz h en la memoria
virtual del proceso y que antes metimos en la pila.
Pero todavía hay un problema. La
instrucción original en VA1 también está
empacada; entonces tenemos que esperar hasta que esta instrucción
sea cargada para escribir un primer salto [ jump
] al recorte: tendremos que localizar otra dirección
VA0 anterior a VA1 que entregue una primera vez el control
al recorte: en esta primera ocación, el recorte sobre-escribirá
la instrucción en la dirección VA1 para que
en VA1 el programa entregue nuevamente el control al recorte.
La segunda vez que el recorte recibe el control, parchará
el programa y lo desprotegerá. Por último
restaurará las instrucciones originales que reescribió
antes.
Una buena dirección para dar el control
al recorte por vez primera es:
:0041A110
0F 84 A7 14 00 00 je
0041B5BDh
Llamamos a esta instrucción VA0.
¿Cómo conseguirla?
Cargo el programa con el loader de SoftIce.
Cuando se despliega la ventana de SoftIce, ejecuto el comando
"D 41B5D2". Luego voy trazando las diversas
instrucciones del programa con la tecla F10 hasta ver como
se realiza un cambio en la dirección 41B5D2 en la
ventana de datos. Seguro aparecerá algo como "
FE 9F E9 E9 FF FE B5 BB ", que son los
valors octales de las instrucciones siguientes, pero invertidas:
:0041B5D2
E9 E9 9F FE FF
jmp 004055C0h ; <- Jump to the original entry point
:0041B5D7 E9 BB B5 FE FF
jmp 00406B97h
Entonces, cuando el programa llega a 00 41
A1 10 h, las instrucciones en la dirección 00 41
B5 D2 h estarán desempacadas y podrán ser
parchadas.
2. Un
lugar para el recorte. Desplazamiento 1 - VA2 (Virtual Address
2)
Para ubicar un lugar para el recorte podemos
emplear un método bastante empírico pero que
funciona. Abrimos el programa con un editor hexadecimal
como HexWorkshop y buscamos un sitio sin código,
lleno de ceros. Estos espacios amplios genertalmente podemos
encontrarlo al final de las diversas secciones. Así
que podemos encontrar un espacio amplio al final de la sección
.rsrc, en el desplazamiento 00 D3 20 h.
Podemos elegir este espacio. Tenemos el desplazamiento
dentro del archivo, pero necesitamos su dirección
virtual. Esta dirección la podemos calcular con esta
fórmula:
(Desplazamiento del
recorte - Desplazamiento del inicio de la sección)
+ VA de la Sección
A esta dirección la llamamos VA2.
Ya hemos determinado la sección donde
pondremos el recorte .rsrc. Para hacerlo ejecutamos en Snippet
Creator PE Info\View Section Info. Podemos ver que
este desplazamiento está en la sección .rsrc,
antes de la sección "madmat". El desplazamiento
de inicio de la sección [ Raw Offset of the section
] es 4A 00h.
La dirección virtual de la sección
[ VA of Section ] es: Dirección de la base de la
imagen [ Image Base Address ] + Desplazamiento virtual
de la sección [ VA offset of the section ]:
00 40 00 00h + 00 01 00 00 h = 00 41 00 00
h
Ahora calculamos:
VA2 = (00 D3 20h - 00 4A 00h) + 00 41 00 00h
= 00 41 99 20h
Esta es la dirección VA2.
3. La dirección
a parchar: VA3 (Virtual Address 3)
Ahora vamos a desproteger el programa. Por
razones de brevedad, considerando que el lector de este
tutorial no es propiamente un principiante, no detallaré
el proceso para ubicar el punto a parchar. Simplemente lo
diré. Para que el programa corra como si estuviera
registrado, con todas sus funciones, debemos cambiar en
el siguiente código:
:00404815
03EA
add ebp,
edx
:00404817 41
inc ecx
:00404818 4E
dec esi
:00404819 75DA
jne 004047F5
:0040481B 33C0
xor eax, eax
:0040481D 5F
pop edi
:0040481E 85ED
test ebp, ebp
:00404820 5E
pop esi
:00404821 5D
pop ebp
:00404822 0F94C0
sete
al
:00404825 5B
pop ebx
:00404826 59
pop ecx
:00404827 C3
ret
La instrucción:
:00404822
0F94C0
sete al
Es donde el programa coloca una bandera en
el registro al para indicar si el programa está
registrado o no. Si esta instrucción pone 1 en al,
el programa está registrado. Entonces podemos cambiar
esa instrucción de tres bytes por
:00404822
FEC0 inc eax
:00404824 90
nop
Esta instrucción hará a al diferente
de cero. Cuando el programa revise la bandera, actuará
como si el programa hubiera sido registrado y actuará
como tal.
Aunque esto sería suficiente para registrar el programa,
todavía necesitamos introducir nuestro nombre de
ususario y el serial. El programa revisa el número
de caracteres en el nombre de usuario (debe ser mayor que
cinco) y el de la clave (debe ser 16 o más).
Bien. ya tenemos la dirección de los parches.
4. Escribir y ensamblar
el recorte.
Tenemos que crear el proyecto en Snippset
Creator: File\New project. Lo llamamos api32.
Luego configuramos las opciones del proyecto:
Snippet VA = VA2 = 41 99 20
Patch Options = Patch into Existing Section
Address to Redirect Control To the Snippet = Redirect
Control From Code Section
VA1 = 00 40 17 75
Return Control to the program = Don't Return Control
To Program
Estas opciones eligen:
· la dirección virtual donde
el recorte será injertado (VA2)
· el recorte será injertado dentro de una
sección existente (.rsrc)
· la dirección virtual donde el programa dará
el control al recorte (VA1)
· el recorte no regresará el control al programa;
tenemos que hacerlo nosotros y escribirlo en el recorte.
· Snippet Creator no restaurará las instrucciones
originales del programa. Tenemos que hacerlo nosotros.
Luego escribimos el recorte y lo ensamblamos.
A continuación está el código del recorte
para TASM v5.0. Antes de ensamblar el recorte debemos elegir
y configurar el ensamblado que usemos. Ejecutamos en Snippet
Creator Action\Options para desplegar la ventana
"General Options". Escogemos el ensamblador (TASM
o MASM según sea el caso) y establecemos los comandos
y parámetros correspondientes. En mi caso particular,
que he empleado TASM v5.0, y tengo a Snippet Creator en
el directorio C:\ASM\ICZ\, los valores y comandos son:
Assembler
TASM
Locations
Assembler:
TASM32 /ml %1
Linker:
TLINK32 /Tpe /c
/aa /V4.0 %1,,,C:\TA\LIB\import32.lib
Project Directory: C:\ASM\ICZ\
Estos comandos suponen que el directorio donde
tengo TASM32.EXE y TLINK32.EXE, está en entorno;
es decir, cuando inicio la sección en Windows, el
archivo por lotes "autoexec.bat" tenía
la siguiente línea:
PATH C:\TASM\BIN;C:\TASM\LIB;C:\TASM\INCLUDE;%PATH%
A contiuación el código del
recorte:
; ----------------------------------------
code snippet ------------------------------------------
jmp init
oldinst1 db 00Fh,084h,0A7h,014h,000h,000h
oldinst2 db 0E9h,0E9h,09Fh,0FEh,0FFh,09Eh
newinst1 db 068h, 020h,099h,041h,000h, 0C3h
newinst2 db 0FEh,0C0h,090h
counter db 0
init:
pushad
cmp counter,0
jne time2
; Restaurar la instrucción
1
inc counter
mov edi,41A110h ;
dirección de la instrucción original 1 en
VA0
lea esi,oldinst1
; instrucción a restaurar
mov ecx,6 push ecx
; tamaño de la instrucción
original
rep movsb
;
restaurar la dirección original
; Escribir la nueva
instrucción en VA1: segundo salto al recorte
mov edi,41B5D2h ;
dirección donde se volverá a entregar el control
al recorte: VA1
lea esi,newinst1 ;
instrucción a escribir
pop ecx ;
tamaño de las instrucciones
rep movsb
; Retorno 1
popad
push 41A110h
ret
time2:
; Restauar intrucción 2
mov edi,41B5D2h ;
dirección de la instrucción original 2 en:
VA1
lea esi,oldinst2
; instrucción a restaurar
mov ecx,6
rep movsb
; Write new instruction
2: patch 2
mov edi,404822h ;
dirección de la instrucción original 2 en
: VA2
lea esi,newinst2
; instrucción
a escribir
mov ecx,3
;
tamaño de las instrucciones
rep movsb
; escribirlas
; Retorno 2
popad
push 41B5D2h
ret
; ---------------------------------------------------------------------------------------------------
Después de escribir estas lineas en
la ventana de edición de Snippet Creator, presionamos
el botón "Assemble" y esperamos. Si no
hay error, el recorte de código ha sido ensamblado
y enlazado.
Ahora podemos "exportar" el binario
correspondiente al recorte (File\Export) y salvamos
api32.bin.
Abrimos el archivo api32.exe con HexWorkshop
(conviene más emplear este editor que HIEW, ya que
necesitamos tener dos vistas desplegadas al mismo tiempo,
una del archivo api32.exe y otra del recorte api32.bin).
Vamos al desplazamiento 00D320 h ( Edit/Goto ). Es
el desplazamiento donde colocaremos el recorte de código.
Ahora abrinos el archivo api32.bin que hemos
exportado. Lo marcamos totalmente con el ratón y
lo copiamos (CTRL+C). Luego desplegamos la vista de api32.exe
y vamos al desplazamiento 00D320h y marcamos desde 00D320
hasta 00D39Eh. Ahora pegamos el recorte (CTRL+V). Para terminar,
ponemos en el desplazamiento 00D510h (correspondiente a
la dirección virtual VA0) la instrucción que
entrega el control al recorte por primera vez: 68 20 99
41 00 C3. Esto significa:
:0041A110 68
20 99 41 00 push
00419920
:0041A115
C3 ret
Recordar que el recorte ha sido colocado en
la sección .rsrc. Como sobrescribimos esta sección
con alguna instrucción debemos asegurarnos que soporte
escritura. Revisemos las características de la sección
.rsrc: PE Info\View Section Info. Las características
son: 40 00 00 40 h. Esto significa:
Datos Inicializados: 00 00 00 40 h
Lectura:
40 00 00 00 h
40 00 00 40 h
La sección no soporta escritura, así que tendremos
que editar las características. Para hacer esto hacemos
click con el botón derecho del ratón sobre
la cadena .rsrc que aparece en el cuadro de diálogo
"Section Information". Seleccionamos "Edit
Section" en el menú emergente: esto despliega
el vuadro de diálogo "Modify Section Values".
Pulsamos el botón "..." al lado del campo
"Characteristics". Esto despliega el cuadro de
diálogo "Section Charactheristics". Seleccionamos
la caja de chequeo IMAGE_SCN_MEM_WRITE y salvamos ( save
). Ahora las características de la sección
serán: C0 00 00 40 h:
Datos Inicializados: 00 00 00 40 h
Lectura:
40 00 00 00 h
Escribible:
80 00 00 00h
C0 00 00 40 h
Esto mismo lo tenemos que hacer para todas
aquellas secciones que serán escritas durante el
proceso, como el cargador del empacado, que es la sección
con que inicia un ejecutable empaquetaso. Eso es todo.
R e g i s t r a n
d o
Ahora corremos el programa y pulsamos el botón
'register'. Escribimos un nombre con más de cinco
caracteres:
Mi_Nombre
y un código serial con más de
dieciseis caracteres:
FREE-FREE-FREE-FREE
Hacemos click sobre OK, y listo...
|