Solved

Delphi DLL hook

Posted on 2003-12-07
11
31,129 Views
Last Modified: 2012-05-04
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...
0
Comment
Question by:craig_capel
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +2
11 Comments
 
LVL 1

Expert Comment

by:fanar
ID: 9893358
http://www.swissdelphicenter.com/en/showcode.php?id=1212
Check this out there is a link to down load the source also
0
 
LVL 2

Author Comment

by:craig_capel
ID: 9893967
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
0
 
LVL 2

Author Comment

by:craig_capel
ID: 9893971
//==========================================
// 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)
{
}
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Expert Comment

by:fanar
ID: 9894336
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.
0
 
LVL 2

Author Comment

by:craig_capel
ID: 9894409
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 :(
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9894587
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:
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20389057.html

0
 
LVL 1

Accepted Solution

by:
fanar earned 100 total points
ID: 9900273
Hey here you go. This is the modiefied dll(I thnk Geubol translated it from c to delphi). This dll stops notepad from closing. Sorry for the mess its just with school exams and stuff that are coming up i dont have time for anything any more

library MSNHook;

uses
 Windows,
 Messages,sysutils;

type
 THookRec = record
   hMSNHook: HHOOK;
   hMSNWnd: HWND;
   oldProc: Integer;
 end;

var
 map: DWord;
 buf: ^THookRec;



function PROC(nCode: Integer; wp: wParam; lp: lParam): LongInt; stdcall;
begin
    if (nCode >= HC_ACTION) then
    if (nCode=HCBT_DESTROYWND)then
    begin
    Result:=1;
    exit;
    end;
    Result := CallNextHookEx(buf^.hMSNHook, nCode, wp, lp);

end;

// sets up hook
function SetHook: Boolean; stdcall; export;
var
startwnd:HWND;
begin
 try
   Result := false;
   if (not assigned(buf)) then
   begin
     map := CreateFileMapping(DWord(-1), nil, PAGE_READWRITE, 0, SizeOf(THookRec), 'HookRecMemBlock');
     buf := MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0, 0);
     startwnd:=FindWindow('Notepad', nil);
     buf^.hMSNWnd:=startwnd;
     buf^.hMSNHook := SetWindowsHookEx(WH_CBT, @Proc, hInstance, GetWindowThreadProcessId(startwnd,nil));
     Result := true;
   end;
 except
   Result := false;
   MessageBox(0, 'error in SetHook', 'error', MB_OK);
 end;
end;

// removes hook
function RemoveHook: Boolean; stdcall; export;
begin
 Result := false;
 if (assigned(buf)) then
 begin

   if (buf^.hMSNHook <> 0) then UnhookWindowsHookEx(buf^.hMSNHook);
   buf^.hMSNHook := 0;
   UnmapViewOfFile(buf);
   buf := nil;
   Result := true;
 end;
end;

// DLL entry point
procedure DllEntry(dwReason: DWord);
begin
 Case dwReason of
   DLL_PROCESS_ATTACH:
   begin
     if (not assigned(buf)) then
     begin
       map := OpenFileMapping(FILE_MAP_ALL_ACCESS, false, 'HookRecMemBlock');
       buf := MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0, 0);
       CloseHandle(map);
       map := 0;
     end;
   end;
   DLL_PROCESS_DETACH:
   begin
     UnmapViewOfFile(buf);
     buf := nil;
   end;
 end;
end;

exports
 SetHook,
 RemoveHook;

// main
begin
 DisableThreadLibraryCalls(hInstance);
 DllProc := @DLLEntry;
 DllEntry(DLL_PROCESS_ATTACH);
end.
0
 
LVL 2

Author Comment

by:craig_capel
ID: 9901757
Muchos Gracias Senor.
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9901863
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));
0
 

Expert Comment

by:bBK
ID: 10456859
Just to follow solution :)
0
 
LVL 4

Expert Comment

by:tobjectpascal
ID: 10457979
The solution is above, it's been answered already.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
how to center only a line in richedit? 4 75
oracle global variables 4 80
Error E2158 compiling with Delphi XE10 Seattle 2 135
migrate this code to work on android 1 42
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question