Inyección de Codigo para API Hook

Iniciado por Keyen Night, 16 Abril 2011, 05:42 AM

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

Keyen Night

LLevo no mucho tiempo programando en C++ estoy intentando hacer un hook por inyección de código, tengo el código que inyecta código directamente en un proceso y tengo la funciones que hacen un hook por tramplín a una función (API). Quisas este equivocado o suene ignorante XD soy nuevo con los hook y estas cosas quisiera que me corrigieran si estoy equivocado, mi pregunta es: ¿debo inyectar en el proceso externo las funciones que se encargan del hook?, quiero decir para que el proceso externo ejecute el mismo la función que hookea el API. Pero no entiendo como hacerlo llevo horas y me tiene confundido :-X si me pudiesen hechar una mano solo darme el camino para seguir estaria agredecido. Les dejo los sources:

Hook por Trampolín (Ejemplo en el mismo Proceso)
Código (c++) [Seleccionar]

#include <windows.h>
#include <stdio.h>

DWORD HookFunction(LPCSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction, unsigned char *lpBackup);
BOOL UnHookFunction(LPCSTR lpModule, LPCSTR lpFuncName, unsigned char *lpBackup);
int Hooked_MessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);

BYTE BackUp[6];

LPCSTR Function = "MessageBoxExA";

void WinMainCRTStartup()
{

MessageBoxA(0, "=( Sin Hook", "", MB_OK); // Mensaje

HookFunction("user32.dll", Function, Hooked_MessageBox, BackUp); // Hookear Función

MessageBoxA(0, "=( Sin Hook", "", MB_OK); // Mensaje

}

int Hooked_MessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) // Función a la que se desvia la función original
{
UnHookFunction("user32.dll", Function, BackUp); // Se llama a la función UnHook para evitar la recursividad

int x = MessageBoxA(hWnd, "=) Hooked", lpCaption, uType); // Se llama la función original

HookFunction("user32.dll", Function, Hooked_MessageBox, BackUp); // Se aplica el Hook nuevamente
return x; // Se retorna el resultado de la función original
}

DWORD HookFunction(LPCSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction, unsigned char *lpBackup) // Función que realiza el Hook al API
{
DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandle(lpModule), lpFuncName); // Obtiene la dirección de la API
       // Array de opcodes en lenguaje de maquina (ASM) para desviar la función
BYTE jmp[6] = { 0xe9, //jmp
0x00, 0x00, 0x00, 0x00, //address
0xc3
}; //retn

ReadProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 6, 0); // Se guardan los primeros 6 bytes de la función

DWORD dwCalc = ((DWORD)lpFunction - dwAddr - 5); // ( to - from) - 5 // Se calcula la posición donde se escribira el salto

memcpy(&jmp[1], &dwCalc, 4); // Se copia en memoria el salto

WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, jmp, 6, 0); // Se escribe en memoria los 6 bytes del salto

return dwAddr; // Se retorna la dirección del API
}

BOOL UnHookFunction(LPCSTR lpModule, LPCSTR lpFuncName, unsigned char *lpBackup) // Función que retira el Hook de la API
{
DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandle(lpModule), lpFuncName); // Se obtiene la dirección de la API

if (WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 6, 0)) // Si se logra escribir los bytes guardados en la función HookFunction
{
return TRUE; // Se retorna TRUE
}
return FALSE; // Sino entonces se retorna FALSE
}


Inyecta código en un proceso externo (Ejemplo hacer que un proceso externo ejecute un MessageBox)
Código (c++) [Seleccionar]

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

//Creamos un puntero a la api que queremos inyectar
typedef int (WINAPI *datMessageBoxA) (HWND, LPCTSTR, LPCTSTR, UINT);

//La estructura que inyectaremos
struct datos
{
datMessageBoxA apiMessageBoxA;
char titulo  [20];
char mensaje [20];
};

//Declaración de funciones
DWORD GetAdres(char *module, char *function);

//La función que inyectaremos
DWORD inyectada (datos *data)
{
data -> apiMessageBoxA (0, data->mensaje, data->titulo, 0);
return 0;
}

//La función inyectora
void inyectora()
{
int      pid;          // Este es el pid del proceso en el que nos queremos inyectar
HANDLE  proc;        // El handle del proceso en el que inyectaremos
datos    dat;          // El tipo de dato de la estructura
DWORD    TamFun;      // El tamaño de la función a inyectar
void*    esp;          // Lugar de memoria donde copiaremos nuestra función

HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //Obtenemos el pid
PROCESSENTRY32 procinfo = { sizeof(PROCESSENTRY32) };
while(Process32Next(handle, &procinfo))
{
  if(!strcmp(procinfo.szExeFile, "APIHOOK.exe"))
  {
      CloseHandle(handle);
    pid = procinfo.th32ProcessID;
  }
}
CloseHandle(handle);

//Abrimos el proceso en el que nos inyectaremos
proc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);

//Metemos la dirección de la api en la estructura llamando a la función GetAdres
dat.apiMessageBoxA = (datMessageBoxA) GetAdres ("USER32.DLL", "MessageBoxA");

//Inicializamos las variables que contendrán el mensaje
sprintf(dat.mensaje,"Mensaje");
sprintf(dat.titulo,"Texto");

//Reservamos espacio para nuestra estructura en el proceso a inyectar y la escribimos
datos *dat_ = (datos*) VirtualAllocEx(proc, 0, sizeof(datos), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(proc, dat_, &dat, sizeof(datos), NULL);

//Calculamos el tamaño de la función a inyectar
TamFun = (long unsigned int) inyectora - (long unsigned int)inyectada;

//Reservamos espacio para la función, escribimos en él y creamos un hilo
esp = VirtualAllocEx(proc, 0, TamFun, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(proc, esp, (void*)inyectada, TamFun, NULL);
CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE) esp, dat_, 0, NULL);
}

//La función main
int main()
{
inyectora();
system("pause>nul");
return EXIT_SUCCESS;
}

//Función que nos devuelve un DWORD con la dirección de una api
DWORD GetAdres(char *module, char *function)
{
HMODULE dh = LoadLibrary(module);
DWORD pf = (DWORD)GetProcAddress(dh,function);
FreeLibrary(dh);
return pf;
}
La Fé Mueve Montañas...
                                    ...De Dinero

La programación es más que un trabajo es más que un hobby es una pasión...

Karman

no podes hookear funciones de un proceso externo justamente porque es externo (otro espacio de memoria) para hookear algo tenes que estar en el mismo espacio de memoria... a lo sumo lo que podes hacer es (sin inyectar una dll) copiar el código a ejecutarse en el espacio de memoria del programa víctima y crear el hook en base a eso, pero sigue siendo más simple y efectivo la inyección, de todas formas, de lo otro creo que hay varios códigos en esta misma web, sino google.

S2

Keyen Night

Lo que quiero es la primera opción inyectar el código de las funciones para hacer hook pero me tiene confundido lo de las estructuras, entiendo el principio, debo inicializar todas las variables, funciones y otras cosas y copiar en el espacio de memoria del proceso externo para que el ejecute y se hookee el mismo, lo que necesito es el primer paso para inyectar las funciones que puse en el primer post al menos un ejemplo de como se inyecta HookFuncion.
La Fé Mueve Montañas...
                                    ...De Dinero

La programación es más que un trabajo es más que un hobby es una pasión...

Karman

te repito, es poco productivo y poco compatible (lo más probable es que solo funcione en el SO que lo crees), de todas formas, si quieres seguir indagando en el tema fijate este link:

http://www.infomalware.net/t62-inyeccion-de-codigo-sin-dll

es de un user de este foro y lo más probable (como ya lo mensioné) es que esté publicado tb en este foro... ( hoo buscador, si te usaran! )

S2

Keyen Night

Con respecto a la segunda forma que dijistes te refieres a inyección de DLL o a otra forma de hacer el hook inyectando código?
La Fé Mueve Montañas...
                                    ...De Dinero

La programación es más que un trabajo es más que un hobby es una pasión...

Karman

Cita de: Keyen Night en 16 Abril 2011, 19:38 PMCon respecto a la segunda forma que dijistes te refieres a inyección de DLL o a otra forma de hacer el hook inyectando código?

creo que la inyección de una dll suele ser la mejor opción, te permite hacer modificaciones de ser necesario en forma simple entre otras cosas (además de que es más fácil de implementar), la inyección de código es más para "parcheo" (cracking).

S2