sábado, 10 de mayo de 2008

Articulo de Programacion #2 (Parte 2)

Dll Injection (Parte 1)


Ya vimos lo que es un proceso y un hilo o thread en la parte anterior, sabiendo como son los procesos, la unica manera de poder ejecutar una funcion en su contexto seria creando un hilo dentro de el, la pregunta seria como hacerlo, ya que normalmente un proceso solo puede crear hilos dentro de si mismo, Microsoft nos dio un regalo para superar esa adversidad bajo usermode, y nos brinda la funcion llamada CreateRemoteThread:


HANDLE WINAPI CreateRemoteThread(

HANDLE hProcess,

LPSECURITY_ATTRIBUTES lpThreadAttributes,

SIZE_T dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreationFlags,

LPDWORD lpThreadId

);


Analicemos la funcion, el primer parametro es un handle representando el proceso en el que queremos crear el thread, lpThreadAttributes son los atributos de seguridad del thread a crear, generalmente este parametro no lo usamos, dWStackSize es el tamaño que tendra la pila del thread creado, lpStartAddress seria el parametro mas importante, especifica la direccion donde empieza el thread creado, lpParameter es un puntero a una variable que le podemos pasar la funcion del thread, ojo, como estamos en contexto de otro proceso, ese parametro lo tenemos que alojar en el proceso remoto (mas adelante se explicara), dwCreationFlags significa la manera de como se crea el nuevo Thread, se puede dejar en tres estados, los mas importantes, son en estado Pausado o Resumido, el ultimo parametro es un puntero que recibira el ThreadId del nuevo thread creado.

Primeramente para poder usar la funcion, necesitamos sacar el handle del proceso en el que queremos crear el thread, como se explico, un proceso es un objeto ejecutivo en el kernel de windows, un handle es una representacion abstracta de ese objeto que hace referencia al mismo. Para poder obtener el handle, primero necesitamos obtener el ProcessId del proceso, el processid es una manera de simplificar el significado del proceso, y es que realmente es un handle que hace referencia a su localizacion en la PspCidTable, una tabla de handles que mantiene un registro de todos los procesos creados. Una de las tantas maneras de obtener la pid es localizando el nombre de la ventana del proceso, por ejemplo digamos que el buscamina muestre un cuadro de dialogo que pregunte si deseas cerrar la aplicacion o no, esto de manera inmediata y sin permiso previo del programa, primero necesitamos localizarlo, esto se haria usando la funcion FindWindow:


HWND FindWindow(
LPCTSTR lpClassName,

LPCTSTR lpWindowName

);


El primer parametro de esta funcion lo pasamos para especificar el nombre de la clase de la ventana a encontrar, el segundo para especificar solamente el nombre de la ventana (es la que usariamos mas habitualmente), se pueden pasar ambos parametros tambien de ser necesario. Si la funcion es un exito, regresa el HWND de la ventana encontrada, un HWND es tambien un handle que hace referencia a la ventana requerida. Ahora una vez que la ventana ha sido encontrada, necesitamos obtener el process Id de quien la ventana pertenece, eso lo hacemos con la funcion GetWindowThreadProcessId:


DWORD GetWindowThreadProcessId(
HWND hWnd,

LPDWORD lpdwProcessId

);


El primer parametro de esta funcion es el HWND de la ventana de la que queremos saber el process id del proceso a quien pertenece, el segundo parametro es un puntero que recibe el processid de la ventana requerida, la funcion retorna el ThreadId del HWND de la ventana pasada a esta funcion. Ahora que ya tenemos el processid, ya podemos obtener el handle a este, el cual obtendremos con la funcion OpenProcess:


HANDLE WINAPI OpenProcess(

DWORD dwDesiredAccess,

BOOL bInheritHandle,

DWORD dwProcessId

);


El primer parametro de esta funcion es el acceso que tendra el handle referenciado, por lo general siempre se usa la constante PROCESS_ALL_ACCESS. El segundo parametro es para indicar si el handle es heredado de un proceso padre, por lo general este parametro es puesto en falso, por ultimo el parametro mas importante, dwProcessId, aqui se pasa el processid del proceso a referenciar. Como resultado la funcion retorna la referencia al objeto del proceso, es decir el handle.

Y ahora si, tenemos lo mas importante para crear un Thread en el proceso, ahora es cuestion de poner todo esto en orden y ponerlo a la practica, pero eso lo veremos en la tercera parte de este articulo xD.

No hay comentarios: