Seguimos con la segunda entrega de esta serie....Una de las formas más sencillas de realizar la inyección de DLL es mediante el uso de la API [Enlace externo eliminado para invitados]. Los ganchos o hooks, en la terminología de Windows, son mecanismos que permiten a las aplicaciones interceptar eventos particulares del sistema. La instalación de un gancho es un proceso de dos partes.

Primero, debe definir e implementar un procedimiento de gancho* para el tipo de gancho que instalará.

Este procedimiento debe estar en una DLL**, ya que la DLL se inyectará en los procesos de destino. A continuación, llama a la API SetWindowsHookEx para instalar el gancho en un subproceso específico o en todos los subprocesos.* A lo largo de esta sección se utilizará el término “procedimiento de gancho”. Un procedimiento es simplemente otro nombre para una función, pero usaré el término "procedimiento de enlace" específicamente cuando me refiero a la función que manejará los eventos de enlace.** Técnicamente, si está instalando un enlace global o un procedimiento de enlace en un subproceso de su propio proceso, no es necesario que esté en una DLL. Este no será el caso de ninguno de los ejemplos presentados en esta serie, ya que estamos interesados ​​en inyectar archivos DLL en otros procesos.

Código: Seleccionar todo

HHOOK WINAPI SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId);
El primer parámetro corresponde al tipo de gancho que se instalará. Hay muchos tipos diferentes de enlaces para eventos del sistema; hay enlaces para monitorear los mensajes que se envían a procedimientos de ventana, enlaces de cola de mensajes, enlaces de teclado, enlaces de mouse y más.

Estos tienen valores predefinidos, como WH_CALLWNDPROCWH_GETMESSAGEWH_KEYBOARD, etc. Cada tipo de enlace tendrá una función de procedimiento de enlace correspondiente asociada. Esta es la función que se invocará cuando el enlace capture un evento del sistema. Por ejemplo, se debe implementar un procedimiento de enlace para enlaces de teclado (WH_KEYBOARD) con el siguiente prototipo:

Código: Seleccionar todo

LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam);
El segundo y tercer parámetro de SetWindowsHookEx son un puntero al procedimiento de enlace y la dirección base de la DLL que contiene el procedimiento de enlace. . En tiempo de ejecución, estos se pueden obtener cargando la biblioteca con [Enlace externo eliminado para invitados] y llamando a [Enlace externo eliminado para invitados] en el procedimiento del gancho. Dado que el puntero al procedimiento de enlace se recupera con GetProcAddress, el procedimiento de enlace se debe exportar explícitamente desde la DLL para que se pueda encontrar. El parámetro final de SetWindowsHookEx es el ID del hilo que se asociará con el gancho. La DLL que contiene el procedimiento de enlace se inyectará en el proceso propietario de este hilo. La API SetWindowsHookEx le permite conectar todos los subprocesos en ejecución si pasa un valor de cero (0) para este parámetro.Ganchos para teclado o Keyboard HooksPara el ejemplo, usaremos un gancho de teclado (WH_KEYBOARD). Comencemos creando la DLL que se inyectará. El código de la DLL se muestra a continuación:

Código: Seleccionar todo

extern "C" {

__declspec(dllexport) LRESULT CALLBACK KeyboardProc(
   int nCode, WPARAM wParam, LPARAM lParam) { 

   if (nCode != HC_ACTION) {
       return CallNextHookEx(nullptr, nCode, wParam, lParam);
   }

    // Key is up
   if ((lParam & 0x80000000) || (lParam & 0x40000000)) {
       MessageBoxA(nullptr, "Hello World!",
           nullptr, 0);
   } return CallNextHookEx(nullptr, nCode, wParam, lParam);
}

}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
    LPVOID lpvReserved) {

    return TRUE;
}
El código de la DLL que se inyectará.

Dado que se está instalando un enlace de teclado, es necesario que haya un procedimiento de enlace que maneje los eventos apropiados. El procedimiento de enlace [Enlace externo eliminado para invitados] hace precisamente eso; es la función que se llamará cuando haya un evento de teclado para procesar. La función KeyboardProc se exporta mediante la palabra clave [Enlace externo eliminado para invitados], lo que la convierte en accesible para importar desde otras aplicaciones.

Puede observar que la función KeyboardProc también está dentro de una “C” externa bloque. Esto obliga al compilador a realizar enlaces C para funciones dentro del bloque, lo que efectivamente evita que el compilador realice cualquier [Enlace externo eliminado para invitados] en el nombre de la función exportada. Si su función exportada está fuera de este bloque, entonces probablemente no se encontrará cuando llame a GetProcAddress para obtener un puntero a ella, debido a la alteración de nombres.

La función KeyboardProc mostrará un mensaje "¡Hola mundo!" cuadro de mensaje en la pantalla en caso de que se presione una tecla. La función comienza verificando si el estado indica que hay información sobre el mensaje de pulsación de tecla.

De lo contrario, se llama a [Enlace externo eliminado para invitados] para pasar el mensaje por la cadena de enlace. Si hay información sobre la pulsación de la tecla, la función verifica si el mensaje indica que la tecla está en la posición levantada o liberada. Si es así, se muestra el cuadro de mensaje.Obtener la identificación del hilo de destino o thread idDespués de crear la DLL, puede pasar a crear el cargador para ella. La lógica del cargador es bastante sencilla. Como se describió anteriormente, configurar un enlace de Windows implica obtener los punteros relevantes y llamar a SetWindowsHookEx para realizar la instalación.

 

Código: Seleccionar todo

std::pair<DWORD, DWORD> GetTargetProcessAndThreadId(const std::string& windowTitle) {

DWORD processId{};
const auto threadId{ GetWindowThreadProcessId(
FindWindowA(nullptr, windowTitle.c_str()),
&processId) };
if (threadId == 0 || processId == 0) {
PrintErrorAndExit("GetWindowThreadProcessId");
}

return std::make_pair(processId, threadId);
}

int main(int argc, char* argv) {

const auto injectingLibrary{ LoadLibraryA("SetWindowsHookExDll.dll") };
if (injectingLibrary == nullptr) {
PrintErrorAndExit("LoadLibraryA");
}

const auto hookFunctionAddress{ reinterpret_cast<HOOKPROC>(
GetProcAddress(injectingLibrary, "KeyboardProc")) };

if (hookFunctionAddress == nullptr) {
std::cerr << "Could not find hook function" << std::endl;
return -1;
}

const auto threadId{ GetTargetProcessAndThreadId(
"Untitled - Notepad").second };

const auto hook{ SetWindowsHookEx(WH_KEYBOARD,
hookFunctionAddress, injectingLibrary, threadId) };
if (hook == nullptr) {
PrintErrorAndExit("SetWindowsHookEx");
}

std::cout << "Hook installed. Press enter to remove hook and exit."
<< std::endl;

std::cin.get();

UnhookWindowsHookEx(hook);

return 0;
}
Un programa que inyecta una DLL llamada SetWindowsHookExDll.dll en un proceso.

El cargador anterior comienza cargando SetWindowsHookExDll.dll en la memoria con una llamada a LoadLibraryA< /span>KeyboardProc llamando a GetProcAddress. El cargador continúa para obtener el ID del hilo de otro proceso: el Bloc de notas en este caso. El ID del hilo se obtiene buscando una ventana con el título "Sin título - Bloc de notas", que es el título predeterminado cuando abre la aplicación por primera vez. Una vez que se obtiene el ID del hilo, se puede instalar el gancho. Se llama a la función SetWindowsHookEx , pasando WH_KEYBOARD para indicar que el gancho El tipo será un enlace de teclado, junto con el puntero al procedimiento de enlace, la dirección base de SetWindowsHookExDll.dll y el ID del hilo del Bloc de notas.Ejecutando la demostraciónNota: si está utilizando el nuevo Bloc de notas para UWP que se encuentra en la última versión de Windows, deberá [Enlace externo eliminado para invitados] para que la demostración funcione.Los proyectos [Enlace externo eliminado para invitados] y [Enlace externo eliminado para invitados] proporcionan la implementación completa. que se presentó en esta sección. Para probar esto localmente, cree los proyectos DLL y del cargador. Después de una compilación exitosa, inicie el Bloc de notas y luego la aplicación de carga. Cambie a la ventana del Bloc de notas y presione cualquier tecla en el cuadro de texto del Bloc de notas. Al hacer esto, deberías ver un mensaje "¡Hola mundo!" cuadro de mensaje emergente desde dentro del proceso del Bloc de notas.

[Enlace externo eliminado para invitados]
Imagen
El cuadro de mensaje que aparece después de presionar una tecla.

Si minimiza la ventana del Bloc de notas y escribe en otro lugar, no verá ningún cuadro de mensaje. Esto muestra que el enlace se instaló exitosamente en el proceso de destino; lo que significa que la DLL que escribió se inyectó en el proceso y que su procedimiento de enlace se invocó en el contexto del espacio de direcciones del proceso de destino. Puedes verificar esto abriendo [Enlace externo eliminado para invitados] y buscando notepad.exe procesar y navegar a su pestaña Módulos.

[Enlace externo eliminado para invitados]
Imagen
La DLL SetWindowsHookExDll.dll se ha cargado en notepad.exe.

Cuando haya terminado, regrese al cargador y presione la tecla Enter para salir. Hacer esto llamará a [Enlace externo eliminado para invitados] para eliminar el enlace del proceso del Bloc de notas. Si se siente particularmente valiente, puede pasar cero (0) como parámetro de ID del hilo a SetWindowsHookEx y observar lo que sucede.

Bueno, pues hasta aqui esta segunda parte... Como siempre,espero que le sirva a alguien..

Saludos a tod@s...

cLn
Imagen


Solo lo mejor es suficiente...
Responder

Volver a “Manuales”