elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: AIO elhacker.NET 2021 Compilación herramientas análisis y desinfección malware


+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Análisis y Diseño de Malware (Moderador: fary)
| | |-+  [SRC][C++/ASM] ClsHookAPI
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 3 Ir Abajo Respuesta Imprimir
Autor Tema: [SRC][C++/ASM] ClsHookAPI  (Leído 15,591 veces)
[Zero]
Wiki

Desconectado Desconectado

Mensajes: 1.082


CALL DWORD PTR DS:[0]


Ver Perfil WWW
[SRC][C++/ASM] ClsHookAPI
« 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. 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
  1. ClsHookAPI Hook;
  2. Hook.SetHookedProcessName("ejecutable.exe");
  3.  

     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
  1. int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
  2. {
  3. //Llamamos a MessageBoxA normalmente, cambiando el mensaje que muestra
  4. return MessageBoxA(0,"MessageBoxA Hookeada!!!",lpCaption,0);
  5. }
  6.  

     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
  1. Hook<<"USER32.MessageBoxA";
  2. Hook>>(unsigned long)HookedMessageBoxA;
  3.  

     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
  1. #pragma comment (linker,"/ENTRY:main")
  2.  
  3. #include "ClsHookApi.h"
  4.  
  5. int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
  6. void __stdcall HookedExitProcess(UINT uExitCode);
  7. BOOL __stdcall HookedBeep(DWORD dwFreq,DWORD dwDuration);
  8.  
  9. int main()
  10. {
  11. ClsHookAPI miHook;
  12.  
  13. if(miHook.SetHookedProcessName("mensaje.exe"))
  14. {
  15. miHook<<"USER32.MessageBoxA";
  16. miHook>>(unsigned long)HookedMessageBoxA;
  17.  
  18. miHook<<"KERNEL32.ExitProcess";
  19. miHook>>(unsigned long)HookedExitProcess;
  20.  
  21. miHook<<"KERNEL32.DLL.Beep";
  22. miHook>>(unsigned long)HookedBeep;
  23. }
  24.  
  25. return 0;
  26. }
  27.  
  28. int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
  29. {
  30. return MessageBoxA(0,"MessageBoxA Hookeada!!!",lpCaption,0);
  31. }
  32.  
  33. void __stdcall HookedExitProcess(UINT uExitCode)
  34. {
  35. MessageBoxA(0,"Has llamado a ExitProcess!","xD",0);
  36. return ExitProcess(uExitCode);
  37. }
  38.  
  39. BOOL __stdcall HookedBeep(DWORD dwFreq,DWORD dwDuration)
  40. {
  41. Beep(1000,100);
  42. Beep(1000,100);
  43. return Beep(1000,100);
  44. }
  45.  

¿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
  1. //----------------------------------------------------------------------------------------------------
  2. //Autor: Hacker_Zero
  3. //Fecha: 11 enero 2010
  4. //Nombre: ClsHookApi
  5. //Descripción:
  6. // Clase en C++ que permite hookear API's de forma simultánea, facilitando enormemente
  7. //la programación de las funciones que reciven el hook así como la instalación de los
  8. //propios hooks.
  9. //----------------------------------------------------------------------------------------------------
  10. //Código liberado bajo la GNU Public License (GPL) <http://www.gnu.org/licenses/gpl-3.0.html>
  11. //Eres libre de utilizar, modificar y distribuír ésta clase siempre que mantengas ésta cabecera
  12. //----------------------------------------------------------------------------------------------------
  13.  
  14. #include <windows.h>
  15. #include <Tlhelp32.h>
  16. #include <vector>
  17. #include <string.h>
  18.  
  19. using namespace std;
  20.  
  21. struct HookStruct
  22. {
  23. LPSTR lpAPI;
  24. LPSTR lpHookFunction;
  25. CHAR lpBuffer[11];
  26. HookStruct* previousHookStruct;
  27. HookStruct* nextHookStruct;
  28. };
  29.  
  30. #ifndef HOOKAPI_H
  31. #define HOOKAPI_H
  32.  
  33. void HookApi(HookStruct* miHookStruct);
  34. void mCopyMemory(LPSTR bEscritura,LPSTR bLectura,DWORD lenBuffer);
  35. void ControlFunction();
  36. void Caller();
  37. void UninstallHooks(HookStruct* miHookStruct);
  38. void RestoreHooks(HookStruct* miHookStruct);
  39.  
  40. class ClsHookAPI
  41. {
  42. public:
  43. ClsHookAPI();
  44. ClsHookAPI& operator<<(LPSTR HookName);
  45. ClsHookAPI& operator>>(unsigned long lpFunctionHook);
  46. bool SetHookedProcessName(LPSTR ProcessName);
  47.  
  48. private:
  49. void AddFunction(HookStruct miHookStruct);
  50. void InstallHook(HookStruct* miHookStruct);
  51. vector<HookStruct> Hooks;
  52. BOOL ExeInjected;
  53. HANDLE hProcess;
  54. LPSTR InjectedExeBaseAddress;
  55. HookStruct* lastInjectedHookStruct;
  56. };
  57. #endif
  58.  

ClsHookAPI.cpp
Código
  1. #include "ClsHookApi.h"
  2.  
  3. //Constructor de la clase
  4. ClsHookAPI::ClsHookAPI()
  5. {
  6. InjectedExeBaseAddress=NULL;
  7. lastInjectedHookStruct=NULL;
  8. ExeInjected=false;
  9. }
  10.  
  11. //Sobrecarga del operador '<<'
  12. ClsHookAPI& ClsHookAPI::operator<<(LPSTR HookName)
  13. {
  14. //Obtenemos la DLL y la API de HookName
  15. string strHookName;
  16. strHookName.append(HookName);
  17. string strDllName=strHookName.substr(0,strHookName.find_last_of("."));
  18. string strApiName=strHookName.substr(strHookName.find_last_of(".")+1);
  19.  
  20. //Inicializamos la estructura y seteamos el puntero a la API
  21. HookStruct miHookStruct;
  22. miHookStruct.lpAPI=(LPSTR)GetProcAddress(LoadLibraryA(strDllName.c_str()),strApiName.c_str());
  23.  
  24. //Añadimos la estructura al Array
  25. AddFunction(miHookStruct);
  26.  
  27. return *this;
  28. }
  29.  
  30. //Sobrecarga del operador '>>'
  31. ClsHookAPI& ClsHookAPI::operator>>(unsigned long lpFunctionHook)
  32. {
  33. Hooks.back().lpHookFunction=(LPSTR)lpFunctionHook;
  34. InstallHook(&Hooks.back());
  35. return *this;
  36. }
  37.  
  38. void ClsHookAPI::AddFunction(HookStruct miHookStruct)
  39. {
  40. //Si es el primer elemento que añadimos
  41. if(!Hooks.size())
  42. {
  43. miHookStruct.previousHookStruct=NULL;
  44. }
  45. else
  46. {
  47. miHookStruct.previousHookStruct=this->lastInjectedHookStruct;
  48. }
  49.  
  50. miHookStruct.nextHookStruct=NULL;
  51. //Insertamos la estructura en el array
  52. Hooks.push_back(miHookStruct);
  53. return;
  54. }
  55.  
  56. //Seteamos el nombre del proceso en el que inyectaremos
  57. bool ClsHookAPI::SetHookedProcessName(LPSTR ProcessName)
  58. {
  59. HANDLE bakhProcess=hProcess;
  60. hProcess=NULL;
  61.  
  62. HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  63. PROCESSENTRY32 pInfo;
  64. pInfo.dwSize=sizeof(PROCESSENTRY32);
  65.  
  66. //Obtenemos el PID del proceso
  67. Process32First(hSnapshot,&pInfo);
  68. for(;Process32Next(hSnapshot,&pInfo);)
  69. {
  70. if(!lstrcmpA(pInfo.szExeFile,ProcessName))
  71. {
  72. if(OpenProcess(PROCESS_ALL_ACCESS,FALSE,pInfo.th32ProcessID))
  73. {
  74. ExeInjected=false;
  75. hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pInfo.th32ProcessID);
  76. }
  77. }
  78. }
  79.  
  80. if(!hProcess)
  81. {
  82. hProcess=bakhProcess;
  83. return false;
  84. }
  85.  
  86. return true;
  87. }
  88.  
  89. void ClsHookAPI::InstallHook(HookStruct* miHookStruct)
  90. {
  91. //Nos inyectamos en el proceso si no lo hemos hecho ya
  92. if(ExeInjected==false)
  93. {
  94. PIMAGE_DOS_HEADER IDH;
  95. PIMAGE_NT_HEADERS INTH;
  96. PIMAGE_SECTION_HEADER ISH;
  97.  
  98. LPSTR lpFileName=(LPSTR)GlobalAlloc(GPTR,MAX_PATH);
  99. GetModuleFileName(NULL,lpFileName,MAX_PATH);
  100.  
  101. HANDLE hFile=CreateFileA(lpFileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
  102. DWORD szFile=GetFileSize(hFile,0);
  103. DWORD dwBytes;
  104. LPSTR lpFileMaped=(LPSTR)GlobalAlloc(GPTR,szFile);
  105. ReadFile(hFile,lpFileMaped,szFile,&dwBytes,0);
  106. CloseHandle(hFile);
  107.  
  108. //Obtenemos la cabecera DOS y PE en las estructuras
  109. IDH=(PIMAGE_DOS_HEADER)&lpFileMaped[0];
  110. INTH=(PIMAGE_NT_HEADERS)&lpFileMaped[IDH->e_lfanew];
  111.  
  112. //Creamos el buffer del tamaño del SizeOfImage en el que cargaremos el ejecutable
  113. LPSTR ExeBuffer=(LPSTR)VirtualAllocEx(this->hProcess,0,INTH->OptionalHeader.SizeOfImage,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  114.  
  115. //Copiamos la cabecera DOS y PE al buffer
  116. WriteProcessMemory(this->hProcess,&ExeBuffer[0],&lpFileMaped[0],INTH->OptionalHeader.SizeOfHeaders,0);
  117.  
  118. //Copiamos las secciones en su VirtualOffset en el buffer
  119. for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++)
  120. {
  121. ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i];
  122. WriteProcessMemory(this->hProcess,&ExeBuffer[ISH->VirtualAddress],&lpFileMaped[ISH->PointerToRawData],ISH->SizeOfRawData,0);
  123. }
  124.  
  125. //Calculamos el delta entre la dirección del buffer y el ImageBase
  126. DWORD Delta=(((DWORD)ExeBuffer)-INTH->OptionalHeader.ImageBase);
  127.  
  128. //------------------------------------------------------------
  129. /* -Reubicamos la dirección base del ejecutable :D- */
  130. //------------------------------------------------------------
  131.  
  132. //Obteemos el Image Base Relocation
  133. //Copiamos el Image Base Relocation de los datos en el proceso a un buffer en el nuestro para
  134. //poder trabajar con él más comodamente
  135. PIMAGE_BASE_RELOCATION IBR=(PIMAGE_BASE_RELOCATION)GlobalAlloc(GPTR,sizeof(IMAGE_BASE_RELOCATION));
  136. PIMAGE_BASE_RELOCATION PIBR=(PIMAGE_BASE_RELOCATION)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
  137. ReadProcessMemory(hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0);
  138.  
  139. //Vamos recorriendo todas las etradas del bloque
  140. for(DWORD n=0;IBR->VirtualAddress>0;n++)
  141. {
  142. //Obtenemos el Bloque de reubicación
  143. LPSTR RelocationBlock=(LPSTR)(ExeBuffer+IBR->VirtualAddress);
  144.  
  145. //Obtenemos la primera entrada del bloque
  146. LPWORD RelocationEntry=(LPWORD)((LPSTR)PIBR+sizeof(IMAGE_BASE_RELOCATION));
  147.  
  148. //Recorremos todas las entradas del bloque
  149. for(DWORD i=0;i<((IBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2);i++,RelocationEntry++)
  150. {
  151. WORD valor;
  152. ReadProcessMemory(this->hProcess,RelocationEntry,&valor,2,0);
  153. //Obtenemos los 4 bits que definen el tipo de reubicación
  154. DWORD type=valor>>12;
  155.  
  156. //Obtenemos los 12 bits que definen la dirección de la reubicación
  157. DWORD offset=valor&0xFFF;
  158.  
  159. //Si el tipo de reubicación es relativo a la dirección base, añadimso el delta
  160. if(type==IMAGE_REL_BASED_HIGHLOW)
  161. {
  162. //Añadimos a la dirección que depende del imagebase original
  163. //el delta entre el imagebase y nuestra dirección base
  164. LPDWORD newAddr=(LPDWORD)(RelocationBlock+offset);
  165. DWORD NewValue;
  166. ReadProcessMemory(this->hProcess,newAddr,&NewValue,4,0);
  167. NewValue+=Delta;
  168. WriteProcessMemory(this->hProcess,newAddr,&NewValue,4,0);
  169. }
  170. }
  171.  
  172. //Vamos al siguiente bloque
  173. PIBR=(PIMAGE_BASE_RELOCATION)(((DWORD)PIBR)+IBR->SizeOfBlock);
  174. ReadProcessMemory(this->hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0);
  175. }
  176. GlobalFree(IBR);
  177.  
  178.  
  179. //---------------------------------------------------------------------
  180. /* -Cargamos los valores de la IAT para poder llamar a las API's- */
  181. //---------------------------------------------------------------------
  182.  
  183. PIMAGE_THUNK_DATA ITD;
  184. PIMAGE_THUNK_DATA PITD;
  185. PIMAGE_IMPORT_BY_NAME IIBN;
  186.  
  187. //Comprobamos si hay Import Data Descriptor
  188. if(INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size>0)
  189. {
  190.  
  191. //Obtenemos el Import Data Descriptor
  192. //Copiamos el Import Data Descriptor de los datos en el proceso a un buffer en el nuestro para
  193. //poder trabajar con él más comodamente
  194. PIMAGE_IMPORT_DESCRIPTOR IID=(PIMAGE_IMPORT_DESCRIPTOR)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_DESCRIPTOR));
  195. PIMAGE_IMPORT_DESCRIPTOR PIID=(PIMAGE_IMPORT_DESCRIPTOR)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  196. ReadProcessMemory(this->hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0);
  197.  
  198. //Vamos recorriendo todas las Dll's importadas por el ejecutable
  199. for(;IID->Name;)
  200. {
  201. //Obtenemos la longitud del nombre de la dll
  202. DWORD szName=0;
  203. CHAR miByte=1;
  204. for(int i=0;miByte;i++)
  205. {
  206. szName=i;
  207. ReadProcessMemory(this->hProcess,ExeBuffer+IID->Name+i,&miByte,1,0);
  208. }
  209.  
  210. //Obtenemos el nombre de la dll
  211. LPSTR lpName=(LPSTR)GlobalAlloc(GPTR,szName+1);
  212. ReadProcessMemory(this->hProcess,ExeBuffer+IID->Name,lpName,szName+1,0);
  213.  
  214. //Cargamos la dll
  215. HMODULE hLib=LoadLibraryA(lpName);
  216.  
  217. //Obtenemos la dirección al primer miembro del array Image Thunk Data's
  218. PITD=(PIMAGE_THUNK_DATA)((DWORD)ExeBuffer+IID->FirstThunk);
  219. ITD=(PIMAGE_THUNK_DATA)GlobalAlloc(GPTR,sizeof(IMAGE_THUNK_DATA));
  220. ReadProcessMemory(this->hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0);
  221.  
  222. //Vamos recorriendo las funciones importadas
  223. for(DWORD x=0;ITD->u1.Ordinal;x++)
  224. {
  225. miByte=1;
  226. //Obtenemos la longitud del nombre de la API
  227. for(int i=0;miByte;i++)
  228. {
  229. szName=i;
  230. LPSTR puntero=ExeBuffer+ITD->u1.Function+2;
  231. puntero+=i;
  232. ReadProcessMemory(this->hProcess,puntero,&miByte,1,0);
  233. }
  234.  
  235. //Cargamos el Image Import By Name para obtener el nombre
  236. IIBN=(PIMAGE_IMPORT_BY_NAME)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_BY_NAME)+szName);
  237. ReadProcessMemory(this->hProcess,ExeBuffer+ITD->u1.Function,IIBN,sizeof(IMAGE_IMPORT_BY_NAME)+szName,0);
  238.  
  239. //Obtenemos la dirección de la función y la guardamos en la IAT
  240. DWORD lpAPI=(DWORD)GetProcAddress(hLib,(LPCSTR)&IIBN->Name);
  241. WriteProcessMemory(this->hProcess,ExeBuffer+IID->FirstThunk+x*sizeof(IMAGE_THUNK_DATA),&lpAPI,4,0);
  242.  
  243. PITD++;
  244. ReadProcessMemory(this->hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0);
  245. }
  246. PIID++;
  247. ReadProcessMemory(this->hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0);
  248. GlobalFree(lpName);
  249. GlobalFree(ITD);
  250. }
  251. GlobalFree(IID);
  252. }
  253. this->InjectedExeBaseAddress=ExeBuffer;
  254. this->ExeInjected=true;
  255. }
  256.  
  257. //Cambiamos el ImageBase a la dirección de la función que recibe el hook
  258. miHookStruct->lpHookFunction=(LPSTR)((unsigned long)this->InjectedExeBaseAddress+(unsigned long)miHookStruct->lpHookFunction-(unsigned long)GetModuleHandle(NULL));
  259.  
  260. //Reservamos espacio para la estructura en el proceso en el que inyectamos
  261. HookStruct* lpHookStruct=(HookStruct*)VirtualAllocEx(this->hProcess,0,sizeof(HookStruct),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  262. //Esribimos la estructura en el espacio reservado
  263. WriteProcessMemory(this->hProcess,lpHookStruct,miHookStruct,sizeof(HookStruct),0);
  264.  
  265. //Seteamos el valor de nextHookStruct de la HookStruct anterior a la que acabamos de inyectar
  266. HookStruct* lastHookStruct=(HookStruct*)GlobalAlloc(GPTR,sizeof(HookStruct));
  267. ReadProcessMemory(this->hProcess,lastInjectedHookStruct,lastHookStruct,sizeof(HookStruct),0);
  268. lastHookStruct->nextHookStruct=lpHookStruct;
  269. WriteProcessMemory(this->hProcess,lastInjectedHookStruct,lastHookStruct,sizeof(HookStruct),0);
  270.  
  271. //Seteamo el valor de lastInjectedHookStruct
  272. this->lastInjectedHookStruct=lpHookStruct;
  273.  
  274. //Obteemos la dirección de la función HookApi
  275. DWORD lpHookApi=(DWORD)this->InjectedExeBaseAddress+(DWORD)HookApi-(DWORD)GetModuleHandle(NULL);
  276.  
  277. //Llamamos al EntryPoint
  278. CreateRemoteThread(this->hProcess,0,0,(LPTHREAD_START_ROUTINE)lpHookApi,(HookStruct*)lpHookStruct,0,0);
  279.  
  280. return;
  281. }
  282.  
  283. //Pequeño código en ASM que por el cual sustituimos el comienzo de la API
  284. void __declspec(naked) Caller()
  285. {
  286. __asm
  287. {
  288. push 0x00400000 //~Ésta dirección se sustituye en tiempo de ejecución por el puntero a HookStruct
  289. push 0x00400000 //~Ésta dirección se sustituye en tiempo de ejecución por la dirección de ControlFunction
  290. ret
  291. }
  292. }
  293.  
  294. void UninstallHooks(HookStruct* miHookStruct)
  295. {
  296. __asm pushad;
  297. //Nos desplazamos al primer Hook
  298. for(;miHookStruct->previousHookStruct!=NULL;)
  299. {
  300. miHookStruct=miHookStruct->previousHookStruct;
  301. }
  302.  
  303. //Desinstalamos todos los Hooks
  304. for(;miHookStruct!=NULL;)
  305. {
  306. mCopyMemory(miHookStruct->lpAPI,miHookStruct->lpBuffer,11);
  307. FlushInstructionCache(GetCurrentProcess(),0,0);
  308. miHookStruct=miHookStruct->nextHookStruct;
  309. }
  310. __asm popad;
  311. }
  312.  
  313. void RestoreHooks(HookStruct* miHookStruct)
  314. {
  315. __asm pushad;
  316. //Nos desplazamos al primer Hook
  317. for(;miHookStruct->previousHookStruct!=NULL;)
  318. {
  319. miHookStruct=miHookStruct->previousHookStruct;
  320. }
  321.  
  322. //Volvemos a instalar todos los Hooks
  323. for(;miHookStruct!=NULL;)
  324. {
  325. //Copiamos los X primeros bytes de la api a nuestro buffer
  326. mCopyMemory(miHookStruct->lpBuffer,miHookStruct->lpAPI,11);
  327.  
  328. //Cambiamos los la primera dirección que pushea 'Caller' por la un puntero a miHookStruct
  329. mCopyMemory((LPSTR)Caller+1,(LPSTR)&miHookStruct,4);
  330.  
  331. //Cambiamos los la segunda dirección que pushea 'Caller' por la dirección de ControlFunction
  332. LPSTR dirControlFunction=(LPSTR)ControlFunction;
  333. mCopyMemory((LPSTR)Caller+6,(LPSTR)&dirControlFunction,4);
  334.  
  335. //Cambiamos los 10 primeros bytes de la API por la función Caller
  336. mCopyMemory(miHookStruct->lpAPI,(LPSTR)Caller,11);
  337. FlushInstructionCache(GetCurrentProcess(),0,0);
  338. miHookStruct=miHookStruct->nextHookStruct;
  339. }
  340. __asm popad;
  341. }
  342.  
  343. //Función a la que salta la API hookeda en que se inyectó 'Caller'
  344. void __declspec(naked) ControlFunction()
  345. {
  346. __asm
  347. {
  348. jmp go
  349.  
  350. miHookStruct:
  351. nop
  352. nop
  353. nop
  354. nop
  355.  
  356. retornar:
  357. _emit 0x68 //push
  358. dirRetorno:
  359. nop
  360. nop
  361. nop
  362. nop
  363. _emit 0xC3 //ret
  364.  
  365. RetornoApi:
  366. nop
  367. nop
  368. nop
  369. nop
  370. Temp:
  371. nop
  372. nop
  373. nop
  374. nop
  375.  
  376. go:
  377. //Sólo modificamos eax para no modificar más registros de los que modifica la API
  378. //Copiamos a Temp el primer parámetro que hay sobre la pila (lpHookStruct)
  379. mov eax,Temp
  380. push dword ptr ds:[esp]
  381. pop dword ptr ds:[eax]
  382.  
  383. //Copiamos lpHookStruct a miHookStruct
  384. push 4
  385. push Temp
  386. push miHookStruct
  387. call mCopyMemory
  388. add esp,12 //Restauramos la pila
  389.  
  390. //Quitamos lpHookStruct de la pila
  391. add esp,4
  392.  
  393. //Copiamos a Temp el primer parámetro que hay sobre la pila (dirección de retorno)
  394. mov eax,Temp
  395. push dword ptr ds:[esp]
  396. pop dword ptr ds:[eax]
  397.  
  398. //Copiamos la dirección de retorno a dirRetorno
  399. push 4
  400. push Temp
  401. push dirRetorno
  402. call mCopyMemory
  403. add esp,12 //Restauramos la pila
  404.  
  405. //Quitamos la direcc de retorno de la pila
  406. add esp,4
  407.  
  408. //LLamamos a UninstallHooks para desinstalar todos los hooks antes de llamar a la función que recive el Hook
  409. mov eax,miHookStruct
  410. push dword ptr ds:[eax]
  411. call UninstallHooks
  412. add esp,4
  413.  
  414. //Llamamos a la función que recive el hook y copiamos el retorno a RetornoApi
  415. mov eax,miHookStruct
  416. mov eax,dword ptr ds:[eax]
  417. call dword ptr ds:[eax+0x04]
  418. push eax
  419. mov eax,RetornoApi
  420. pop dword ptr ds:[eax]
  421.  
  422. //Restauramos todos los Hooks
  423. mov eax,miHookStruct
  424. push dword ptr ds:[eax]
  425. call RestoreHooks
  426. add esp,4
  427.  
  428. //Movemos a eax el retorno de la API
  429. mov eax,RetornoApi
  430. push dword ptr ds:[eax]
  431. pop eax
  432.  
  433. //Saltamos a la dirección de retorno
  434. jmp retornar
  435. }
  436. }
  437.  
  438. void HookApi(HookStruct* miHookStruct)
  439. {
  440. __asm pushad;
  441. //Damos permisos de escritura, lectura y ejecución a nuestro buffer
  442. DWORD OldProtection;
  443. VirtualProtect((LPVOID)miHookStruct->lpBuffer,11,PAGE_EXECUTE_READWRITE,&OldProtection);
  444.  
  445. // Le damos permisos de ejecución a los X primeros bytes de la api
  446. VirtualProtect((LPVOID)miHookStruct->lpAPI,11,PAGE_EXECUTE_READWRITE,&OldProtection);
  447.  
  448. //Copiamos los X primeros bytes de la api a nuestro buffer
  449. mCopyMemory(miHookStruct->lpBuffer,miHookStruct->lpAPI,11);
  450.  
  451. //Cambiamos los la primera dirección que pushea 'Caller' por la un puntero a miHookStruct
  452. mCopyMemory((LPSTR)Caller+1,(LPSTR)&miHookStruct,4);
  453.  
  454. //Cambiamos los la segunda dirección que pushea 'Caller' por la dirección de ControlFunction
  455. LPSTR dirControlFunction=(LPSTR)ControlFunction;
  456. mCopyMemory((LPSTR)Caller+6,(LPSTR)&dirControlFunction,4);
  457.  
  458. //Cambiamos los 10 primeros bytes de la API por la función Caller
  459. mCopyMemory(miHookStruct->lpAPI,(LPSTR)Caller,11);
  460.  
  461. FlushInstructionCache(GetCurrentProcess(),0,0);
  462. __asm popad;
  463. }
  464.  
  465. //Función que simula RtlCopyMemory
  466. void __declspec(naked) mCopyMemory(LPSTR bEscritura,LPSTR bLectura,DWORD lenBuffer)
  467. {
  468. __asm
  469. {
  470. pushad
  471. mov esi,[esp+0x28] //bLectura
  472. mov ecx,[esp+0x2C] //lenBuffer
  473. mov edi,[esp+0x24] //bEscritura
  474. dec ecx
  475.  
  476. bCopyMemory:
  477. dec ecx
  478. movsb
  479. cmp ecx,0
  480. jge bCopyMemory
  481. popad
  482. ret
  483. }
  484. }
  485.  

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
En línea


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


Desconectado Desconectado

Mensajes: 859



Ver Perfil
Re: [SRC][C++/ASM] ClsHookAPI
« Respuesta #1 en: 16 Enero 2010, 15:31 pm »

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


  De verdad que esta termendo el Code Men  ;)
En línea

‭‭‭‭jackl007


Desconectado Desconectado

Mensajes: 1.403


[UserRPL]


Ver Perfil WWW
Re: [SRC][C++/ASM] ClsHookAPI
« Respuesta #2 en: 16 Enero 2010, 15:59 pm »

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

YST


Desconectado Desconectado

Mensajes: 965


I'm you


Ver Perfil WWW
Re: [SRC][C++/ASM] ClsHookAPI
« Respuesta #3 en: 16 Enero 2010, 19:05 pm »

Muy bueno :P
Salu2
En línea



Yo le enseñe a Kayser a usar objetos en ASM
MazarD
Colaborador
***
Desconectado Desconectado

Mensajes: 885


mazard.info


Ver Perfil WWW
Re: [SRC][C++/ASM] ClsHookAPI
« Respuesta #4 en: 16 Enero 2010, 20:52 pm »

Excelente trabajo y muy buen estilo de programación.
En línea

-Learn as if you were to live forever, live as if you were to die tomorrow-

http://www.mazard.info
irc://irc.freenode.org/elhacker.net
raulrl

Desconectado Desconectado

Mensajes: 16


Ver Perfil
Re: [SRC][C++/ASM] ClsHookAPI
« Respuesta #5 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  ;-)
En línea

Nork

Desconectado Desconectado

Mensajes: 196



Ver Perfil
Re: [SRC][C++/ASM] ClsHookAPI
« Respuesta #6 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!
En línea

C' Est La Vie
Karcrack


Desconectado Desconectado

Mensajes: 2.416


Se siente observado ¬¬'


Ver Perfil
Re: [SRC][C++/ASM] ClsHookAPI
« Respuesta #7 en: 16 Enero 2010, 22:13 pm »

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

Tiene algun error? :rolleyes: :rolleyes: :xD
En línea

[Zero]
Wiki

Desconectado Desconectado

Mensajes: 1.082


CALL DWORD PTR DS:[0]


Ver Perfil WWW
Re: [SRC][C++/ASM] ClsHookAPI
« Respuesta #8 en: 16 Enero 2010, 22:56 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
En línea


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


Desconectado Desconectado

Mensajes: 2.416


Se siente observado ¬¬'


Ver Perfil
Re: [SRC][C++/ASM] ClsHookAPI
« Respuesta #9 en: 17 Enero 2010, 01:35 am »

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:
En línea

Páginas: [1] 2 3 Ir Arriba Respuesta Imprimir 

Ir a:  
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines