Una vez instalado el software
ejecutaremos el programa vuepro32.exe y este nos presentará
una pantalla donde nos comunica los diás de evaluación que
nos quedan y nos solicitará un numero de serie, fijate que
sólo nos pide el número, y no un nombre y un número como
suele ser habitual.
Podremos continuar si no le
introducimos el número de serie y pulsamos sobre OK, pero
esta pantalla nos volverá a aparecer cuando volvamos a ejecutar
el programa.
La
primera modificación... |
Nuestro primer objetivo aquí es eliminar esta pantalla,
he seleccionado este método porque en esta entrega usaremos
una nueva técnica para la eliminación de nags de este tipo.
Podriamos buscar un número de serie válido pero no era este
mi objetivo.
Bueno debemos saber que hemos
de eliminar un cuadro de dialogopara
ello necesitamos saber que funciones del API de Windows
se utilizan en la creación de este tipo de cuadros de diálogo.
Aquí enumero las más utilizadas.
DialogBox
DialogBoxParam
DialogBoxIndirect
DialogBoxIndirectParam
Recuerda que si son en 32 bits
(Windows 95 o superior) llevaran una letra 'A' añadida al
final de la función, esto sólo se cumple en algunas de estas
funciones y no en todas, para mayor información te recomiendo
que tengas a mano la ayuda del API de Windows (43 Mb). La
más utilizada de estas tres suele ser la segunda : DialogBoxParam
Pues nada, activamos el SoftIce
(Ctrl+D) y ponemos los siguientes bpx:
:bpx DialogBoxParam
:bpx DialogBoxParamA
Ahora ejecutamos el programa
y comprobaremos que el control vuelve al SoftIce antes de
que aparezca el cuadro de diálogo (ok todo funciona),ahora
estamos en el SoftIce al inicio de la función DialogBoxParamA
pulsamos F12 hasta que en la pantalla del SoftIce aparezcamos
debajo de la llamada call DialogBoxParamAsi
examinamos la rutina donde estamos veremos algo así:
:0044C270
push ebp -> reajusta la pila
:0044C271 mov ebp, esp
:0044C273 mov eax, dword ptr [ebp+08]
:0044C276 push [eax+14] -> empuja el quinto argumento
:0044C279 push 0044BF6F -> empuja el quarto argumento
:0044C27E mov edx, dword ptr [eax]
:0044C280 cmp dword ptr [edx+14], 00000000
:0044C284 je 0044C290
:0044C286 mov ecx, dword ptr [eax]
:0044C288 mov edx, dword ptr [ecx+14]
:0044C28B mov ecx, dword ptr [edx+0C]
:0044C28E jmp 0044C292
* Referenced by a (U)nconditional or (C)onditional Jump
at Address:
|:0044C284(C)
|
:0044C290 xor ecx, ecx
* Referenced by a (U)nconditional or (C)onditional Jump
at Address:
|:0044C28E(U)
:0044C292 push ecx -> empuja el tercer argumento
:0044C293 push [eax+10] -> empuja el segundo
argumento
:0044C296 mov eax, dword ptr [eax]
:0044C298 mov edx, dword ptr [eax+6C]
:0044C29B push [edx+08] -> empuja el primer argumento
* Reference To: USER32.DialogBoxParamA, Ord:0000h
:0044C29E Call USER32.DialogBoxParamA
:0044C2A3 pop ebp
:0044C2A4 ret
Como podemos comprobar se preparan
los argumentos necesarios para llamar a la función DialogBoxParamA
y luego se realiza esta llamada, la pregunta es ¿
Que parametros se pasan a esta función ?. Aquí tienes
la respuesta:
int DialogBoxParam(
HINSTANCE
hInstance, // handle a la instancia de la aplicación
LPCTSTR lpTemplateName, // Identifica la clase
de cuadro de dialogo
HWND hWndParent, // handle a la ventana propietaria
DLGPROC lpDialogFunc, // puntero al procedimiento
del cuadro de diálogo
LPARAM dwInitParam // valor de inicialización
);
Podriamos eliminar la llamada
a DialogBoxParam facilmente, pero esto sería erróneo ya
que esta rutina se utiliza para llamar a todos los cuadros
de diálogo que nuestro programa hace servir (sino te lo
crees pon un bpx sobre ella y compruebalo tu mismo), por
lo que esto dificultará nuestra tarea (si no pensamos adecuadamente).
Bueno sabemos que uno de los parámetros usados por DialogboxParamA
es un identificador de cuadro de diálogo
(único para cada uno de los cuadros que puede contener la
aplicación) por lo que deberiamos averiguar
cual según el funcionamiento de la pila, lo
que buscamos está en:
:0044C293
push [eax+10] -> empuja el segundo argumento,
Identificador del cuadro de diálogo
Recuerda que los argumentos
son empujados a la pila en orden inverso para ser restaurados
en su orden normal.En la dirección [EAX+10] se encuentra
nuestro ID de cuadro de diálogo. Pondremos un bpx sobre
esta linea (44C293) y quitaremos
el resto de bpx. Volvemos a ejecutar el programa y esperamos
hasta que tengamos el control, ahora podemos ver cual es
el valor de nuestro ID tecleando en el SoftIce :
:d
[eax+10]
En la ventana de datos veremos
52 04 00 00 , como es un dword con ordenamiento Intel
el número real es 0000452.
Bueno ya tenemos lo que buscabamos una referencia al cuadro
de diálogo que deseamos eliminar, ahora desactivamos el
bpx y salimos del programa. Procederemos a desensamblar
una copia del ejecutable con el W32Dasm. Una vez terminado
este proceso, hacemos click sobre el botón DlgRefy
buscaremos todas las posibles referencias al cuadro de diálogo
452veremos
las siguientes:
Dialog:
DialogID_0452
Dialog: DialogID_0452, CONTROL_ID:05FC, ""
Dialog: DialogID_0452, CONTROL_ID:05FD, ""
Dialog: DialogID_0452, CONTROL_ID:05FE, ""
Haremos doble click en la primera
por ser la la que se refiere al cuadro en si, las otras
son referencias a controles de este cuadro. Veremos que
el W32Dasm nos muestra un código, si lo examinanos veremos
que no hay ningun salto cercano a la referencia, por lo
que ignoraremos esta referencia y volveremos a hacer doble
click sobre Dialog: DialogID_0452para
que nos lleve a la siguiente referencia, ahora veremos el
siguiente código:
:0047924A
call 0046BF58 -> Llama a una función
:0047924F pop ecx
:00479250 test eax, eax -> Comprueba valor de
retorno
:00479252 je 00479268 -> si es 0 nos envia a
donde se carga el ID del cuadro de diálogo :)y esto no
es lo que queremos
:00479254 mov edx, dword ptr [ebp+FFFFFF28] ->
continuamos normalmente
:0047925A mov dword ptr fs:[00000000], edx
:00479261 mov eax, edx
:00479263 jmp 00479343 -> y saltamos a una dirección
de código superior a la 479285 esquivando así la referencia
:)
* Referenced by a (U)nconditional or (C)onditional Jump
at Address:
|:00479252(C)
:00479268 mov edi, dword ptr [ebx+49]
:0047926B lea edx, dword ptr [ebp+FFFFFF48]
:00479271 mov esi, dword ptr [edi+000005B8]
:00479277
66C78538FFFFFF0800 mov word ptr [ebp+FFFFFF38], 0008
:00479280 6A00 push 00000000
:00479282 83C4FC add esp, FFFFFFFC
* Possible Reference to Dialog: DialogID_0452
:00479285 C7042452040000 mov dword ptr [esp], 00000452
-> esta es la referencia al cuadro de diálogo
Bueno parece claro ¿ o no ?,
eliminando el salto en :00479252
podremos esquivar la referencia. Pues probemos, hagamos
click sobre esta linea y apuntemos el offset
(78852h) de la instrucción que ocupa 2
bytes(74 14). Ahora
en nuestro editor hexadecimal preferido reemplazaremos los
dos bytes en el offset 78852h (74
14) por 90 90 (NOP NOP), Probamos el programa y...
funciona, pero aún no hemos terminado.
La
segunda modificación... |
Falta por eliminar el banner que aparece cuando se termina
el periodo de evaluación, para poder ver este banner deberemos
ir incrementando la fecha del sistema e ir ejecutando el
programa cada vez, ya que parece ser que este programa no
usa el sistema "normal" para contar los dias que
lleva instalados. Bueno cuando tengamos el programa con
su tiempo de evaluación terminado, podremos comprobar que
nos aparece un mensaje en medio de la pantalla que dice:
"You
trial evaluation period has ended... bla bla"
Si te crees que podrás usar
el metodo de las referencias a cadena vas equivocado, no
encontraras ninguna referencia directa a esta cadena. Oh
! que putada, ¿Entonces, cómo lo haremos ?. Pensando...
, es una cadena, es una entidad gráfica de texto y como
tal debe dibujarse, y ¿ Cómo se dibuja
un texto en Windows ?, pues con una de las siguientes
funciones:
TextOut
DrawText
Estas dos funciones son las
más sencillas y son las de mayor probabilidad de éxito aunque
tienen el inconveniente que son usadas por Windows para
dibujar la mayoria de sus textos incluido el de los botones,
por lo que habrá que ser paciente cuando tratemos con ellas
e ir trazando con F12 hasta que nos paremos después de pintar
el texto que no deseamos que aparezca. Un consejo: no activar
los bpx a estas funciones hasta que estemos cerca de donde
queremos empezar a trazar, ya que si no podriamos tardar
horas en llegar a donde queremos.
Prueba con TextOuta
que es más sencilla que DrawText, aquí tienes una definición
de la función:
BOOL
TextOut(
HDC hdc,
// handle del dispositivo de contexto
int nXStart, // coordenada x de inicio
int nYStart, // coordenada y de inicio
LPCTSTR lpString, // puntero a la cadena a imprimir
int cbString // numero de caracteres a imprimir
);
Bueno este trabajillo te lo
dejo a ti solo, espero que seas capaz de hacerlo, ya tienes
todas las pistas necesarias. Es muy sencillo, cuando encuentres
la función donde se llama a TexOut sólo tienes que hacer
que retorne con EAX=1. Si no lo tienes muy claro mira mi
tutorial número 5 en el se utiliza un metodo similar para
evitar que se imprima el banner.
|