Test Foro de elhacker.net SMF 2.1

Seguridad Informática => Análisis y Diseño de Malware => Mensaje iniciado por: [Zero] en 16 Enero 2010, 14:49 PM

Título: [SRC][C++/ASM] ClsHookAPI
Publicado por: [Zero] en 16 Enero 2010, 14:49 PM
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 (http://foro.elhacker.net/analisis_y_diseno_de_malware/inyeccion_de_archivos_en_un_proceso_1_proceso_2_ejecutables-t280471.0.html). 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 (http://www.megaupload.com/?d=AIEEY7MB)

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

Saludos  :P
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: Jaixon Jax en 16 Enero 2010, 15:31 PM
 :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  ;)
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: ‭‭‭‭jackl007 en 16 Enero 2010, 15:59 PM
Excelente, muy bueno eh :P
ya me imaginabas que ibas a postear algo asi
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: YST en 16 Enero 2010, 19:05 PM
Muy bueno :P
Salu2
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: MazarD en 16 Enero 2010, 20:52 PM
Excelente trabajo y muy buen estilo de programación.
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: raulrl en 16 Enero 2010, 21:34 PM
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  ;-)
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: Nork en 16 Enero 2010, 21:43 PM
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!
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: Karcrack en 16 Enero 2010, 22:13 PM
Muy bueno, a ver si saco tiempo para revisarlo a fondo...

Tiene algun error? :rolleyes: :rolleyes: :xD
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: [Zero] en 16 Enero 2010, 22:56 PM
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
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: Karcrack en 17 Enero 2010, 01:35 AM
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:
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: [Zero] en 17 Enero 2010, 01:40 AM
De todas formas, algún fallo indirecto seguro que tiene, no testeé demasiado el código.

Saludos  :xD
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: isseu en 17 Enero 2010, 01:41 AM
waw muy bueno
con esta te pasaste hacker_zero
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: -Ramc- en 17 Enero 2010, 01:45 AM
Felicitaciones, lo que más me gusta es que el código te quedó impecable, está muy limpio y ordenado, porque hay códigos que además de saber C o C++ y assembly, hay que ponerse a descifrarlos, pero, este está muy entendible, de verdad felicitaciones y gracias por deleitarnos con el código.

Slaudos.
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: [L]ord [R]NA en 17 Enero 2010, 03:05 AM
Buen Trabajo... (No le digas a mas nadie que te felicite por tu trabajo)
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: Debci en 17 Enero 2010, 10:52 AM
Bestial, es buenísimo, lo mejor que he visto y explicado de esta manera.

Saludos
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: E.P.I. en 17 Enero 2010, 11:46 AM
Menos la parte de ASM que no entiendo nada, lo otro que te tengo que decir... ya lo sabes! Muy buen trabajo!
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: NewLog en 21 Enero 2010, 21:01 PM
Como ves, tengo muy pocos mensajes y estoy registrado desde hace años. Contando que entro a chafardear cada dos dias, significa que mis posts son escasos, y sólo gasto las teclas para cosas que valgan la pena...

Lo que más me ha gustado de todo esto, es que lo hayas comentado linea por linea. Como dios manda.

Suerte y ánimos.
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: Amerikano|Cls en 23 Enero 2010, 00:23 AM
Excelente code Gracias y Felicitaciones  ;)
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: [Zero] en 21 Abril 2010, 18:21 PM
Arreglaré ésta clase para el Abril Negro, así que me tomo la libertad de revivir éste post. Corrigiré varios bugs que encontré al darle uso a la clase, y añadiré nuevas funcionalidades, entre ellas pensé en añadir soporte para varios tipos de hooking, no sólo por trampolín, pudiendo así el programador elegir entre Hooking por Trampolín, VEH Hooking o IAT Hooking. Si alguien tiene una idea de qué más cosas podría añadir será bienvenida. Tambien necesitaría a algunas personas que se manejen bien en C para buscar bugs, de lo contrario seguro se me escapan algunos.

Saludos
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: [L]ord [R]NA en 21 Abril 2010, 21:35 PM
:xD entonces yo tambien trabajare en algo para este mes que parece que esta quedando muy negro
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: DarkItachi en 10 Mayo 2010, 14:11 PM
Podrías buscar alguna alternativa a remotethread , no sé casi nada de diseñar malware ni sé si hay alternativas fáciles/estables/manejables a esta pero por lo que he leído remotethread es muy detectada, si me equivoco avísadme (ya dije que sé muy poco), pero sólo comento para intentar mejorarlo :).

Salu2
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: [Zero] en 10 Mayo 2010, 17:17 PM
Jaja, es que la única forma de crear un hilo en un proceso remoto es esa. La alternativa sería apañarse con los threads que hay. Si saco tiempo termina la v2, que tiene veh hooking y no es necesario inyectar nada  :P.

Saludos  ;)
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: Arkangel_0x7C5 en 11 Mayo 2010, 18:59 PM
Cita de: DarkItachi en 10 Mayo 2010, 14:11 PM
Podrías buscar alguna alternativa a remotethread , no sé casi nada de diseñar malware ni sé si hay alternativas fáciles/estables/manejables a esta pero por lo que he leído remotethread es muy detectada, si me equivoco avísadme (ya dije que sé muy poco), pero sólo comento para intentar mejorarlo :).

Salu2
Tecnicamente cuando creas un proceso o el propio proceso crea un hilo se usa esa api al final. lo que ocurre es que los AV detectan esa api en la IAT

Saludos
Título: Re: [SRC][C++/ASM] ClsHookAPI
Publicado por: inexinferismonster en 5 Septiembre 2014, 16:32 PM
hola zero  I can not download clshoolapi project no download another site to upload please Zero  Thank you in advance