Red de conocimiento informático - Conocimientos de programación - ¿Qué son los ganchos del sistema?

¿Qué son los ganchos del sistema?

De hecho, el sistema Windows se basa en un mecanismo basado en eventos. Para decirlo sin rodeos, todo el sistema se implementa mediante la transmisión de mensajes. El gancho es una interfaz de sistema muy importante en el sistema Windows. Se puede utilizar para interceptar y procesar mensajes enviados a otras aplicaciones para completar funciones que son difíciles de lograr con aplicaciones normales.

Se puede ver que se pueden lograr muchas funciones especiales y útiles mediante el uso de ganchos. Por lo tanto, es necesario que los programadores avanzados dominen los métodos de programación de ganchos.

Hay muchos tipos de ganchos y cada gancho puede interceptar y procesar los mensajes correspondientes. Por ejemplo, los ganchos de teclado pueden interceptar mensajes de teclado y los ganchos de shell pueden interceptar, iniciar y cerrar mensajes de aplicaciones, etc.

Como se muestra en la figura, se muestra un diagrama esquemático de un enlace global.

El enlace WH_GETMESSAGE se utiliza en el programa de ejemplo. Este enlace monitorea los mensajes de Windows entregados a la cola de mensajes.

Los ganchos se pueden dividir en ganchos de subprocesos y ganchos de sistema. Los ganchos de subprocesos monitorean los mensajes de eventos de subprocesos específicos y los ganchos del sistema monitorean los mensajes de eventos de todos los subprocesos del sistema. Debido a que los enlaces del sistema afectan a todas las aplicaciones del sistema, las funciones de enlace deben colocarse en una biblioteca de vínculos dinámicos (DLL) independiente. 1. El programa de enlace de Windows requiere el uso de varias funciones API en el SDK. Los prototipos y descripciones de estas funciones se enumeran a continuación:

hhook setwindowshookex(int ​​​​idhook, hook_proc lpfn, hinstance hmod, dword dwthreadid);

Las descripciones de los parámetros son las siguientes:

idhook: tipo de gancho

lpfn: dirección de la función de procesamiento del gancho

hmod: identificador del módulo que contiene la función de gancho

dwthreadid: monitoreo hilo de gancho

Descripción de la función: La función colgará un gancho del tipo especificado por idhook en el sistema, monitoreará y procesará los mensajes específicos correspondientes.

bool unhookwindowshookex(hhook hhk);

Descripción de la función: La función deshará el gancho especificado por hhk.

lresult callnexthookex(hhook hhk, int ncode, wparam wparam, lparam lparam);

Descripción de la función: la función pasa el mensaje hacia abajo y el siguiente proceso de enlace interceptará este mensaje.

2. Dado que el procesamiento de enlaces implica problemas de dirección de datos entre módulos y procesos, la situación general es integrar el enlace en una biblioteca de enlaces dinámicos (dll). Hay tres formas de DLL de MFC en VC para elegir, a saber, Regular vinculado estáticamente a DLL de MFC (). enlace estático estándar MFC DLL), Regular utilizando el MFC DLL compartido (enlace dinámico estándar MFC DLL) y Extensión MFC DLL (extensión MFC DLL). El primer tipo de DLL vincula el código MFC utilizado en la DLL durante la compilación y no requiere el soporte de otras bibliotecas de vínculos dinámicos de MFC al ejecutar el programa, pero es de mayor tamaño; el segundo tipo de DLL se vincula dinámicamente a la clase MFC; biblioteca en tiempo de ejecución, por lo tanto, es de menor tamaño, pero depende del soporte de la biblioteca de clases de enlace dinámico MFC, tanto los programas MFC como los programas Win32 pueden utilizar ambas DLL. El tercer tipo de DLL también está vinculado dinámicamente, pero como extensión de la biblioteca de clases MFC, solo puede ser utilizado por programas MFC.

Además, se debe configurar un segmento de datos globales para compartir datos para almacenar algunas variables globales y conservar el estado cuando ocurrió el último evento de mensaje de enlace.

3. Las funciones de entrada y salida de Win32 DLL son DLLMain.

Esta función se llamará cada vez que un proceso o subproceso cargue y descargue una DLL. Su prototipo es:

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); identificador de descarga de subprocesos), DLL_PROCESS_DETACH (descarga de procesos). En la función DLLMain, puede juzgar el valor de este parámetro pasado y realizar el trabajo de inicialización o limpieza necesario en la DLL en función de diferentes valores de parámetros. Dado que en el entorno Win32 los espacios de todos los procesos son independientes entre sí, esto reduce la interacción entre aplicaciones, pero aumenta enormemente la dificultad de programación. Cuando un proceso carga dinámicamente una DLL, el sistema asigna automáticamente la dirección de la DLL al espacio privado del proceso y también copia una copia de los datos globales de la DLL al espacio del proceso. Cada proceso posee los mismos datos globales de su DLL. Los valores no son necesariamente los mismos. Cuando la memoria DLL se asigna al espacio de proceso, cada proceso tiene su propia copia de la memoria global. Cada nuevo proceso que carga la DLL reinicializa esta área de memoria, lo que significa que el proceso ya no puede compartir exclusivamente la DLL. Por lo tanto, si desea compartir datos entre múltiples procesos en un entorno Win32, debe realizar las configuraciones necesarias. Un método consiste en separar los datos que deben compartirse por separado, colocarlos en un segmento de datos independiente, establecer el atributo del segmento en compartido y crear una DLL de memoria compartida. Al crear un programa de enlace, el procesamiento del enlace debe integrarse en la biblioteca de enlaces dinámicos, por lo que es necesario crear dos proyectos en la rutina.

1. Biblioteca de enlaces dinámicos de procesamiento de enlaces

(1) Seleccione mfc appwizard(dll) para crear un nuevo proyecto y asígnele el nombre "espía".

(2) Seleccione el tipo dll de extensión mfc.

(3) Cree un nuevo archivo de encabezado, llamado "hook.h", modifique su código de la siguiente manera:

extern C LRESULT CALLBACK mouseproc(int code, WPARAM wparam, LPARAM lparam ); //Función de procesamiento de gancho

extern C bool WINAPI starthook(); //Iniciar la función de gancho

extern C bool WINAPI stophook() //Cancelar la función de gancho

extern C int WINAPI getresultl(); //Función para obtener el número de clics del botón izquierdo

extern C int WINAPI getresultr() //Función para obtener el número de clics del botón derecho clics

(4) Modifique el código del programa spy.cpp de la siguiente manera:

#include hook.h //Incluir gancho de archivo de encabezado

#pragma data_seg(publicdata ) //Definir segmento de datos globales

HHOOK hhook=NULL; //Manejador de gancho

HINSTANCE pinstance=NULL; //Manejador de módulo de gancho

UINT mouseclickl= 0; //Variable que registra el número de clics del botón izquierdo

UINT mouseclickr=0; //Registra el número de clics del botón derecho

#pragma data_seg()

extern C int APIENTRY

DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)

{ if (dwReason == DLL_PROCESS_ATTACH)

{…… //Omitido parte del código generado por la máquina

new CDynLinkLibrary(SpyDLL);

pinstance=hInstance; //Obtener el identificador del módulo

}

…… ;

}

extern C LRESULT CALLBACK mouseproc(int code, WPARAM wparam, LPARAM lparam)//función de procesamiento de gancho

{

if (codelt; 0) //Si código<0, llama a callnexthookex directamente para regresar

devuelve CallNextHookEx(hhook, code, wparam, lparam);

if(wparam== WM_LBUTTONDOWN)

{ mouseclickl; //Registra el número de clics izquierdo del mouse}

if(wparam==WM_RBUTTONDOWN)

{ mouseclickr; //Registra el número de clics derecho del mouse}

return CallNextHookEx(hhook, code, wparam, lparam);

}

extern C bool WINAPI starthook()//Iniciar la función de enlace

{

hhook=SetWindowsHookEx(WH_MOUSE, mou

seproc, pinstance, 0); //Conectar

if(hhook!=NULL)

devuelve verdadero;

de lo contrario, devuelve falso;

}

extern C bool WINAPI stophook() //Cancelar función de gancho

{ return UnhookWindowsHookEx(hhook); //Cancelar gancho}

extern C int WINAPI getresultl()//Devuelve el número de clics izquierdo del ratón

{ return mouseclickl;}

extern C int WINAPI getresultr()//Devuelve el número de clics derecho del ratón

{ return mouseclickr;}

(5) Modifique el código del programa spy.def de la siguiente manera:

exportaciones

stophook @2

starthook @1

getresultl @3

getresultr @4

(6) Compile el proyecto y genere el archivo spy.dll y documento spy.lib. 2. Cree una aplicación usando ganchos

(1) Genere un proyecto de archivo ejecutable (exe) de un solo documento.

(2) Modifique el menú principal en el recurso y agregue un elemento de menú "Monitor" con tres elementos de submenú debajo, a saber, "Inicio", "Deshacer" y "Eliminar".

(3) Agregue el archivo spy.lib al proyecto.

(4) Modifique las funciones de respuesta de comando de los elementos del menú "Inicio", "Deshacer" y "Eliminar" de la siguiente manera:

#include E:\DevStudio\MyProjects\spy \hook .h //La ruta puede ser diferente

void CMainFrame::OnMenuitem32771() //Función de respuesta del elemento del menú "Inicio"

{ starthook() }

void CMainFrame::OnMenuitem32772() //Función de respuesta para el elemento del menú "Cancelar"

{ stophook();}

void CMainFrame::OnMenuitem32773() //"Eliminar" función de respuesta del elemento del menú

{ int resultl=getresultl();

int resultr=getresultr();

char buffer[80 ];

wsprintf(búfer, durante la ejecución del programa, hace clic con el botón izquierdo del mouse d veces, hace clic con el botón derecho d veces!, resultl, resultr);

: MessageBox( this-gt; m_hWnd, buffer, message, MB_OK);

}

Compile este proyecto y coloque spy.dll en el directorio del archivo ejecutable generado para ejecutar el programa. Cuando se ejecute, seleccione el elemento del menú "Inicio" en el menú "Supervisar" y el enlace comenzará a funcionar, monitoreando la actividad del mouse, seleccione el elemento del menú "Deshacer" y el sistema cancelará el enlace, seleccione el menú "Eliminar"; elemento, y el programa informará el número de veces que el usuario hizo clic en los botones izquierdo y derecho del mouse, respectivamente, durante el monitoreo.