Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Dev C++ systemwide hook

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Reak
I post too much
Reputation: 0

Joined: 15 May 2007
Posts: 3496

PostPosted: Fri Nov 28, 2008 4:46 pm    Post subject: Dev C++ systemwide hook Reply with quote

Hey,

I read a tutorial about system-wide hooks and here's the code:

dllmain.cpp
Code:
/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <windows.h>

// Globale Variablen
HHOOK g_hMouseHook SHARED = NULL; 
HINSTANCE g_hInst SHARED = NULL;



BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    g_hInst = hInst;
    return TRUE;
}

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < 0)
        return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
    if(nCode == HC_ACTION)
    {
        if ( (wParam == WM_LBUTTONDOWN)||(wParam == WM_NCLBUTTONDOWN) )
        {
            MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT*)lParam;
            HWND caller = FindWindow("Pipette", NULL);
            if(caller != NULL)
                PostMessage(caller, WM_USER+123, 0, MAKELPARAM(mhs->pt.x, mhs->pt.y));
        }
    }
    return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
}

extern "C" DLLIMPORT BOOL InstallHook()
{
    if(g_hMouseHook != NULL)
        return TRUE;
       
    g_hMouseHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseProc, g_hInst, 0);
   
    if(g_hMouseHook == NULL)
        return FALSE;
    return TRUE;
}



extern "C" DLLIMPORT BOOL UninstallHook()
{
    if(g_hMouseHook != NULL)
    {
        UnhookWindowsHookEx(g_hMouseHook);
        g_hMouseHook = NULL;
    }
    return TRUE;
}


dll.h

Code:
#ifndef _DLL_H_
#define _DLL_H_

#include <windows.h>

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */

#define SHARED __attribute__((section(".shr"), shared))
DLLIMPORT bool InstallHook();
DLLIMPORT bool UninstallHook();
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);
#endif



But if I do InstallHook it always returns FALSE because SetWindowsHookEx fails.
But why?
Back to top
View user's profile Send private message
hcavolsdsadgadsg
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5801

PostPosted: Fri Nov 28, 2008 5:26 pm    Post subject: Reply with quote

GetLastError
Back to top
View user's profile Send private message
sloppy
Expert Cheater
Reputation: 0

Joined: 17 Aug 2008
Posts: 123

PostPosted: Fri Nov 28, 2008 10:19 pm    Post subject: Reply with quote

Your code seems to work fine for me.. I only removed the header crap and updated it to compile under visual studio,

DllMain.cpp
Code:
#include <windows.h>

#pragma comment(linker, "/section:.shared,rws")
#pragma data_seg(".shared")
   HHOOK g_hMouseHook = NULL;
#pragma data_seg()

HINSTANCE g_hInst = NULL;

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                  DWORD reason             /* Reason this function is being called. */ ,
                  LPVOID reserved          /* Not used. */ )
{
   g_hInst = hInst;
   return TRUE;
}

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
   if (nCode < 0)
      return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
   if(nCode == HC_ACTION)
   {
      if ( (wParam == WM_MOUSEMOVE)||(wParam == WM_NCMOUSEMOVE) )
      {
         MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT*)lParam;
         HWND caller = FindWindow("Pipette", NULL);
         if(caller != NULL)
            PostMessage(caller, WM_USER+123, 0, MAKELPARAM(mhs->pt.x, mhs->pt.y));
      }
   }
   return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
}

__declspec(dllexport) BOOL InstallHook()
{
   if(g_hMouseHook != NULL)
      return TRUE;

   g_hMouseHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseProc, g_hInst, 0);

   if(g_hMouseHook == NULL)
      return FALSE;
   return TRUE;
}

__declspec(dllexport) BOOL UninstallHook()
{
   if(g_hMouseHook != NULL)
   {
      UnhookWindowsHookEx(g_hMouseHook);
      g_hMouseHook = NULL;
   }
   return TRUE;
}

Created a simple app to test the hook,

WinMain.cpp
Code:
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>

#define ID_SETHOOK      101
#define ID_REMHOOK      102
#define ID_TEXT         201

__declspec(dllimport) BOOL InstallHook();
__declspec(dllimport) BOOL UninstallHook();

