Enganche


De Wikipedia, la enciclopedia libre
  (Redirigido desde la función Hook )
Saltar a navegación Saltar a búsqueda

En programación de computadoras , el término enganche cubre una variedad de técnicas utilizadas para alterar o aumentar el comportamiento de un sistema operativo , de aplicaciones o de otros componentes de software al interceptar llamadas a funciones o mensajes o eventos que se transmiten entre componentes de software . El código que maneja tales llamadas a funciones, eventos o mensajes interceptados se llama gancho .

El enganche se utiliza para muchos propósitos, incluida la depuración y la ampliación de la funcionalidad. Los ejemplos pueden incluir interceptar mensajes de eventos de teclado o mouse antes de que lleguen a una aplicación, o interceptar llamadas al sistema operativo para monitorear el comportamiento o modificar la función de una aplicación u otro componente. También se usa ampliamente en programas de evaluación comparativa, por ejemplo , en la medición de la velocidad de fotogramas en juegos 3D, donde la salida y la entrada se realizan mediante enganches.

El enganche también puede ser utilizado por código malicioso. Por ejemplo, los rootkits , piezas de software que intentan hacerse invisibles falsificando el resultado de las llamadas a la API que de otro modo revelarían su existencia, a menudo utilizan técnicas de enganche.

Métodos

Normalmente, los enganches se insertan mientras el software ya se está ejecutando, pero el enganche es una táctica que también se puede emplear antes de que se inicie la aplicación. Ambas técnicas se describen con mayor detalle a continuación.

Modificación de fuente

Al modificar la fuente del ejecutable o biblioteca antes de que se ejecute una aplicación, a través de técnicas de ingeniería inversa , también puede lograr el enganche. Esto se usa generalmente para interceptar llamadas a funciones para monitorearlas o reemplazarlas por completo.

Por ejemplo, al usar un desensamblador , se puede encontrar el punto de entrada de una función dentro de un módulo . Luego se puede modificar para cargar dinámicamente algún otro módulo de biblioteca y luego ejecutar los métodos deseados dentro de esa biblioteca cargada. Si corresponde, otro enfoque relacionado mediante el cual se puede lograr el enlace es alterando la tabla de importación de un ejecutable. Esta tabla se puede modificar para cargar cualquier módulo de biblioteca adicional, así como para cambiar el código externo que se invoca cuando la aplicación llama a una función.

Un método alternativo para lograr el enlace de funciones es interceptar las llamadas a funciones a través de una biblioteca contenedora . Al crear un contenedor, crea su propia versión de una biblioteca que carga una aplicación, con la misma funcionalidad de la biblioteca original que reemplazará. Es decir, todas las funciones a las que se puede acceder son esencialmente las mismas entre el original y el reemplazo. Esta biblioteca contenedora puede diseñarse para llamar a cualquiera de las funciones de la biblioteca original o reemplazarla con un conjunto de lógica completamente nuevo.

Modificación del tiempo de ejecución

Los sistemas operativos y el software pueden proporcionar los medios para insertar fácilmente eventos en tiempo de ejecución . Está disponible siempre que el proceso de inserción del gancho tenga suficiente permiso para hacerlo. Microsoft Windows, por ejemplo, le permite insertar enlaces que se pueden usar para procesar o modificar eventos del sistema y eventos de aplicaciones para cuadros de diálogo , barras de desplazamiento y menús , así como otros elementos. También permite que un gancho inserte, elimine, procese o modifique eventos de teclado y mouse . Linux proporciona otro ejemplo en el que los ganchos se pueden usar de manera similar para procesar eventos de red dentro del kernel a través deNetFilter .

Cuando no se proporciona dicha funcionalidad, una forma especial de enlace emplea la interceptación de las llamadas a la función de biblioteca realizadas por un proceso. El enganche de funciones se implementa cambiando las primeras instrucciones de código de la función de destino para saltar a un código inyectado. Alternativamente, en sistemas que utilizan el concepto de biblioteca compartida , la tabla de vectores de interrupción o la tabla de descriptores de importación se pueden modificar en la memoria. Esencialmente, estas tácticas emplean las mismas ideas que las de la modificación de la fuente, pero en cambio alteran las instrucciones y estructuras ubicadas en la memoria de un proceso una vez que ya se está ejecutando.

Código de muestra

Enlace de tabla de método virtual

Siempre que una clase define / hereda una función virtual (o método), los compiladores agregan una variable miembro oculta a la clase que apunta a una tabla de método virtual (VMT o Vtable). La mayoría de los compiladores colocan el puntero VMT oculto en los primeros 4 bytes de cada instancia de la clase. Un VMT es básicamente una matriz de punteros a todas las funciones virtuales que las instancias de la clase pueden llamar. En el tiempo de ejecución, estos punteros se establecen para apuntar a las funciones correctas, porque en el momento de la compilación , aún no se sabe si se llamará a la función base o si se llamará a una versión anulada de la función de una clase derivada (lo que permite para polimorfismo). Por lo tanto, las funciones virtuales se pueden conectar reemplazando los punteros a ellas dentro de cualquier VMT que aparezcan. El siguiente código muestra un ejemplo de un gancho VMT típico en Microsoft Windows, escrito en C ++. [1]

#include <iostream> #include "windows.h"  usando el espacio de nombres std ;   clase  VirtualClass{publico :  int número ;   virtual void VirtualFn1 () // Esta es la función virtual que se enganchará. {     cout << "VirtualFn1 llamado" << número ++ << " \ n \ n " ;       }};    usando VirtualFn1_t = void ( __thiscall * ) ( void * thisptr ); VirtualFn1_t orig_VirtualFn1 ;       void __fastcall hkVirtualFn1 ( void * thisptr , int edx ) // Esta es nuestra función de enganche que haremos que llame al programa en lugar de la función original de VirtualFn1 después de que se haya realizado el enganche. {       cout << "Función de gancho llamada" << " \ n " ;      orig_VirtualFn1 ( thisptr ); // Llamar a la función original. }     int main () { VirtualClass * myClass = new VirtualClass (); // Cree un puntero a una instancia asignada dinámicamente de VirtualClass. void ** vTablePtr = * reinterpret_cast < void ***> ( myClass ); // Busque la dirección que apunta a la base de VirtualClass 'VMT (que luego apunta a VirtualFn1) y almacénela en vTablePtr. DWORD oldProtection ;               VirtualProtect ( vTablePtr , 4 , PAGE_EXECUTE_READWRITE , y oldProtection ); // Elimina la protección de la página al inicio del VMT para que podamos sobrescribir su primer puntero. orig_VirtualFn1 = reinterpret_cast < VirtualFn1_t > ( * vTablePtr ); // Almacena el puntero a VirtualFn1 desde el VMT en una variable global para que se pueda acceder de nuevo más tarde después de que su entrada en el VMT se haya // sobrescrito con nuestra función de gancho. * vTablePtr = & hkVirtualFn1 ;               // Sobrescribe el puntero a VirtualFn1 dentro de la tabla virtual a un puntero a nuestra función de gancho (hkVirtualFn1). VirtualProtect ( vTablePtr , 4 , oldProtection , 0 ); // Restaurar la protección de la página antigua. myClass -> VirtualFn1 (); // Llame a la función virtual desde nuestra instancia de clase. Debido a que ahora está enganchado, esto realmente llamará a nuestra función de enganche (hkVirtualFn1). myClass -> VirtualFn1 ();           myClass -> VirtualFn1 ();  eliminar myClass ;   return 0 ; }

Es importante tener en cuenta que todas las funciones virtuales deben ser funciones miembro de clase, y todas las funciones miembro de clase (no estáticas) se llaman con la convención de llamada __thiscall(a menos que la función miembro tome un número variable de argumentos, en cuyo caso se llama con __cdecl). La convención de llamada __thiscall pasa un puntero a la instancia de la clase de llamada (comúnmente conocida como puntero "this") a través del registro ECX (en la arquitectura x86). Por lo tanto, para que una función de gancho intercepte correctamente el puntero "this" que se pasa y lo tome como argumento, debe buscar en el registro ECX. En el ejemplo anterior, esto se hace configurando la función hook (hkVirtualFn1) para usar la convención de llamada __fastcall, que hace que la función hook busque en el registro ECX uno de sus argumentos.

También tenga en cuenta que, en el ejemplo anterior, la función hook (hkVirtualFn1) no es una función miembro en sí misma, por lo que no puede usar la convención de llamada __thiscall. En su lugar, debe usarse __fastcall porque es la única otra convención de llamada que busca un argumento en el registro ECX.

Enlace de evento de teclado C #

El siguiente ejemplo se conectará a eventos de teclado en Microsoft Windows usando Microsoft .NET Framework .

utilizando  System.Runtime.InteropServices ;espacio de nombres  Ganchos {  público  de clase  KeyHook  {  / * variables de miembro * /  protegida  estática  int  gancho ;  Delegado LowLevelKeyboardDelegate estático protegido  ; objeto protegido de solo lectura estático Lock = new object (); protected static bool IsRegistered = false ;                 / * Importaciones de DLL * /  [DllImport ("user32")]  extern estático privado  int SetWindowsHookEx ( int idHook , LowLevelKeyboardDelegate lpfn , int hmod , int dwThreadId );           [DllImport ("user32")]  privado  estático  extern  int  CallNextHookEx ( int  hHook ,  int  nCode ,  int  wParam ,  KBDLLHOOKSTRUCT  lParam ); [DllImport ("user32")]  privado  estático  extern  int  UnhookWindowsHookEx ( int  hHook ); / * Tipos y constantes * /  delegado protegido  int LowLevelKeyboardDelegate ( int nCode , int wParam , ref KBDLLHOOKSTRUCT lParam ); const privado int HC_ACTION = 0 ; privado const int WM_KEYDOWN = 0 x0100 ; privado const int WM_KEYUP = 0 x0101 ; const privado int WH_KEYBOARD_LL = 13 ;                                 [StructLayout (LayoutKind.Sequential)]  public  struct  KBDLLHOOKSTRUCT  {  public  int  vkCode ;  public  int  scanCode ;  banderas públicas  int  ; public int time ; public int dwExtraInfo ; }        / * Métodos * /  static  private  int  LowLevelKeyboardHandler ( int  nCode ,  int  wParam ,  ref  KBDLLHOOKSTRUCT  lParam )  {  if  ( nCode  ==  HC_ACTION )  {  if  ( wParam  ==  WM_KEYDOWN )  System . Consola . Fuera . WriteLine ( "Tecla abajo:"  +  lParam . VkCode );  más  si  ( wParam  == WM_KEYUP )  Sistema . Consola . Fuera . WriteLine ( "Tecla arriba:"  +  lParam . VkCode );  }  return  CallNextHookEx ( Hook ,  nCode ,  wParam ,  lParam );  } public  static  bool  RegisterHook ()  {  lock  ( Lock )  {  if  ( IsRegistered )  return  true ;  Delegado  =  LowLevelKeyboardHandler ;  Hook  =  SetWindowsHookEx (  WH_KEYBOARD_LL ,  Delegado ,  Marshal . GetHINSTANCE (  Sistema . Reflexión . Ensamblaje . GetExecutingAssembly (). GetModules () [ 0 ]  ).ToInt32 (),  0  ); if  ( Hook  ! =  0 )  return  IsRegistered  =  true ;  Delegado  =  nulo ;  devolver  falso ;  }  } public  static  bool  UnregisterHook ()  {  lock  ( Lock )  {  return  IsRegistered  =  ( UnhookWindowsHookEx ( Hook )  ! =  0 );  }  }  } }

API / función de enganche / intercepción usando la instrucción JMP también conocida como empalme

El siguiente código fuente es un ejemplo de un método de enlace API / función que enlaza sobrescribiendo los primeros seis bytes de una función de destino con una instrucción JMP a una nueva función. El código se compila en un archivo DLL y luego se carga en el proceso de destino utilizando cualquier método de inyección de DLL . Usando una copia de seguridad de la función original, se pueden restaurar los primeros seis bytes nuevamente para que la llamada no se interrumpa. En este ejemplo, la función de la API de win32 MessageBoxW está enganchada. [2]

