Hi guys.
I want to write a keylogger which logs all strings I copy via <CTRL>+<C>
My problem is that I loose track of interessting links or code-snippets when overdoing it.

So I want a basic keylogger which notices every hotkey event and copies the content in the clipboard into a file.
The problem is that the clipboard doens't copy a string as I block the hotkey with my keyhook.
That means that the last copied string stays in the clipboard and as long as my programm runs I can't save new content with the hot key, as the event will not be passed to windows.
I have to pass the event to windows but I don't know how.

Here's the code, thanks for advice.

#include <windows.h>
#include <fstream>
#include <iostream>
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

#define MY_HOTKEYID     100

/*  Make the class name into a global variable  */
char szClassName[ ] = "kl";

char* GetClipBoard(void)
{
    HANDLE clip;
    if (OpenClipboard(NULL))
        clip = GetClipboardData(CF_TEXT);

    return (char*)clip;
}

HANDLE SetClipboard(std::string cpy)
{
    const char* output = cpy.c_str();

    const size_t len = strlen(output) + 1;
    HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
    memcpy(GlobalLock(hMem), output, len);
    GlobalUnlock(hMem);
    OpenClipboard(0);
    EmptyClipboard();
    SetClipboardData(CF_TEXT, hMem);
    CloseClipboard();

    return 0;

}

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{

    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "kl",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    //  ShowWindow (hwnd, nCmdShow);
    RegisterHotKey(hwnd,MY_HOTKEYID,MOD_CONTROL,0x44);
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    UnregisterHotKey(hwnd,MY_HOTKEYID);

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        case WM_HOTKEY :
            {
                // Nope. Windows doesn't recieved any <Ctrl><c> hotkey, hence there is no new stuff in the clipboard
                // How to pass the event to windows then, before checking the clipboard again ?
                std::string help = GetClipBoard();

                std::cout << "Clip : " << help;

                if (help.size() < 100)
                {
                    std::ofstream tempfile("Records.txt", std::ios::app);

                    SYSTEMTIME time;
                    GetLocalTime(&time);

                    tempfile << "<" << help << ">";
                    tempfile << "Logging at " << time.wHour << ":" << time.wMinute << ":" << time.wSecond <<  " on " << time.wDay << "." << time.wMonth << "." <<  time.wYear << " (DD.MM.YYYY)\n\n";

                    tempfile.close();
                }
            }

        default:                      /* for messages that we don't deal with */
            return DefWindowProc (0, message, wParam, lParam);
    }

    return 0;
}

Recommended Answers

All 2 Replies

Instead of hooking keystrokes why not use the clipboard api to get notifications when the clipboard changes? (clipboard)

because that could be triggered by others application which modify the clipboard.
i cannot help you OP, sorry

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.