Link to home
Start Free TrialLog in
Avatar of craig_capel
craig_capel

asked on

Delphi DLL hook

Anyone got a working example of a dll hook, basically i would like to do something like get the handle of a program (at runtime) and then process the messages like wm_close or mouse click and prevent it if it's even possible.

all i can find on the net are stupid keyloggers...

Thanx folks...
Avatar of fanar
fanar

http://www.swissdelphicenter.com/en/showcode.php?id=1212
Check this out there is a link to down load the source also
Avatar of craig_capel

ASKER

Nope...

For example something like this, this is where i find it's not possible..

Wnd:=Findwindow.... (Get notepad's handle, or something else)
SetHook(HandleToWindow);

The dll the runs, it then gets the messageproc of the new program, if if msg = wm_close then stop it.

I have a program in C++ which uses a DLL to monitor another applications wm messages and if it detects a mouse wheel it scrolls
it down (i use it on Delphi 3).

i will post the code in the next post
//==========================================
// Matt Pietrek
// Microsoft Systems Journal, June 1997
// FILE: MouseWheel.CPP
//==========================================
#include <windows.h>
#include "mousewheel.h"

//=============================================================================
// Data
//=============================================================================

// Shared Data
#pragma data_seg(".shared")     // Make a new section that we'll make shared
HHOOK g_hHook=0;                // HHOOK from SetWindowsHook
UINT  g_WM_MOUSEWHEEL = 0;      // Window message for mousewheel scrolling
                                // Back to regular, non-shared data
char g_szRegPath[] = "Software\\WheatyProductions\\MouseWheel";
#pragma data_seg()

// Per process data
BOOL g_IsHookingProcess = FALSE;
BOOL g_okToAct = FALSE;
BOOL g_pageIncrements = FALSE;
unsigned g_incrementAmount = 1;

//=============================================================================
// Start of code
//=============================================================================

LRESULT CALLBACK GetMsgProc(
    int code,        // hook code
    WPARAM wParam,   // removal flag
    LPARAM lParam)   // address of structure with message
{
    LRESULT retValue = 0;

    // Be a good citizen, and call the other hooks
    retValue = CallNextHookEx( g_hHook, code, wParam, lParam );

    if ( FALSE == g_okToAct )    // Bail out if this process isn't one that
        return retValue;        // we care about

    LPMSG pMsg = (LPMSG)lParam;    // Make a ptr to the MSG structure for exam

    // If it's not a MOUSEWHEEL message, or if the app is just PEEK'ing,
    // bail out now.

    if ( g_WM_MOUSEWHEEL != pMsg->message || (wParam == PM_NOREMOVE) )
        return retValue;

    // By this point, we know a WM_MOUSEWHEEL message will be delivered.
    // Synthesize the appropriate WM_VSCROLL message(s) and post them

    WPARAM upDown;

    if ( g_pageIncrements )
        upDown = (short)HIWORD(pMsg->wParam) > 0 ? SB_PAGEUP : SB_PAGEDOWN;
    else
        upDown = (short)HIWORD(pMsg->wParam) > 0 ? SB_LINEUP : SB_LINEDOWN;

    for ( unsigned i = 0; i < g_incrementAmount; i++ )
        PostMessage(pMsg->hwnd, WM_VSCROLL, upDown,    0 );

    return 1;
}

UINT GetMouseWheelMsg( void )
{
    OSVERSIONINFO osvi;

    osvi.dwOSVersionInfoSize = sizeof(osvi);

    if ( !GetVersionEx(&osvi) )
        return WM_MOUSEWHEEL;            // Got a better idea?

    // NT 4 and later supports WM_MOUSEWHEEL
    if ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId )
        if ( osvi.dwMajorVersion >= 4 )
            return WM_MOUSEWHEEL;

    // Future Win32 versions ( >= 5.0 ) should support WM_MOUSEWHEEL
    if ( osvi.dwMajorVersion >= 5 )
        return WM_MOUSEWHEEL;

    // Hmmm... an older version.  The mouse driver support app should
    // have registered a window message for it.  By registering the
    // same message, we should get back the same message number.
    // Note that "MSWHEEL_ROLLMSG" below is a #define taken from ZMOUSE.H,
    // which is from the "Intellimouse SDK".
   
    return RegisterWindowMessage( "MSWHEEL_ROLLMSG" );
}


BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,    // handle to DLL module
    DWORD fdwReason,    // reason for calling function
    LPVOID lpvReserved)    // reserved
{
    //=========================================================================
    // DLL Process attach
    //=========================================================================

    if ( fdwReason == DLL_PROCESS_ATTACH )
    {
        // We don't need thread notifications for what we're doing.  Thus, get
        // rid of them, thereby eliminating some of the overhead of this DLL,
        // which will end up in nearly every GUI process anyhow.
        DisableThreadLibraryCalls( hinstDLL );

        if ( lpvReserved )   // Is this main process that sets the hook and
        {                    // loads this DLL initially ???

            if ( g_hHook )        // If we've already hooked, fail the DllMain
                return FALSE;

            g_IsHookingProcess = TRUE;

            // Set a global GetMessage hook
            g_hHook = SetWindowsHookEx( WH_GETMESSAGE, (HOOKPROC)GetMsgProc,
                                        hinstDLL, 0 );

            g_WM_MOUSEWHEEL = GetMouseWheelMsg();
        }

        // Get the name of the parent process EXE, and uppercase it
        char szExeName[MAX_PATH];
        GetModuleFileName( 0, szExeName, sizeof(szExeName) );
        CharUpperBuff( szExeName, lstrlen(szExeName) );

        //
        // Determine if the parent process EXE's name is in the registry, under
        // our special key.  If not, we won't bother translating mousewheel
        // scroll messages into WM_VSCROLL messsages.
        //

        HKEY hKey;
        if (ERROR_SUCCESS==RegOpenKey( HKEY_CURRENT_USER, g_szRegPath, &hKey))
        {
            DWORD dwValue = 0;
            DWORD dType, cbValue = sizeof(dwValue);

            if ( ERROR_SUCCESS == RegQueryValueEx(  hKey, szExeName, 0, &dType,
                                                    (PBYTE)&dwValue, &cbValue))
            {
                g_incrementAmount = dwValue & MW_SCROLL_INCREMENT_MASK;
                g_pageIncrements = dwValue & MW_SCROLL_PAGE ? TRUE : FALSE;

                g_okToAct = TRUE;
            }

            RegCloseKey( hKey );
        }

        // else.... This process's EXE wasn't under our key.  Do nothing.
    }

    //=========================================================================
    // DLL Process detach
    //=========================================================================

    else if ( fdwReason == DLL_PROCESS_DETACH )
    {
        if ( g_IsHookingProcess && g_hHook )    // The main EXE that loaded
        {                                       // this DLL is shutting down,
            UnhookWindowsHookEx( g_hHook );     // so remove the hook
            g_hHook = 0;
        }
    }

    return TRUE;
}

//-------------------------------------------------------------
// Dummy startup routine that does nothing except call DllMain
// This cuts out all of the standard startup code crud that
// bloats the DLL, and makes it take longer to load
//-------------------------------------------------------------
extern "C" BOOL __stdcall _DllMainCRTStartup(
    HINSTANCE hinstDLL,     // handle to DLL module
    DWORD fdwReason,        // reason for calling function
    LPVOID lpvReserved)     // reserved
{
    return DllMain( hinstDLL, fdwReason, lpvReserved );
}

//----------------------------------------------------------------------------
// Dummy routine that allows the main EXE to have an implicit import of
// this DLL.
//----------------------------------------------------------------------------
void DoNothing(void)
{
}
SetWindowsHookEx(WH_GETMESSAGE, @PROC, hInstance, GetWindowThreadProcessId(startwnd,nil));

function PROC(nCode: Integer; wp: wParam; lp: lParam): LongInt; stdcall;
begin
    if (nCode >= HC_ACTION) then
//check to see if it is wm_mousemove or wm_etc
//check windows sdk help it has documentation on every hook
//if u can also check the help for setWindowsHookEx in the sdk
     pmsg(lp).message:=WM_NULL;//will cancell it
    Result := CallNextHookEx(buf^.hMSNHook, nCode, wp, lp);
   end;
end;

I have a working source with this. It blocks all the messages from notepad. But the source is very very messy cause i modified another hook to do that. So if u still want that i could post it later.
Yes please.. i am more interesting in incerpting the wm_close as i intend on writing a hook to prevent
the shutdown of one of my old programs which i no longer the source for :(
craig_capel,
I think you could use CBT hooks for trapping HCBT_DESTROYWND or HCBT_SYSCOMMAND.
I had recently found this thread during my cleanup effort and had bookmarked it, hope it helps.

...Snehanshu
For CBT hook:
https://www.experts-exchange.com/questions/20389057/Detect-another-app's-edit-box-text-change.html

ASKER CERTIFIED SOLUTION
Avatar of fanar
fanar

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Muchos Gracias Senor.
Hmm,
Interesting to see how the working source of
>>SetWindowsHookEx(WH_GETMESSAGE, @PROC, hInstance, GetWindowThreadProcessId(startwnd,nil));
translated to
>>SetWindowsHookEx(WH_CBT, @Proc, hInstance, GetWindowThreadProcessId(startwnd,nil));
Just to follow solution :)
The solution is above, it's been answered already.