HINSTANCE g_hInst = NULL;

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
   static char szBuff[25];

   if (Msg == WM_USER+123)
   {
      sprintf_s(szBuff, sizeof(szBuff), " x: %d\r\n y: %d", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
      SetDlgItemText(hWnd, ID_TEXT, szBuff);
      return 0;
   }

   switch(Msg)
   {
   case WM_CREATE:
      {
         CreateWindowEx(NULL, "Button", "Install Hook",
            WS_BORDER | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
            20, 90, 140, 30, hWnd, (HMENU)ID_SETHOOK, g_hInst, NULL);
         CreateWindowEx(NULL, "Button", "Remove Hook",
            WS_BORDER | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
            20, 130, 140, 30, hWnd, (HMENU)ID_REMHOOK, g_hInst, NULL);
         CreateWindowEx(NULL, "Static", " x: ---\r\n y: ---", WS_BORDER | WS_CHILD | WS_VISIBLE,
            20, 25, 140, 45, hWnd, (HMENU)ID_TEXT, g_hInst, NULL);
         break;
      }
   case WM_COMMAND:
      {
         switch(LOWORD(wParam))
         {
         case ID_SETHOOK:
            InstallHook();
            break;
         case ID_REMHOOK:
            UninstallHook();
            break;
         }
         break;
      }
   case WM_CLOSE:
      DestroyWindow(hWnd);
      break;
   case WM_DESTROY:
      UninstallHook();
      PostQuitMessage(0);
      break;
   default:
      return DefWindowProc(hWnd, Msg, wParam, lParam);
   }
   return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   const char *szClassName = "Pipette";

   g_hInst = hInstance;
   WNDCLASSEX WndClass = {0};
   MSG Msg;

   WndClass.cbSize        = sizeof(WNDCLASSEX);
   WndClass.style         = CS_HREDRAW | CS_VREDRAW;
   WndClass.lpfnWndProc   = WndProc;
   WndClass.hInstance     = g_hInst;
   WndClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
   WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
   WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
   WndClass.lpszMenuName  = NULL;
   WndClass.lpszClassName = szClassName;
   WndClass.hIconSm       = WndClass.hIcon;

   if(!RegisterClassEx(&WndClass)) {
      MessageBox(0, "Error Registering Window!", "Error!", MB_ICONSTOP | MB_OK);
      return 0;
   }

   HWND hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, szClassName, "Hook Test",
      WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 190, 215,
      NULL, NULL, g_hInst, NULL);

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   while(GetMessage(&Msg, NULL, 0, 0))
   {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
   }
   return Msg.wParam;
}

You would be better off passing the caller window handle to your dll and store it as a shared global instead of using FindWindow. http://www.flounder.com/hooks.htm is a good reference. Oh and don't include the instance global in your shared data segment!

-edit-
As slovach mentioned, use GetLastError to find out why SetWindowsHookEx failed,
Code:
void DisplayLastError(LPTSTR szFunc)
{
   LPTSTR szMsg;
   DWORD dwError = GetLastError();

   FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL, dwError,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR)&szMsg, 0, NULL );

   MessageBox(NULL, szMsg, szFunc, 0);
   LocalFree(szMsg);
}

Code:
InstallHook();
DisplayLastError("InstallHook");

I'd guess it has something to do with permissions / vista.
Back to top
View user's profile Send private message
Reak
I post too much
Reputation: 0

Joined: 15 May 2007
Posts: 3496

PostPosted: Sat Nov 29, 2008 6:05 pm    Post subject: Reply with quote

Hey,

First off, thanks for your answers.
But yours isn't working either.
I used your DisplayLastError() function and it returned:
Nicht-lokaler Hook kann nicht ohne Modulhandle gesetzt werden.
means:
Cannot set non-local hook without a module handle..

I don't really get it =/
I've googled for it a bit but couldn't find anything.
Any idea?

Btw: I'm on WinXP Pro Admin account.

Current code:
Code:
#include <windows.h>
#include <stdio.h>

#pragma data_seg("Pipette")
   HHOOK g_hMouseHook = NULL;
#pragma data_seg()

HINSTANCE g_hInst = NULL;

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                  DWORD reason             /* Reason this function is being called. */ ,
                  LPVOID reserved          /* Not used. */ )
{
   g_hInst = (HINSTANCE)hInst;
   return TRUE;
}



LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
   LRESULT lResult = CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
    MessageBox(NULL, "...", "", 0);
   return lResult;
}

void DisplayLastError(LPTSTR szFunc)
{
   LPTSTR szMsg;
   DWORD dwError = GetLastError();

   FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL, dwError,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR)&szMsg, 0, NULL );

   MessageBox(NULL, szMsg, szFunc, 0);
   LocalFree(szMsg);
}

__declspec(dllexport) BOOL InstallHook()
{
   if(g_hMouseHook != NULL)
      return TRUE;

   g_hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, g_hInst, 0);
   DisplayLastError("SetWindowsHookEx");
   
   if(g_hMouseHook == NULL)
      return FALSE;
   return TRUE;
}

__declspec(dllexport) BOOL UninstallHook()
{
   if(g_hMouseHook != NULL)
   {
      UnhookWindowsHookEx(g_hMouseHook);
      g_hMouseHook = NULL;
   }
   return TRUE;
}
Back to top
View user's profile Send private message
rapion124
Grandmaster Cheater Supreme
Reputation: 0

Joined: 25 Mar 2007
Posts: 1095

PostPosted: Sat Nov 29, 2008 7:07 pm    Post subject: Reply with quote

Maybe if you read the API documentation, you would have realized that global hooks must be declared in a .DLL. Razz

Code:

The global hooks are a shared resource, and installing one affects all applications in the same desktop as the calling thread. All global hook functions must be in libraries. Global hooks should be restricted to special-purpose applications or to use as a development aid during application debugging. Libraries that no longer need a hook should remove its hook procedure.
Back to top
View user's profile Send private message
sloppy
Expert Cheater
Reputation: 0

Joined: 17 Aug 2008
Posts: 123

PostPosted: Sun Nov 30, 2008 3:55 am    Post subject: Reply with quote

^ What rapion said, how are you installing the hook? and does it reside in a dll? I thought it did.. so I'm a little confused on how you are implementing the hook. I can upload my test project if that helps.

MSDN wrote:
ERROR_HOOK_NEEDS_HMOD: A global hook is being set with a NULL hInstance parameter or a thread-specific hook is being set for a thread that is not in the setting application.
Back to top
View user's profile Send private message
Reak
I post too much
Reputation: 0

Joined: 15 May 2007
Posts: 3496

PostPosted: Sun Nov 30, 2008 4:16 am    Post subject: Reply with quote

It's a DLL ..
I know why it fails now.
It's because of the g_hInst.
It's always NULL for some reason, even though I'm setting it to the hInst in the DllMain().

I found a good source with an example of this in VC++. I edited a bit and it's working perfectly now. But I still want to figure out why my Devcpp one isn't working.
Also, I edited the DllMain() parameters to how they are in VC++:
Code:
BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                )
{
   g_hInst = (HINSTANCE)hModule;
   return TRUE;
}

But g_hInst is still NULL. any idea why?
Back to top
View user's profile Send private message
Flyte
Peanuts!!!!
Reputation: 6

Joined: 19 Apr 2006
Posts: 1887
Location: Canada

PostPosted: Sun Nov 30, 2008 4:55 am    Post subject: Reply with quote

Try compiling it in VC++, Dev C++ (well, MingW) fucks up dll files.
Back to top
View user's profile Send private message
sloppy
Expert Cheater
Reputation: 0

Joined: 17 Aug 2008
Posts: 123

PostPosted: Sun Nov 30, 2008 5:07 am    Post subject: Reply with quote

I'm not really sure sorry, but is it possible that DllMain is not being executed? try a message box test.

-edit-
Maybe this will help -> http://mirrors.zoreil.com/webclub.kcom.ne.jp/ma/colinp/win32/dll/make.html
Quote:
If you do not force DllMain to be a C function it will not be found by the call in the Mingw32 start up code, and the default DllMain in libmingw32.a will get called instead. If your initialization code doesn't seem to be called, and you are programming in C++, check that your DllMain function is either in a separate C source file or is forced to be a C function with extern "C".
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites