Solved

Delphi DLL hook

Posted on 2003-12-07
11
31,117 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
  • 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
Industry Leaders: 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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

685 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