[SRC][C++/ASM] ClsHookAPI

Iniciado por [Zero], 16 Enero 2010, 14:49 PM

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

[Zero]

ClsHookAPI

¿Para qué sirve?
     La clase ClsHookAPI nos permite crear aplicaciones en las que necesitemos hacer uso de un API Hooking de una forma muy sencilla, de forma que nos permita centrarnos en la programación que reciba el hook.

¿Cómo funciona?
     La clase lo que hace es inyectar el propio Rootkit en el proceso que tratamos de Hookear mediante ésta técnica. Una vez que tenemos todo el ejecutable en el mismo proceso, el Rootkit instala los Hooks redirigiendo las API's hacia las funciones del Rootkit inyectado en ese mismo proceso.

¿Qué consigues con eso?
     Al estar el Rootkit perfectamente inyectado en el proceso que queremos hookear, al redirigir las API's hacia las funciones que reciben el hook, las variables utiliadas en esa función, así como las llamadas a otras fuciones, API's, etc funcionarán perfectamente, lo que nos evita tener que preocuparnos de cargar las API's dinámicamente, deltas, variables imposibles, etc.

¿Cuanto facilita la clase el proceso?
     Al MÁXIMO!. La verdad no se me ocurrió ningúna forma más sencilla.

¿Cómo funciona?
     Lo primero es llamar al constructor de la clase y setear el proceso que queremos hookear:

Código (cpp) [Seleccionar]

ClsHookAPI Hook;
Hook.SetHookedProcessName("ejecutable.exe");


     La función SetHookedProcessName() devuelve TRUE si se puedo abrir el proceso, y FALSE si ocurrió algún error, como que el proceso no esté en ejecución.

     Luego debemos definir la función que recibirá el hook. La función debe de usar la convención de llamada __stdcall para que no corrompa la pila. En la función podemos usar cualquier API o variable, incluso podemos llamar a la misma API que estamos Hookeando sin temor a que caiga en el hook. En éste caso hookearé MessageBoxA:

Código (cpp) [Seleccionar]

int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
//Llamamos a MessageBoxA normalmente, cambiando el mensaje que muestra
return MessageBoxA(0,"MessageBoxA Hookeada!!!",lpCaption,0);
}


     Ahora ya podemos instalar el Hook, para eso utilizamos el operador '<<' para setear el nombre de la DLL y la API, y el operador '>>' para indicar a donde queremos redirigir la API:

Código (cpp) [Seleccionar]

Hook<<"USER32.MessageBoxA";
Hook>>(unsigned long)HookedMessageBoxA;


     Ya tendríamos la API MessageBoxA Hookeada  :P.

     Nota: #Es necesario setear la dirección a la que se redirigirá la API justo despues de indicar la API que queremos Hookear.

¿Puedo Hookear varias API's a la vez?
     Por supuesto, aquí un ejemplo de 3 Hooks simultáneos:

Código (cpp) [Seleccionar]

#pragma comment (linker,"/ENTRY:main")

#include "ClsHookApi.h"

int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
void __stdcall HookedExitProcess(UINT uExitCode);
BOOL __stdcall HookedBeep(DWORD dwFreq,DWORD dwDuration);

int main()
{
ClsHookAPI miHook;

if(miHook.SetHookedProcessName("mensaje.exe"))
{
miHook<<"USER32.MessageBoxA";
miHook>>(unsigned long)HookedMessageBoxA;

miHook<<"KERNEL32.ExitProcess";
miHook>>(unsigned long)HookedExitProcess;

miHook<<"KERNEL32.DLL.Beep";
miHook>>(unsigned long)HookedBeep;
}

return 0;
}

int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
return MessageBoxA(0,"MessageBoxA Hookeada!!!",lpCaption,0);
}

void __stdcall HookedExitProcess(UINT uExitCode)
{
MessageBoxA(0,"Has llamado a ExitProcess!","xD",0);
return ExitProcess(uExitCode);
}

BOOL __stdcall HookedBeep(DWORD dwFreq,DWORD dwDuration)
{
Beep(1000,100);
Beep(1000,100);
return Beep(1000,100);
}


¿Vale, me la das ya?
      Claro  :laugh:. Pongo aquí el código aunque es un poco largo. Más abajo ponto el proyecto de ejemplo en descarga.

ClsHookAPI.h
Código (cpp) [Seleccionar]

//----------------------------------------------------------------------------------------------------
//Autor: Hacker_Zero
//Fecha: 11 enero 2010
//Nombre: ClsHookApi
//Descripción:
// Clase en C++ que permite hookear API's de forma simultánea, facilitando enormemente
//la programación de las funciones que reciven el hook así como la instalación de los
//propios hooks.
//----------------------------------------------------------------------------------------------------
//Código liberado bajo la GNU Public License (GPL) <http://www.gnu.org/licenses/gpl-3.0.html>
//Eres libre de utilizar, modificar y distribuír ésta clase siempre que mantengas ésta cabecera
//----------------------------------------------------------------------------------------------------

#include <windows.h>
#include <Tlhelp32.h>
#include <vector>
#include <string.h>

using namespace std;

struct HookStruct
{
LPSTR lpAPI;
LPSTR lpHookFunction;
CHAR lpBuffer[11];
HookStruct* previousHookStruct;
HookStruct* nextHookStruct;
};

#ifndef HOOKAPI_H
#define HOOKAPI_H

void HookApi(HookStruct* miHookStruct);
void mCopyMemory(LPSTR bEscritura,LPSTR bLectura,DWORD lenBuffer);
void ControlFunction();
void Caller();
void UninstallHooks(HookStruct* miHookStruct);
void RestoreHooks(HookStruct* miHookStruct);

class ClsHookAPI
{
public:
ClsHookAPI();
ClsHookAPI& operator<<(LPSTR HookName);
ClsHookAPI& operator>>(unsigned long lpFunctionHook);
bool SetHookedProcessName(LPSTR ProcessName);

private:
void AddFunction(HookStruct miHookStruct);
void InstallHook(HookStruct* miHookStruct);
vector<HookStruct> Hooks;
BOOL ExeInjected;
HANDLE hProcess;
LPSTR InjectedExeBaseAddress;
HookStruct* lastInjectedHookStruct;
};
#endif


ClsHookAPI.cpp
Código (cpp) [Seleccionar]

#include "ClsHookApi.h"

//Constructor de la clase
ClsHookAPI::ClsHookAPI()
{
InjectedExeBaseAddress=NULL;
lastInjectedHookStruct=NULL;
ExeInjected=false;
}

//Sobrecarga del operador '<<'
ClsHookAPI& ClsHookAPI::operator<<(LPSTR HookName)
{
//Obtenemos la DLL y la API de HookName
string strHookName;
strHookName.append(HookName);
string strDllName=strHookName.substr(0,strHookName.find_last_of("."));
string strApiName=strHookName.substr(strHookName.find_last_of(".")+1);

//Inicializamos la estructura y seteamos el puntero a la API
HookStruct miHookStruct;
miHookStruct.lpAPI=(LPSTR)GetProcAddress(LoadLibraryA(strDllName.c_str()),strApiName.c_str());

//Añadimos la estructura al Array
AddFunction(miHookStruct);

return *this;
}

//Sobrecarga del operador '>>'
ClsHookAPI& ClsHookAPI::operator>>(unsigned long lpFunctionHook)
{
Hooks.back().lpHookFunction=(LPSTR)lpFunctionHook;
InstallHook(&Hooks.back());
return *this;
}

void ClsHookAPI::AddFunction(HookStruct miHookStruct)
{
//Si es el primer elemento que añadimos
if(!Hooks.size())
{
miHookStruct.previousHookStruct=NULL;
}
else
{
miHookStruct.previousHookStruct=this->lastInjectedHookStruct;
}

miHookStruct.nextHookStruct=NULL;
//Insertamos la estructura en el array
Hooks.push_back(miHookStruct);
return;
}

//Seteamos el nombre del proceso en el que inyectaremos
bool ClsHookAPI::SetHookedProcessName(LPSTR ProcessName)
{
HANDLE bakhProcess=hProcess;
hProcess=NULL;

HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 pInfo;
pInfo.dwSize=sizeof(PROCESSENTRY32);

//Obtenemos el PID del proceso
Process32First(hSnapshot,&pInfo);
for(;Process32Next(hSnapshot,&pInfo);)
{
if(!lstrcmpA(pInfo.szExeFile,ProcessName))
{
if(OpenProcess(PROCESS_ALL_ACCESS,FALSE,pInfo.th32ProcessID))
{
ExeInjected=false;
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pInfo.th32ProcessID);
}
}
}

if(!hProcess)
{
hProcess=bakhProcess;
return false;
}

return true;
}

void ClsHookAPI::InstallHook(HookStruct* miHookStruct)
{
//Nos inyectamos en el proceso si no lo hemos hecho ya
if(ExeInjected==false)
{
PIMAGE_DOS_HEADER IDH;
PIMAGE_NT_HEADERS INTH;
PIMAGE_SECTION_HEADER ISH;

LPSTR lpFileName=(LPSTR)GlobalAlloc(GPTR,MAX_PATH);
GetModuleFileName(NULL,lpFileName,MAX_PATH);

HANDLE hFile=CreateFileA(lpFileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
DWORD szFile=GetFileSize(hFile,0);
DWORD dwBytes;
LPSTR lpFileMaped=(LPSTR)GlobalAlloc(GPTR,szFile);
ReadFile(hFile,lpFileMaped,szFile,&dwBytes,0);
CloseHandle(hFile);

//Obtenemos la cabecera DOS y PE en las estructuras
IDH=(PIMAGE_DOS_HEADER)&lpFileMaped[0];
INTH=(PIMAGE_NT_HEADERS)&lpFileMaped[IDH->e_lfanew];

//Creamos el buffer del tamaño del SizeOfImage en el que cargaremos el ejecutable
LPSTR ExeBuffer=(LPSTR)VirtualAllocEx(this->hProcess,0,INTH->OptionalHeader.SizeOfImage,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);

//Copiamos la cabecera DOS y PE al buffer
WriteProcessMemory(this->hProcess,&ExeBuffer[0],&lpFileMaped[0],INTH->OptionalHeader.SizeOfHeaders,0);

//Copiamos las secciones en su VirtualOffset en el buffer
for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++)
{
ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i];
WriteProcessMemory(this->hProcess,&ExeBuffer[ISH->VirtualAddress],&lpFileMaped[ISH->PointerToRawData],ISH->SizeOfRawData,0);
}

//Calculamos el delta entre la dirección del buffer y el ImageBase
DWORD Delta=(((DWORD)ExeBuffer)-INTH->OptionalHeader.ImageBase);

//------------------------------------------------------------
/* -Reubicamos la dirección base del ejecutable :D- */
//------------------------------------------------------------

//Obteemos el Image Base Relocation
//Copiamos el Image Base Relocation de los datos en el proceso a un buffer en el nuestro para
//poder trabajar con él más comodamente
PIMAGE_BASE_RELOCATION IBR=(PIMAGE_BASE_RELOCATION)GlobalAlloc(GPTR,sizeof(IMAGE_BASE_RELOCATION));
PIMAGE_BASE_RELOCATION PIBR=(PIMAGE_BASE_RELOCATION)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
ReadProcessMemory(hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0);

//Vamos recorriendo todas las etradas del bloque
for(DWORD n=0;IBR->VirtualAddress>0;n++)
{
//Obtenemos el Bloque de reubicación
LPSTR RelocationBlock=(LPSTR)(ExeBuffer+IBR->VirtualAddress);

//Obtenemos la primera entrada del bloque
LPWORD RelocationEntry=(LPWORD)((LPSTR)PIBR+sizeof(IMAGE_BASE_RELOCATION));

//Recorremos todas las entradas del bloque
for(DWORD i=0;i<((IBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2);i++,RelocationEntry++)
{
WORD valor;
ReadProcessMemory(this->hProcess,RelocationEntry,&valor,2,0);
//Obtenemos los 4 bits que definen el tipo de reubicación
DWORD type=valor>>12;

//Obtenemos los 12 bits que definen la dirección de la reubicación
DWORD offset=valor&0xFFF;

//Si el tipo de reubicación es relativo a la dirección base, añadimso el delta
if(type==IMAGE_REL_BASED_HIGHLOW)
{
//Añadimos a la dirección que depende del imagebase original
//el delta entre el imagebase y nuestra dirección base
LPDWORD newAddr=(LPDWORD)(RelocationBlock+offset);
DWORD NewValue;
ReadProcessMemory(this->hProcess,newAddr,&NewValue,4,0);
NewValue+=Delta;
WriteProcessMemory(this->hProcess,newAddr,&NewValue,4,0);
}
}

//Vamos al siguiente bloque
PIBR=(PIMAGE_BASE_RELOCATION)(((DWORD)PIBR)+IBR->SizeOfBlock);
ReadProcessMemory(this->hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0);
}
GlobalFree(IBR);


//---------------------------------------------------------------------
/* -Cargamos los valores de la IAT para poder llamar a las API's- */
//---------------------------------------------------------------------

PIMAGE_THUNK_DATA ITD;
PIMAGE_THUNK_DATA PITD;
PIMAGE_IMPORT_BY_NAME IIBN;

//Comprobamos si hay Import Data Descriptor
if(INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size>0)
{

//Obtenemos el Import Data Descriptor
//Copiamos el Import Data Descriptor de los datos en el proceso a un buffer en el nuestro para
//poder trabajar con él más comodamente
PIMAGE_IMPORT_DESCRIPTOR IID=(PIMAGE_IMPORT_DESCRIPTOR)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_DESCRIPTOR));
PIMAGE_IMPORT_DESCRIPTOR PIID=(PIMAGE_IMPORT_DESCRIPTOR)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
ReadProcessMemory(this->hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0);

//Vamos recorriendo todas las Dll's importadas por el ejecutable
for(;IID->Name;)
{
//Obtenemos la longitud del nombre de la dll
DWORD szName=0;
CHAR miByte=1;
for(int i=0;miByte;i++)
{
szName=i;
ReadProcessMemory(this->hProcess,ExeBuffer+IID->Name+i,&miByte,1,0);
}

//Obtenemos el nombre de la dll
LPSTR lpName=(LPSTR)GlobalAlloc(GPTR,szName+1);
ReadProcessMemory(this->hProcess,ExeBuffer+IID->Name,lpName,szName+1,0);

//Cargamos la dll
HMODULE hLib=LoadLibraryA(lpName);

//Obtenemos la dirección al primer miembro del array Image Thunk Data's
PITD=(PIMAGE_THUNK_DATA)((DWORD)ExeBuffer+IID->FirstThunk);
ITD=(PIMAGE_THUNK_DATA)GlobalAlloc(GPTR,sizeof(IMAGE_THUNK_DATA));
ReadProcessMemory(this->hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0);

//Vamos recorriendo las funciones importadas
for(DWORD x=0;ITD->u1.Ordinal;x++)
{
miByte=1;
//Obtenemos la longitud del nombre de la API
for(int i=0;miByte;i++)
{
szName=i;
LPSTR puntero=ExeBuffer+ITD->u1.Function+2;
puntero+=i;
ReadProcessMemory(this->hProcess,puntero,&miByte,1,0);
}

//Cargamos el Image Import By Name para obtener el nombre
IIBN=(PIMAGE_IMPORT_BY_NAME)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_BY_NAME)+szName);
ReadProcessMemory(this->hProcess,ExeBuffer+ITD->u1.Function,IIBN,sizeof(IMAGE_IMPORT_BY_NAME)+szName,0);

//Obtenemos la dirección de la función y la guardamos en la IAT
DWORD lpAPI=(DWORD)GetProcAddress(hLib,(LPCSTR)&IIBN->Name);
WriteProcessMemory(this->hProcess,ExeBuffer+IID->FirstThunk+x*sizeof(IMAGE_THUNK_DATA),&lpAPI,4,0);

PITD++;
ReadProcessMemory(this->hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0);
}
PIID++;
ReadProcessMemory(this->hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0);
GlobalFree(lpName);
GlobalFree(ITD);
}
GlobalFree(IID);
}
this->InjectedExeBaseAddress=ExeBuffer;
this->ExeInjected=true;
}

//Cambiamos el ImageBase a la dirección de la función que recibe el hook
miHookStruct->lpHookFunction=(LPSTR)((unsigned long)this->InjectedExeBaseAddress+(unsigned long)miHookStruct->lpHookFunction-(unsigned long)GetModuleHandle(NULL));

//Reservamos espacio para la estructura en el proceso en el que inyectamos
HookStruct* lpHookStruct=(HookStruct*)VirtualAllocEx(this->hProcess,0,sizeof(HookStruct),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
//Esribimos la estructura en el espacio reservado
WriteProcessMemory(this->hProcess,lpHookStruct,miHookStruct,sizeof(HookStruct),0);

//Seteamos el valor de nextHookStruct de la HookStruct anterior a la que acabamos de inyectar
HookStruct* lastHookStruct=(HookStruct*)GlobalAlloc(GPTR,sizeof(HookStruct));
ReadProcessMemory(this->hProcess,lastInjectedHookStruct,lastHookStruct,sizeof(HookStruct),0);
lastHookStruct->nextHookStruct=lpHookStruct;
WriteProcessMemory(this->hProcess,lastInjectedHookStruct,lastHookStruct,sizeof(HookStruct),0);

//Seteamo el valor de lastInjectedHookStruct
this->lastInjectedHookStruct=lpHookStruct;

//Obteemos la dirección de la función HookApi
DWORD lpHookApi=(DWORD)this->InjectedExeBaseAddress+(DWORD)HookApi-(DWORD)GetModuleHandle(NULL);

//Llamamos al EntryPoint
CreateRemoteThread(this->hProcess,0,0,(LPTHREAD_START_ROUTINE)lpHookApi,(HookStruct*)lpHookStruct,0,0);

return;
}

//Pequeño código en ASM que por el cual sustituimos el comienzo de la API
void __declspec(naked) Caller()
{
__asm
{
push 0x00400000 //~Ésta dirección se sustituye en tiempo de ejecución por el puntero a HookStruct
push 0x00400000 //~Ésta dirección se sustituye en tiempo de ejecución por la dirección de ControlFunction
ret
}
}

void UninstallHooks(HookStruct* miHookStruct)
{
__asm pushad;
//Nos desplazamos al primer Hook
for(;miHookStruct->previousHookStruct!=NULL;)
{
miHookStruct=miHookStruct->previousHookStruct;
}

//Desinstalamos todos los Hooks
for(;miHookStruct!=NULL;)
{
mCopyMemory(miHookStruct->lpAPI,miHookStruct->lpBuffer,11);
FlushInstructionCache(GetCurrentProcess(),0,0);
miHookStruct=miHookStruct->nextHookStruct;
}
__asm popad;
}

void RestoreHooks(HookStruct* miHookStruct)
{
__asm pushad;
//Nos desplazamos al primer Hook
for(;miHookStruct->previousHookStruct!=NULL;)
{
miHookStruct=miHookStruct->previousHookStruct;
}

//Volvemos a instalar todos los Hooks
for(;miHookStruct!=NULL;)
{
//Copiamos los X primeros bytes de la api a nuestro buffer
mCopyMemory(miHookStruct->lpBuffer,miHookStruct->lpAPI,11);

//Cambiamos los la primera dirección que pushea 'Caller' por la un puntero a miHookStruct
mCopyMemory((LPSTR)Caller+1,(LPSTR)&miHookStruct,4);

//Cambiamos los la segunda dirección que pushea 'Caller' por la dirección de ControlFunction
LPSTR dirControlFunction=(LPSTR)ControlFunction;
mCopyMemory((LPSTR)Caller+6,(LPSTR)&dirControlFunction,4);

//Cambiamos los 10 primeros bytes de la API por la función Caller
mCopyMemory(miHookStruct->lpAPI,(LPSTR)Caller,11);
FlushInstructionCache(GetCurrentProcess(),0,0);
miHookStruct=miHookStruct->nextHookStruct;
}
__asm popad;
}

