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...
all i can find on the net are stupid keyloggers...
Thanx folks...
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
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
ASKER
//======================== ========== ========
// 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\\WheatyProductio ns\\MouseW heel";
#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)
{
}
// 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\\WheatyProductio
#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
else
upDown = (short)HIWORD(pMsg->wParam
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(
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
{
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_GETMES SAGE, @PROC, hInstance, GetWindowThreadProcessId(s tartwnd,ni l));
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^.hMSNHo ok, 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.
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;
Result := CallNextHookEx(buf^.hMSNHo
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.
ASKER
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 :(
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Muchos Gracias Senor.
Hmm,
Interesting to see how the working source of
>>SetWindowsHookEx(WH_GETM ESSAGE, @PROC, hInstance, GetWindowThreadProcessId(s tartwnd,ni l));
translated to
>>SetWindowsHookEx(WH_CBT, @Proc, hInstance, GetWindowThreadProcessId(s tartwnd,ni l));
Interesting to see how the working source of
>>SetWindowsHookEx(WH_GETM
translated to
>>SetWindowsHookEx(WH_CBT,
Just to follow solution :)
The solution is above, it's been answered already.
Check this out there is a link to down load the source also