/ * Esta idea se basa en el enfoque chrom-lib, distribuido bajo licencia GNU LGPL. Fuente chrom-lib: https://github.com/linuxexp/chrom-lib Copyright (C) 2011 Raja Jamwal * /#include <windows.h>  #define TAMAÑO 6 typedef int ( WINAPI * pMessageBoxW ) ( HWND , LPCWSTR , LPCWSTR , UINT ); // Prototipo de cuadro de mensaje int WINAPI MyMessageBoxW ( HWND , LPCWSTR , LPCWSTR , UINT ); // Nuestro desvío               anular BeginRedirect ( LPVOID ); pMessageBoxW pOrigMBAddress = NULL ; // dirección del BYTE original oldBytes [ TAMAÑO ] = { 0 }; // copia de seguridad BYTE JMP [ TAMAÑO ] = { 0 }; // Instrucción JMP de 6 bytes DWORD oldProtect , myProtect = PAGE_EXECUTE_READWRITE ;                       INT APIENTRY DllMain ( HMODULE hDLL , DWORD Razón , LPVOID Reservados ) { interruptor ( Razón ) { caso DLL_PROCESS_ATTACH : // si está unido pOrigMBAddress = ( pMessageBoxW ) GetProcAddress ( GetModuleHandleA ( "user32.dll" ), // obtener la dirección del original de "MessageBoxW " ); if ( pOrigMBAddress ! = NULL ) BeginRedirect (                                MyMessageBoxW ); // empezar a desviar la pausa ;   caso DLL_PROCESS_DETACH : VirtualProtect (( LPVOID ) pOrigMBAddress , TAMAÑO , myProtect , y oldProtect ); // asignar protección de lectura y escritura memcpy ( pOrigMBAddress , oldBytes , SIZE ); // restaurar copia de seguridad VirtualProtect (( LPVOID ) pOrigMBAddress , SIZE , oldProtect , & myProtect ); // restablecer la protección                 caso DLL_THREAD_ATTACH : caso DLL_THREAD_DETACH : romper ; } devuelve VERDADERO ; }              anular BeginRedirect ( LPVOID newFunction ) { BYTE tempJMP [ TAMAÑO ] = { 0xE9 , 0x90 , 0x90 , 0x90 , 0x90 , 0xC3 }; // 0xE9 = JMP 0x90 = NOP 0xC3 = RET memcpy ( JMP , tempJMP , SIZE ); // almacena la instrucción jmp en JMP DWORD JMPSize = (( DWORD ) newFunction - ( DWORD ) pOrigMBAddress                          - 5 ); // calcular la distancia de salto VirtualProtect (( LPVOID ) pOrigMBAddress , SIZE , // asignar protección de lectura y escritura PAGE_EXECUTE_READWRITE , & oldProtect ); memcpy ( oldBytes , pOrigMBAddress , TAMAÑO ); // hacer una copia de seguridad de memcpy ( & JMP [ 1 ], & JMPSize , 4 ); // llena los nop con la distancia de salto (JMP, distancia (4bytes), RET) memcpy (                 pOrigMBAddress , JMP , TAMAÑO ); // establece la instrucción de salto al comienzo de la función original VirtualProtect (( LPVOID ) pOrigMBAddress , SIZE , oldProtect , & myProtect ); // restablecer la protección }          int WINAPI MyMessageBoxW ( HWND hWnd , LPCWSTR lpText , LPCWSTR lpCaption , UINT uiType ) { VirtualProtect (( LPVOID ) pOrigMBAddress , SIZE , myProtect , & oldProtect ); // asignar protección de lectura y escritura memcpy ( pOrigMBAddress , oldBytes , SIZE ); // restaurar copia de seguridad int retValue = MessageBoxW ( hWnd                         , lpText , lpCaption , uiType ); // obtiene el valor de retorno de la función original memcpy ( pOrigMBAddress , JMP , SIZE ); // establece la instrucción de salto de nuevo VirtualProtect (( LPVOID ) pOrigMBAddress , SIZE , oldProtect , & myProtect ); // restablecer la protección return retValue ; // devuelve el valor de retorno original }                 

Gancho de filtro de red

Este ejemplo muestra cómo usar el enganche para alterar el tráfico de red en el kernel de Linux usando Netfilter .

#include <linux / module.h> #include <linux / kernel.h> #include <linux / skbuff.h> #include <linux / ip.h> #include <linux / tcp.h> #include <linux / in.h> #include <linux / netfilter.h> #include <linux / netfilter_ipv4.h> / * Puerto en el que queremos soltar paquetes * /static const uint16_t puerto = 25 ;     / * Esta es la función de gancho en sí misma * /static unsigned int hook_func ( unsigned int hooknum ,      struct  sk_buff ** pskb ,  const estructura net_device * en ,    const struct net_device * out ,    int ( * okfn ) ( estructura sk_buff * ))   { estructura  iphdr * iph = ip_hdr ( * pskb );    struct  tcphdr * tcph , tcpbuf ;   si ( iph -> protocolo ! = IPPROTO_TCP )    return NF_ACCEPT ;  tcph = skb_header_pointer ( * pskb , ip_hdrlen ( * pskb ), sizeof ( * tcph ), & tcpbuf );      si ( tcph == NULL )    return NF_ACCEPT ;  return ( tcph -> dest == puerto ) ? NF_DROP : NF_ACCEPT ;       }/ * Se usa para registrar nuestra función de gancho * /estructura estática nf_hook_ops nfho = {      . hook = hook_func ,   . hooknum = NF_IP_PRE_ROUTING ,   . pf = NFPROTO_IPV4 ,   . prioridad = NF_IP_PRI_FIRST ,  };estático __init int my_init ( vacío )   { return nf_register_hook ( & nfho ); }estática __exit void my_exit ( void )   { nf_unregister_hook ( & nfho );}module_init ( my_init );module_exit ( my_exit );

Conexión IAT interna

El siguiente código muestra cómo enlazar funciones que se importan desde otro módulo. Esto se puede utilizar para enlazar funciones en un proceso diferente del proceso de llamada. Para ello, el código debe compilarse en un archivo DLL y luego cargarse en el proceso de destino utilizando cualquier método de inyección de DLL . La ventaja de este método es que es menos detectable por el software antivirus y / o el software anti-trampas , uno puede convertir esto en un gancho externo que no hace uso de llamadas maliciosas. El encabezado Portable Executable contiene la tabla de direcciones de importación (IAT), que se puede manipular como se muestra en la fuente a continuación. La fuente a continuación se ejecuta en Microsoft Windows.


#include <windows.h> typedef int ( __stdcall * pMessageBoxA ) ( HWND hWnd , LPCSTR lpText , LPCSTR lpCaption , UINT uType ); // Este es el 'tipo' de la llamada MessageBoxA. pMessageBoxA RealMessageBoxA ; // Esto almacenará un puntero a la función original.             void DetourIATptr ( const char * function , void * newfunction , módulo HMODULE );       int __stdcall NewMessageBoxA ( HWND hWnd , LPCSTR lpText , LPCSTR lpCaption , UINT uType ) { // Nuestra función falsa printf ( "La cadena enviada a MessageBoxA era:% s \ n " , lpText );              return RealMessageBoxA ( hWnd , lpText , lpCaption , uType ); // Llamar a la función real }     int main ( int argc , CHAR * argv []) {      DetourIATptr ( "MessageBoxA" , ( void * ) NewMessageBoxA , 0 ); // Enganche la función MessageBoxA ( NULL , "Sólo un cuadro de mensajes" , "Sólo un cuadro de mensajes" , 0 ); // Llame a la función - esto invocará nuestro gancho falso. return 0 ;        }vacío ** IATfind ( const char * función , HMODULE módulo ) { // Encuentra la entrada específica IAT (Dirección importación de tablas) para la función dada. int ip = 0 ;          si ( módulo == 0 )   módulo = GetModuleHandle ( 0 );  PIMAGE_DOS_HEADER pImgDosHeaders = módulo ( PIMAGE_DOS_HEADER ) ;   PIMAGE_NT_HEADERS pImgNTHeaders = ( PIMAGE_NT_HEADERS ) (( LPBYTE ) pImgDosHeaders + pImgDosHeaders -> e_lfanew );     PIMAGE_IMPORT_DESCRIPTOR pImgImportDesc = ( PIMAGE_IMPORT_DESCRIPTOR ) (( LPBYTE ) pImgDosHeaders + pImgNTHeaders -> OptionalHeader . DataDirectory [ IMAGE_DIRECTORY_ENTRY_IMPORT ]. VirtualAddress );     if ( pImgDosHeaders -> e_magic ! = IMAGE_DOS_SIGNATURE )   printf ( "Error libPE: e_magic no es una firma DOS válida \ n " );para ( IMAGE_IMPORT_DESCRIPTOR * iid = pImgImportDesc ; iid -> Name ! = NULL ; iid ++ ) {         para ( int funcIdx = 0 ; * ( funcIdx + ( LPVOID * ) ( IID -> FirstThunk + ( size_t ) módulo )) =! NULL ; funcIdx ++ ) {             char * modFuncName = ( char * ) ( * ( funcIdx + ( SIZE_T * ) ( iid -> OriginalFirstThunk + ( SIZE_T ) módulo )) + ( SIZE_T ) módulo + 2 );           const uintptr_t nModFuncName = ( uintptr_t ) modFuncName ;    bool isString = ! ( NModFuncName y ( sizeof ( nModFuncName ) == 4 ? 0x80000000 : 0x8000000000000000 ));           if ( isString ) {  if ( ! _stricmp ( función , modFuncName ))  retorno funcIdx + ( LPVOID * ) ( IID -> FirstThunk + ( size_t ) módulo );     }}}return 0 ; }void DetourIATptr ( const char * function , void * newfunction , módulo HMODULE ) {        void ** funcptr = IATfind ( función , módulo );    if ( * funcptr == nueva función )    volver ;DWORD oldrights , newrights = PAGE_READWRITE ;    // Actualice la protección a READWRITE VirtualProtect ( funcptr , sizeof ( LPVOID ), newrights , & oldrights );   RealMessageBoxA = ( pMessageBoxA ) * funcptr ; // Algunos compiladores requieren la conversión como "MinGW" no estoy seguro acerca de MSVC * funcptr = newfunction ;     // Restaurar los indicadores de protección de memoria antiguos. VirtualProtect ( funcptr , sizeof ( LPVOID ), oldrights , y newrights );   }

Ver también

  • Devolución de llamada (informática)
  • Delegación (programación)
  • Terminar y permanecer residente
  • Salida de usuario
  • WinAPIOverride32

Referencias

  1. ^ psyfl, [1]
  2. ^ Para obtener más información, consulte http://ntvalk.blogspot.nl/2013/11/hooking-explained-detouring-library.html
  • Jonathan Daniel (27 de noviembre de 2013). "Hooking explicado: desvío de llamadas a la biblioteca y parcheo vtable en Windows / Linux / MAC-OSX" . Consultado el 1 de enero de 2014 .
  • Binh Nguyen (16 de agosto de 2004). "Diccionario de Hacking-Lexicon / Linux V 0.16" . Consultado el 23 de febrero de 2008 . Gancho
  • [2012-06-29: Link parece estar muerto] Autor: Santo Padre (2002-06-10). "Enganchar la API de Windows - Técnicas para enganchar las funciones de la API en Windows 1.1 en inglés" (PDF) . Archivado desde el original (PDF) el 29 de diciembre de 2009 . Consultado el 21 de febrero de 2008 .

enlaces externos

Ventanas

  • Información sobre el enlace de la función Importar tabla de direcciones.
  • Información de Microsoft sobre el enganche
  • Información y diversas técnicas relacionadas con el enganche x86.
  • APISpy32 es una aplicación que se utiliza para conectar la API de win32.
  • Detours es una biblioteca de enlace de funciones de propósito general creada por Microsoft Research que funciona en C / C ++.
  • winspy Tres formas de inyectar código en otro proceso.
  • HookTool SDK (ACF SDK) Proporciona una descripción general completa sobre el enlace de API y la inyección de código. Un producto comercial disponible también.
  • madCodeHook es una biblioteca comercial de inyección de DLL y enlaces de API x86 y x64 para C ++ y Delphi.
  • EasyHook es un motor de enganche de código abierto compatible con x86 y x64 en Windows tanto en la tierra del usuario como del kernel.
  • Seguimiento de aplicaciones de SpyStudio SpyStudio es un seguimiento de aplicaciones que engancha llamadas y muestra los resultados de forma estructurada.
  • rohitab.com API Monitor es una aplicación gratuita que puede conectar y mostrar más de 10,000 API de Windows e interfaces COM en aplicaciones y servicios de 32 y 64 bits.
  • Deviare API Hook Deviare es un marco de enganche entre procesos gratuito que se puede utilizar para interceptar las llamadas a la API de otros procesos y mostrar información de parámetros completos o crear monitores de API.
  • WinAPIOverride WinAPIOverride es un software gratuito para uso no comercial. Puede conectar win32 API, COM, OLE, ActiveX, .NET en procesos de 32 y 64 bits. Incluye herramientas de seguimiento y análisis posterior.
  • Biblioteca multiplataforma urmem C ++ 11 (x86) para trabajar con memoria (ganchos, parches, contenedor de punteros, escáner de firmas, etc.)

Linux

  • [2] Un proyecto de investigación de estudiantes que utiliza el enganche.
  • [3] Funcionalidad que permite que una pieza de software observe y controle la ejecución de otro proceso.
  • [4] Uso de LD_PRELOAD para conectar llamadas a bibliotecas compartidas.

Emacs

  • Hooks de Emacs Los Hooks son un mecanismo importante para la personalización de Emacs. Un gancho es una variable Lisp que contiene una lista de funciones, a las que se puede llamar en alguna ocasión bien definida. (Esto se llama ejecutar el gancho).

OS X y iOS

  • Cydia Substrate es un marco para dispositivos iOS con jailbreak que permite a los desarrolladores conectarse a cualquier otro marco o aplicación.
  • harpoon es una biblioteca de OS X para enganchar funciones en tiempo de ejecución.

Enlace de API en profundidad

  • Artículo desmitificado de enlace de API x86 sobre varios métodos de enlace de API para la arquitectura x86.
Obtenido de " https://en.wikipedia.org/w/index.php?title=Hooking&oldid=1036081237 "