[GUIDE] How to write a simple Keyboard Hook menu

User Tag List

Results 1 to 6 of 6
  1. #1
    Kekke's Avatar Member
    Reputation
    10
    Join Date
    Jan 2009
    Posts
    30
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [GUIDE] How to write a simple Keyboard Hook

    Hello everyone, please notice that this is my first tutorial I have ever wrote so please give me lots of feedback of what I could have done better.


    First of all, what is a keyboard hook?


    A keyboard hook is a windows hook that will hook the keyboard, a windows hook is something that will 'trap' the windows events.
    A windows hook works under the skin of applications.
    As soon as a event is sent to the window you hooked, you will recieve the message first, meaning you could modify, log or delete it.

    I will show you how to delete the message.


    How do a keyboard hook look?


    A keyboard hook does most often exist within a DLL (Dynamically Linked Library) but in some cases they don't have to (WH_KEYBOARD_LL).
    The keyboard hook we will use is called WH_KEYBOARD and is not global by default(?).

    This is how our almighty DLL will look

    Code:
    #include "dll.h"
    #include <windows.h>
    
    extern "C" __declspec (dllexport) LRESULT __stdcall KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
    {
    
        if(code == HC_ACTION) //if the wparam/lparam contains any data
        {
            if(wParam == VK_RETURN) //if wparam (which is a vk) is return
            {
                return 1; //return 1, which means that the key event wont be processed
            }
        }
    
        return CallNextHookEx(0, code, wParam, lParam);
    }
    
    extern "C" BOOL __declspec (dllexport) __stdcall DllMain (HINSTANCE hInst,
                           DWORD reason,
                           LPVOID reserved)
    {
        switch (reason)
        {
          case DLL_PROCESS_ATTACH:
                MessageBox(HWND_DESKTOP, "Attached!", "Yesh", MB_OK);
            break; //let us know we attached the dll.
    
          case DLL_PROCESS_DETACH:
            break;
    
          case DLL_THREAD_ATTACH:
            break;
    
          case DLL_THREAD_DETACH:
            break;
        }
        return TRUE;
    }
    The only winAPI we use in our DLL is a keyboardproc and it looks like this (taken from msdn):

    Code:
    LRESULT CALLBACK KeyboardProc(      
        int code,
        WPARAM wParam,
        LPARAM lParam
    );
    Where code, is a code that we use to see if there is any data on wParam or lParam.

    The WPARAM specifies the Virtual Key code.
    The lParam Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag. we do not have to use this.


    Why don't you show us a global hook?


    1 reason, I don't want any script-kiddie to copy paste the code and then have his own keylogger which he can use to steal illegal data.
    I do not in any way support stealing private people.
    The way I show you, will only recieve keyboard events in our specified process.


    How do I load the correct DLL into the correct process?


    This can be done in a few ways, first I will show you the easiest way.

    What we want to do is inject the dll in a thread ID, I will choose tibias thread id.

    Of course, this can also be done in a few ways (finding the thread ID) but here is one.

    We use the CreateToolHelp32Snapshot API to get a snapshot of all running processes.
    after that, we need to find the PID of our application so that we can find the pid in the snapshot and compare, if it matches we got our thread id!

    We use GetWindowThreadProcessId API to find the pid address.
    It takes 2 parameters first is a HANDLE to the window, the second is a pointer to a variable which recieves the pid (if it finds it).

    Then loop through the snapshot using first Thread32First and then Thread32Next, until we find our thread id.

    Code:
        HANDLE Snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    
        THREADENTRY32 te;
        te.dwSize = sizeof(te);
    
        unsigned long tid = 0;
        DWORD pid;
    
        GetWindowThreadProcessId(::FindWindow("TibiaClient", 0), &pid);
    
        if(Thread32First(Snap, &te))
        do
        {
            if (te.th32OwnerProcessID == pid)
                tid = te.th32ThreadID;
        }
        while (Thread32Next(Snap, &te));
    
        if(tid == 0)
        {
            cout << "I could not find the thread id :(\n";
            exit(1);
        }
    Now that we have the thread id, we can go ahead loading the library and then installing the hook.


    Installing the hook


    What we need to do now is to load our library using the LoadLibrary API.
    It will look something like, LoadLibrary("ourdll.dll");.

    After that, we need to get the address to our keyboardproc and we can do that easily by using the GetProcAddress API.

    And then we can just set the hook using the SetWindowsHookEx with our proc and the thread ID we got before.
    We also call a MessageBox after we installed our hook so that it will not unhook immediately.

    Code:
        HINSTANCE hDll = LoadLibrary("Keyboardhooktest.dll");
    
        if(hDll == NULL)
        {
            cout << "I could not find the DLL :(\n";
            exit(1);
        }
    
        HOOKPROC KeyboardProc = reinterpret_cast<HOOKPROC>(GetProcAddress(hDll, "KeyboardProc@12"));
    
        if(KeyboardProc == NULL)
        {
            cout << "I could not find the address of the proc :(\n";
            exit(1);
        }
    
        HHOOK hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hDll, tid);
    
        if(hook == NULL)
        {
            cout << "I could not set the hook :(\n";
            exit(1);
        }
    
        MessageBox(HWND_DESKTOP, "H", "g", MB_OK);
    
        UnhookWindowsHookEx(hook);
    That is it folks, a non-global keyboard hook made easy.

    Have any questions?
    Contact me at Henric-Johansson at hotmail.com

    full code:

    Code:
    #include <iostream>
    #include <windows.h>
    #include <tlhelp32.h>
    
    using namespace std;
    
    int main()
    {
        HANDLE Snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    
        THREADENTRY32 te;
        te.dwSize = sizeof(te);
    
        unsigned long tid = 0;
        DWORD pid;
    
        GetWindowThreadProcessId(::FindWindow("TibiaClient", 0), &pid);
    
        if(Thread32First(Snap, &te))
        do
        {
            if (te.th32OwnerProcessID == pid)
                tid = te.th32ThreadID;
        }
        while (Thread32Next(Snap, &te));
    
        if(tid == 0)
        {
            cout << "I could not find the thread id :(\n";
            exit(1);
        }
    
        HINSTANCE hDll = LoadLibrary("Keyboardhooktest.dll");
    
        if(hDll == NULL)
        {
            cout << "I could not find the DLL :(\n";
            exit(1);
        }
    
        HOOKPROC KeyboardProc = reinterpret_cast<HOOKPROC>(GetProcAddress(hDll, "KeyboardProc@12"));
    
        if(KeyboardProc == NULL)
        {
            cout << "I could not find the address of the proc :(\n";
            exit(1);
        }
    
        HHOOK hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hDll, tid);
    
        if(hook == NULL)
        {
            cout << "I could not set the hook :(\n";
            exit(1);
        }
    
        MessageBox(HWND_DESKTOP, "H", "g", MB_OK);
    
        UnhookWindowsHookEx(hook);
    }
    Please give me feedback, Kekke.

    [GUIDE] How to write a simple Keyboard Hook
  2. #2
    XinuX's Avatar Contributor
    Reputation
    129
    Join Date
    Apr 2007
    Posts
    583
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice copy paste
    How To Write A Simple Keyboard Hook - Critical Security.NET

    [EDIT] Damn, really sorry =P didn't see you made it ^^
    Last edited by XinuX; 01-09-2009 at 11:28 AM.

  3. #3
    arigity's Avatar Banned
    Reputation
    49
    Join Date
    Dec 2007
    Posts
    548
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by XinuX View Post
    take a look at who made that thread.

  4. #4
    Kekke's Avatar Member
    Reputation
    10
    Join Date
    Jan 2009
    Posts
    30
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    lol :P yeah I made it for them first but thought I'd share it here too..

  5. #5
    streppel's Avatar Active Member
    Reputation
    77
    Join Date
    Mar 2007
    Posts
    196
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thanks,this will help me a lot i think

  6. #6
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1356
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No offense but as far as correct programming practices for Windows go (and to a lesser extent C++ in general) that code is pretty bad.

Similar Threads

  1. Replies: 51
    Last Post: 08-09-2008, 09:36 PM
  2. [Guide] How to make a simple web browser
    By Viter in forum Programming
    Replies: 13
    Last Post: 06-01-2008, 05:23 PM
  3. Guide: How to write a guide
    By Debt in forum World of Warcraft Guides
    Replies: 18
    Last Post: 11-03-2007, 07:04 PM
  4. GUIDE: How to write Exploration Guides
    By Fault in forum World of Warcraft Exploration
    Replies: 4
    Last Post: 12-31-2006, 04:07 AM
  5. [Guide] How hunters farm tendriss in DM
    By KuRIoS in forum World of Warcraft Guides
    Replies: 1
    Last Post: 05-11-2006, 10:50 AM
All times are GMT -5. The time now is 01:57 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search