Hooking

técnicas para alterar un sistema operativo

En programación, el término hooking abarca una gama de técnicas utilizadas para alterar o aumentar el comportamiento de un sistema operativo, de aplicaciones o de otros componentes de software interceptando llamadas de función o mensajes o eventos pasados entre componentes de software. El código que maneja tales llamadas de función, eventos o mensajes interceptados se llama un hook.

Hooking se utiliza para muchos propósitos, incluyendo la depuración de programas y la ampliación de la funcionalidad. Los ejemplos pueden incluir la interceptación de mensajes de eventos de teclado o de ratón antes de que lleguen a una aplicación o interceptar llamadas de sistema operativo para supervisar el comportamiento o modificar la función de una aplicación u otro componente. También se utiliza ampliamente en los programas de evaluación comparativa, por ejemplo la medición de las imágenes por segundo en juegos en 3D, donde la salida y la entrada se realiza mediante hooking.

Hooking también puede ser utilizado por código malicioso. Por ejemplo, los rootkits, piezas de software que tratan de hacerse invisibles simulando la salida de llamadas de la interfaz de programación de aplicaciones que de otra manera revelarían su existencia, usan a menudo técnicas de hooking. Un wallhack es otro ejemplo de funcionalidad útil que puede provenir de técnicas de hooking. Se hace interceptando llamadas de función en un juego de computadora y alterando lo que se muestra al jugador para permitirles obtener una ventaja injusta sobre otros jugadores.

Métodos editar

Normalmente los hooks se insertan mientras el software ya se está ejecutando, pero el hooking es una táctica que también se puede emplear antes de que se inicie la aplicación.

Modificación física editar

Mediante la modificación física de un archivo ejecutable o una biblioteca antes de que una aplicación se ejecute a través de técnicas de ingeniería inversa, también puede lograr un hooking. Normalmente se utiliza para interceptar llamadas de función para supervisarlas o reemplazarlas por completo.

Por ejemplo, utilizando un desensamblador, se puede encontrar el punto de entrada de una función dentro de un módulo. A continuación, puede ser modificado para cargar dinámicamente otro módulo de biblioteca y luego ejecutar los métodos deseados dentro de esa biblioteca cargada. Si es aplicable, otro enfoque relacionado mediante el cual se puede conseguir el hooking es alterando la tabla de importación de un ejecutable. Esta tabla puede modificarse 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 la función de hooking es mediante la interceptación de llamadas de función a través de una biblioteca de envoltura. Al crear un contenedor, crea su propia versión de una biblioteca que una aplicación carga, con todas las mismas funcionalidades de la biblioteca original que reemplazará. Es decir, todas las funciones que son accesibles son esencialmente las mismas entre el original y el reemplazo. Esta biblioteca de envoltura puede diseñarse para llamar a cualquiera de la funcionalidad de la biblioteca original o reemplazarla por un conjunto totalmente nuevo de lógica.

Modificación del tiempo de ejecución editar

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

Cuando no se proporciona tal funcionalidad, una forma especial de hooking emplea la interceptación de las llamadas a la función de biblioteca realizadas por un proceso. El hooking 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 vector de interrupción o la tabla de descriptor de importación se pueden modificar en memoria. Esencialmente, estas tácticas emplean las mismas ideas que las de la modificación física, pero en cambio alteran las instrucciones y las estructuras localizadas en la memoria de un proceso una vez que ya está en ejecución.

Ejemplos editar

Hooking de la tabla de métodos virtuales editar

Cada vez que una clase define una función virtual (o método), la mayoría de los compiladores agregan una variable de miembro oculta a la clase que apunta a una tabla de método virtual (VMT o Vtable). Este VMT es básicamente una matriz de punteros a funciones (virtuales). En tiempo de ejecución de estos indicadores se establecerán para que apunte a la función correcta, porque en tiempo de compilación, que aún no se sabe si la función de base ha de ser llamado o un derivado implementada por una clase que hereda de la clase base.

API/Función hooking/Interception usando JMP Instruction editar

Es un método de hooking de API/función que se anuda sobrescribiendo los primeros seis bytes de una función de destino con una instrucción JMP en 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 DLL injection. Utilizando una copia de seguridad de la función original, uno podría restaurar los seis primeros bytes de nuevo para que la llamada no se interrumpa.

Hooking interno de IAT editar

Este código siguiente muestra cómo conectar funciones que se importan de otro módulo. Esto se puede utilizar para conectar funciones en un proceso diferente del proceso de llamada. Para esto, el código debe ser compilado en un archivo DLL, luego cargado en el proceso de destino utilizando cualquier método de DLL injection. La ventaja de este método es que es menos detectable por el software antivirus y/o software antitrampa, podría convertirse en un hook externo que no hace uso de las llamadas maliciosas. El encabezado Portable Executable contiene la tabla de direcciones de importación (IAT), la cual puede manipularse.

Véase también editar

Referencias editar