//Función a la que salta la API hookeda en que se inyectó 'Caller'
void __declspec(naked) ControlFunction()
{
__asm
{
jmp go

miHookStruct:
nop
nop
nop
nop

retornar:
_emit 0x68 //push
dirRetorno:
nop
nop
nop
nop
_emit 0xC3 //ret
     
RetornoApi:
nop
nop
nop
nop
Temp:
nop
nop
nop
nop

go:
//Sólo modificamos eax para no modificar más registros de los que modifica la API
//Copiamos a Temp el primer parámetro que hay sobre la pila (lpHookStruct)
mov eax,Temp
push dword ptr ds:[esp]
pop dword ptr ds:[eax]

//Copiamos lpHookStruct a miHookStruct
push 4
push Temp
push miHookStruct
call mCopyMemory
add esp,12 //Restauramos la pila

//Quitamos lpHookStruct de la pila
add esp,4

//Copiamos a Temp el primer parámetro que hay sobre la pila (dirección de retorno)
mov eax,Temp
push dword ptr ds:[esp]
pop dword ptr ds:[eax]

//Copiamos la dirección de retorno a dirRetorno
push 4
push Temp
push dirRetorno
call mCopyMemory
add esp,12 //Restauramos la pila

//Quitamos la direcc de retorno de la pila
add esp,4

//LLamamos a UninstallHooks para desinstalar todos los hooks antes de llamar a la función que recive el Hook
mov eax,miHookStruct
push dword ptr ds:[eax]
call UninstallHooks
add esp,4

//Llamamos a la función que recive el hook y copiamos el retorno a RetornoApi
mov eax,miHookStruct
mov eax,dword ptr ds:[eax]
call dword ptr ds:[eax+0x04]
push eax
mov eax,RetornoApi
pop dword ptr ds:[eax]

//Restauramos todos los Hooks
mov eax,miHookStruct
push dword ptr ds:[eax]
call RestoreHooks
add esp,4

//Movemos a eax el retorno de la API
mov eax,RetornoApi
push dword ptr ds:[eax]
pop eax

//Saltamos a la dirección de retorno
jmp retornar
}
}

void HookApi(HookStruct* miHookStruct)
{
__asm pushad;
//Damos permisos de escritura, lectura y ejecución a nuestro buffer
DWORD OldProtection;
VirtualProtect((LPVOID)miHookStruct->lpBuffer,11,PAGE_EXECUTE_READWRITE,&OldProtection);

// Le damos permisos de ejecución a los X primeros bytes de la api
VirtualProtect((LPVOID)miHookStruct->lpAPI,11,PAGE_EXECUTE_READWRITE,&OldProtection);

//Copiamos los X primeros bytes de la api a nuestro buffer
mCopyMemory(miHookStruct->lpBuffer,miHookStruct->lpAPI,11);

//Cambiamos los la primera dirección que pushea 'Caller' por la un puntero a miHookStruct
mCopyMemory((LPSTR)Caller+1,(LPSTR)&miHookStruct,4);

//Cambiamos los la segunda dirección que pushea 'Caller' por la dirección de ControlFunction
LPSTR dirControlFunction=(LPSTR)ControlFunction;
mCopyMemory((LPSTR)Caller+6,(LPSTR)&dirControlFunction,4);

//Cambiamos los 10 primeros bytes de la API por la función Caller
mCopyMemory(miHookStruct->lpAPI,(LPSTR)Caller,11);

FlushInstructionCache(GetCurrentProcess(),0,0);
__asm popad;
}

//Función que simula RtlCopyMemory
void __declspec(naked) mCopyMemory(LPSTR bEscritura,LPSTR bLectura,DWORD lenBuffer)
{
__asm
{
pushad
mov esi,[esp+0x28] //bLectura
mov ecx,[esp+0x2C] //lenBuffer
mov edi,[esp+0x24] //bEscritura
dec ecx

bCopyMemory:
dec ecx
movsb
cmp ecx,0
jge bCopyMemory
popad
ret
}
}


Descargar Ejemplo

Nota: El ejecutable hookeado en el proceso de ejemplo se puede encontrar en la carpeta release, junto con el source del mismo.

Saludos  :P

"El Hombre, en su orgullo, creó a Dios a su imagen y semejanza.”
Nietzsche

Jaixon Jax

 :o Jeje entendi hasta   __asm    :-\  por ahora  >:D Lo que nos hacia falta estandarizar los HOOKS  :laugh: Felicitaciones :


 De verdad que esta termendo el Code Men  ;)

‭‭‭‭jackl007

Excelente, muy bueno eh :P
ya me imaginabas que ibas a postear algo asi

YST



Yo le enseñe a Kayser a usar objetos en ASM

MazarD

Excelente trabajo y muy buen estilo de programación.
-Learn as if you were to live forever, live as if you were to die tomorrow-

http://www.mazard.info
http://twitter.com/MazarD
irc://irc.freenode.org/elhacker.net

raulrl

Un codigo fantástico Hacker_Zero, no se C pero se reconocer un buen code cuando lo veo. Se que lleva mucho trabajo eso del Hook, ya que yo lo intenté hace unas semanas con VB y al final sali escaldado!!!  :rolleyes:

Un trabajo impresionante, pero, una pregunta, ¿teniendo algun conocimiento de C se podria compilar este proyecto a una DLL para poder exportar la función del Hook a otros lenguajes??? :P

Saludos  ;-)

Nork

Buenísimo! Algo que hace una faena no trivial de forma fácil y entendible es digno de admiración. A partir de hoy recordaré tu nick xDD


S4ludos!
C' Est La Vie

Karcrack

Muy bueno, a ver si saco tiempo para revisarlo a fondo...

Tiene algun error? :rolleyes: :rolleyes: :xD

[Zero]

Cita de: Karcrack en 16 Enero 2010, 22:13 PM
Tiene algun error? :rolleyes: :rolleyes: :xD

No, iva a poner algún error, pero como puse uno sin querer y me llevó casi una hora encontrarlo siendo yo el autor del código, sería bastante cabrón si lo dejara con errores  :xD.

Saludos

"El Hombre, en su orgullo, creó a Dios a su imagen y semejanza.”
Nietzsche

Karcrack

Cita de: Hacker_Zero en 16 Enero 2010, 22:56 PM
No, iva a poner algún error, pero como puse uno sin querer y me llevó casi una hora encontrarlo siendo yo el autor del código, sería bastante cabrón si lo dejara con errores  :xD.

Saludos
Entonces elimino el tema! >:D >:D :xD :xD :xD :xD (Broma :¬¬)
Pues siempre viene bien un pequeñito fallo, para asegurarse que se tienen conocimientos bases... Ya que se tiene mucho al C&P sin leer, pero bueno, es C... si fuera VB ya lo detectaria hasta el Panda :laugh: