Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Hook a la API GetClipboardData (https://www.clubdelphi.com/foros/showthread.php?t=59996)

escafandra 16-09-2008 19:54:44

Hook a la API GetClipboardData
 
He realizado un Hook a la API GetClipboardData como me propuse aquí. No ha sido fácil. He de agradecer a cHackAll por su interés en el tema y su ayuda, así como el tutorial que ha publicado.

Parte de la programación está en ensamblador, me hacía ilusión volver a usarlo, hacía mucho tiempo que lo tenía apartado. El resto de la programación la he escrito en Builder. He tenido problemas cuendo la API era llamada desde un mensaje WM_PASTE, se alteraba la pila, pero lo solucioné, al menos en las pruebas que he realizado.

La dll:
Código:

#include <windows.h>
//---------------------------------------------------------------------------

void HookGetClipboardData(UINT uFormat, HANDLE ClipboardHandle)
{
  char MSG[256];
  strcpy(MSG, "Esto es la prueba del Hook\n");
  if(uFormat == CF_TEXT){
    strcat(MSG, "En el clipboard tenemos: \n\n");
    if(ClipboardHandle) strcat(MSG, (char*)ClipboardHandle);
  }
  MessageBox(0, MSG, "Hook API GetClipboardData", MB_OK);

}

__declspec(naked)
void HGetClipboardData()
{
  asm{
  jmp Sigue
  Salto_API:
  // Llamo a la Call de la API original:
  db 0E9h, 00, 00, 00, 00        // JMP al Call_de_API_Original

  uFormat:  dd 0
  Handle:  dd 0
  RetAPI:  dd 0
  PilaRet:  dd 0
  Temporal: dd 0

  Sigue:
  // Preparo el salto al Hook al finalizar la API
  mov  dword Ptr PilaRet, ebp    // Guardo la posición de la pila para retorno
  add  dword Ptr PilaRet, 4

  push [ebp]+8                  // Guardo parámetro uFormat
  pop  dword Ptr uFormat

  push [ebp]+4                  // Guardo Dirección de retorno de la API original
  pop  dword Ptr RetAPI

  mov  [ebp]+4, offset HPostAPI  // Coloco la nueva dirección de retorno en la

pila

  jmp  Salto_API                // Salto a completar la API original

 
 
  // Despues de ejecutar la API GetClipboardData se ejecutará el Hook
  HPostAPI:
  mov  esp, dword Ptr PilaRet    // restauro el valor de la pila
  mov  dword Ptr Handle, eax    // Guardo el valor Handle de retorno
 
  // Lamada a la función Hook 
  push eax                      // Paso Handle devuelto por API
  push dword Ptr uFormat        // Paso uFormat
  call HookGetClipboardData      // EL HOOK
  pop  dword Ptr Temporal        // Retiro los parámetros pasados
  pop  dword Ptr Temporal

  // Terminación
  mov  eax, dword Ptr Handle    // Coloco el valor de retorno
  pop  dword Ptr Temporal        // Retiro el antiguo retorno.
  push dword Ptr RetAPI          // Restauro la dirección retorno original
  ret  4
  }
}

void InstallHook()
{
  DWORD OldProtect;
  BYTE*  APIAddress = (BYTE*)GetProcAddress(GetModuleHandle("User32.dll"),

"GetClipboardData");
  DWORD* HookCall  = (DWORD*)((BYTE*)HGetClipboardData + 0x06);
  DWORD* APICall    = (DWORD*)(APIAddress + 0x12);  //APICall  =

(DWORD*)(0x7E3B0D7A + 0x12);

  // Autorizo escribir en HGetClipboardData
  VirtualProtectEx((void*)-1, (BYTE*)HookCall, 4, PAGE_EXECUTE_READWRITE,

&OldProtect);
  *HookCall = (DWORD)APICall + 4 + *APICall - (DWORD)HookCall-4;
  VirtualProtectEx((void*)-1, (BYTE*)HookCall, 4, OldProtect, 0);

  // Autorizo escribir en la API GetClipboardData
  VirtualProtectEx((void*)-1, (BYTE*)APICall, 4, PAGE_EXECUTE_READWRITE,

&OldProtect);
  *APICall = (DWORD)((BYTE*)HGetClipboardData - (BYTE*)APICall) - 4;
  VirtualProtectEx((void*)-1, (BYTE*)APICall, 4, OldProtect, 0);
}

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    switch (reason)
    {
        case DLL_PROCESS_ATTACH:
            InstallHook();
            break;
        case DLL_PROCESS_DETACH:
            break;
    }
  return 1;
}

El programa de prueba:
Código:

#include <windows.h>
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int

nCmdShow)
{
  HANDLE H = LoadLibrary("GetClipboardData.dll");
  OpenClipboard(0);
  char* Text = (char*)GetClipboardData(CF_TEXT);
  CloseClipboard();
}

Para mi esto ha sido un juego muy satisfactorio y he aprendido mucho.

Saludos.


La franja horaria es GMT +2. Ahora son las 18:48:23.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi