Tech Support > Microsoft Windows > Drivers > Precise Control of Messages
Precise Control of Messages
Posted by Extrarius on November 25th, 2005


I have a program that needs very precise control of messages, but
user32.dll provides insufficient functionality. The program needs to be
able to intercept (almost) every message to a specific application
(including those to all of its threads, windows, and the controls on
each window, such as standard windows buttons), prevent the message
from having any affect on the application, exchange information about
the message with other parts of the program (which will involve
networking and thus latency measured in millisecs at least), and
possibly later send the message on as if it were never stopped. The
target OS is "Windows 2000 Professional" and both XP Pro and 2K Pro are
used on development machines.

How is this relevant to kernel-mode/driver development groups? (I would
have posted it to a single group if it were clear what each covers, but
I could find no such descriptions.) I'm wondering if some type of
driver (or other kernel-mode code) might be the best way to implement
complete control over the messaging system.

I currently know nothing about driver development, but recently I
became interested and ordered the 'Windows Server 2003 SP1 DDK CD' and
the book 'Windows Internals (ISBN: 0735619174)' as a place to start.
Just as both arrived, it occured to me that kernel-mode code might be
the solution I've been looking for. Searching through the book, the ddk
documentation, and the internet in general, I was unable to find
anything that seemed relevant one way or the other to this specific
problem, so I figured that a developer more experienced in this area
might be able to tell me whether this idea is feasible and/or could
point me towards directly relevant information.

I would appreciate any suggestions, pointers, or other assistance =-)

-Extrarius

P.S. Any email replies should include a relevant group name in the
subject so the email isn't filtered as junk.

Posted by Kellie Fitton on November 25th, 2005


Hi,

You need to use a system-wide hook, for example, WH_CALLWNDPROC to
monitor messages being sent, and WH_CALLWNDPROCRET to monitor the
messages handlers returning, and a hook procedure in a .DLL file.

Use the following API's to create/set/handle hooks in a windows
environment application:

SetWindowsHookEx()
CallNextHookEx()
UnhookWindowsHookEx()

http://msdn.microsoft.com/library/de...dowshookex.asp

http://msdn.microsoft.com/library/de...nexthookex.asp

http://msdn.microsoft.com/library/de...dowshookex.asp

http://msdn.microsoft.com/library/de...abouthooks.asp

Hope these information helps,

Kellie.

Posted by Extrarius on November 25th, 2005


Unfortunately, neither of the mentioned hook types allow the message to
be modified (to prevent it from reaching the target), which is one of
the requirements. As far as I can tell, no combination of hooks allows
all messages to be both intercepted and modified.

-Extrarius

Posted by Bernhard Poess on November 25th, 2005


Extrarius wrote:
kernel mode code for accomplishing this. In order to use the debug port,
you must go through some native ntdll calls, but I'll give you some
hints if you want to know more.

Bernhard

P.S. For an introduction see http://undocumented.ntinternals.net

Posted by James Brown on November 25th, 2005


In that case you could try hooking the GetMessage and PeekMessage API
calls within your target application using the Detours package from
Microsoft -
this would have you access to all messages being processed by all threads
in the application.

http://research.microsoft.com/sn/detours/

Installing the hook would allow you to either modify the message
before passing it onto the target app, or even "eating" the message
altogether.

You will need to write a DLL which you "inject" into the app - this DLL
should contain all of your hooking code. I think maybe Detours provides
this functionality as well, otherwise google for "dll injection".

James

--
www.catch22.net
Free win32 software, sourcecode and tutorials


"Extrarius" <filtered@psychosanity.com> wrote in message
news:1132903694.596413.45150@g49g2000cwa.googlegro ups.com...


Posted by Extrarius on November 25th, 2005


Bernhard Poess wrote:
It sounds like your suggestion involves modifying the the application
that is to be monitored. While in the most urgent case, such
modifications are possible, the message-monitoring (and modifying)
program will need to work with applications that cannot be modified in
the future.

-Extrarius


Posted by Bernhard Poess on November 25th, 2005


Extrarius wrote:
No, it doesn't. You just write a new app, that acts somehow like a
debugger. But instead of reacting to every debug message you can filter
the messages you're interested in and handle them accordingly.

-Bernhard

Posted by Extrarius on November 25th, 2005


Unfortunately, notification messages (sent via WM_COMMAND to notify a
parent window of events such as button clicks) do not go through the
normal message processing procedure, so they never pass through
GetMessage or PeekMessage.

I was already fairly certain that this was the case, but to make
absolutely sure I made a simple windows program and made it log all
messages returned by GetMessage to a file, which resulted in messages
such as mouse down and mouse up messages to the button being logged,
but not the WM_COMMAND message carrying the BN_CLICKED notification.

-Extrarius

James Brown wrote:

Posted by Extrarius on November 25th, 2005


Bernhard Poess wrote:
I'm confused, then, about why you inlcuded the link to
http://undocumented.ntinternals.net . Was the link merely to help me
get started in kernel-mode development? The debugging API is well
documented in the Platform SDK, but I see no capability for
intercepting messages in any of the debugging functions.


Posted by Maxim S. Shatskih on November 25th, 2005


Then hook the wndproc itself, by subclassing all windows, for instance.

Anyway: this product idea looks like a major paranoia remember - you will be
filtering most OLE/COM traffic too, not only UI.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com


Posted by Extrarius on November 25th, 2005


Maxim S. Shatskih wrote:
The problem with subclassing is that in order for it to be effective, I
also need to know when new windows are created so they can be
subclassed. Is the best way to do that hooking CreateWindow A/W,
CreateWindowEx A/W, and any other functions that create windows? If so,
what other functions would need to be hooked, and what is the best
method for hooking?

-Extrarius


Posted by Maxim S. Shatskih on November 25th, 2005


BTW - am I correct that CALLWNDPROC type of hook will hook this?

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com


Posted by Scherbina Vladimir on November 25th, 2005


I am not sure that you need to hook CreateWindow(Ex)(W|A) because you can't
get wndproc from it.
Hooking RegisterClass(Ex), AFAIR will be enough (you can get pointer to
wndproc function from WNDCLASS(EX) structure).

As for hooking techniques, take a look at
http://www.internals.com/articles/apispy/apispy.htm and
http://www.codeproject.com/system/hooksys.asp.

Good luck.

--
Scherbina Vladimir

"Extrarius" <filtered@psychosanity.com> wrote in message
news:1132927109.632396.23250@g43g2000cwa.googlegro ups.com...


Posted by Extrarius on November 26th, 2005


Maxim S. Shatskih wrote:
You are correct that such a hook should receive notification about such
messages, but the hook would have no way to modify the message or
prevent it from being delivered to it's target.

-Extrarius

Posted by Extrarius on November 26th, 2005


Scherbina Vladimir wrote:
The reason to hook CreateWindow(*) and other functions such as
CreateDialog(*) is so that the hooking program knows of every window
that needs to be subclassed. Many windows, such as standard windows
buttons (window class "button"), are not be registered by applications
that use them.

Other than that, the only two problems are that this method only works
for window messages (no thread or system messages) and that it would be
very tedious to implement since I would have to look up every function
in User32.dll (and possibly other dlls also) to discover which functions
create a window.

-Extrarius

Posted by Maxim S. Shatskih on November 26th, 2005


Cal you forget calling the next hook? or call the next hook with modified
message code or parameters?

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com


Posted by Maxim S. Shatskih on November 26th, 2005


They are not interesting anyway. They are usually the innerworkings of some
app.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com


Posted by Extrarius on November 26th, 2005


Maxim S. Shatskih wrote:
Such things are possible, but they don't have the desired result. In
fact, they don't seem to have any result at all. Despite the PlatformSDK
specifically stating that WH_CALLWNDPROC hooks cannot modify the
message, I created a quick test program that both modified the CWPSTRUCT
that is passed by pointer to the hook function and also returned 0
(indicating that the hook function did not call CallNextHookEx) or
CallNextHookEX (with the modified or original parameters) and it
demonstrated that the documentation was correct on the issue.

-Extrarius

Posted by Extrarius on November 26th, 2005


Maxim S. Shatskih wrote:

I'm sure that is generally the case, but I can't rely on it because it
isn't guaranteed. Actually, even if it were, intercepting those 'inner
workings' might be just as important as intercepting a window message. I
wouldn't be at all surprised to find an application that required such
unusual treatment. I sometimes have to work with software created for
government contracts and, if you haven't, you might be surprised at the
variety and depth of offenses committed in such software.

-Extrarius

Posted by Bernhard Poess on November 28th, 2005


Extrarius wrote:
By using the debug port, you get lots more messages than documented e.g.
in the Platform SDK, since I don't know your expertise level I sent the
link because PORT objects are explained there.

-bernhard