SetwindowHookEx

c++ / delphi package - dll injection and api hooking
Post Reply
Mazinger
Posts: 33
Joined: Wed Jan 26, 2005 6:26 am

SetwindowHookEx

Post by Mazinger »

Hi,

I'm playin with madCodeHook and SetWindowHookEx, and I have a little question:

Where is the best place SetWindowHookEx API function will be called? On the main program? on the DLL?

Thanks in advance.
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Post by iconic »

Please explain more because you provided no details about what you are trying to do. If you are using DLL injection and injecting into one specific process for example, calling SetWindowsHookEx() within your DLL, in DLLMain() for example, the windows hook will be installed from the target process which you've injected into. If you call SetWindowsHookEx() from your program your exe will be the caller. Where you call it does not really make a difference with how the hook is installed, when you call it may make a difference.

An example being user calls madCodeHook.CreateProcessEx() and user uses the returned TID from this call in SetWindowsHookEx(). Windows attempts to install your hook immediately but the process is not up yet or fully initialized. In this case calling SetWindowsHookEx() from DLLMain() of your injected DLL is probably a better choice.

-Iconic
Mazinger
Posts: 33
Joined: Wed Jan 26, 2005 6:26 am

Post by Mazinger »

Sorry,

I actually use a WH_CBT hook to detect when a certain window is created on my system (yes, is a system-Wide hook), so I have a main app and a DLL with the hook callback function. On the DLL I have two additional functions, to set (setwindowHookEx) and remove the hook. These two functions are called from the main app.

The problem I have is: On main app I remove the hook (calling a DLL function) and make a FreeLibrary for the DLL. All seems to work fine, but if after make the freelibrary I use madKernel.module(true) wich lists alls system-wide modules, I can see my DLL (unloaded theoricaly from all processes) on the owner process (main application) and sometimes on other 3 o 4 processes.

Thanks.
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Post by iconic »

So you're wondering why some processes have not freed the library? The OS is responsible for doing that when the time is right. The PE loader knows when to load and unload your DLL from the processes that are forced to load your DLL. And in this case, any process that links against user32.dll and has a thread message queue, since SetWindowsHookEx() requires it (It's a message based hook so it makes sense ;))

--Iconic
Mazinger
Posts: 33
Joined: Wed Jan 26, 2005 6:26 am

Post by Mazinger »

:oops: Sorry, not fully understood.

Is there any chance to assure that my library is full unload. Why I need it? Mainly to update the application. If I can't fully unload the library I can't override it and I must do a system reboot :cry:
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Post by iconic »

I've had the same problem myself actually and Yes, I know exactly what you mean. What does your unhook code look like? Sounds to me like a condition might be preventing the hook from being uninstalled _or_ Windows is taking its time because you've hooked/unhooked so many times.

--Iconic
Mazinger
Posts: 33
Joined: Wed Jan 26, 2005 6:26 am

Post by Mazinger »

:cry: I only set/unset the hook one time: on app init and end.

Have you any ideas?

Thanks!
dcsoft
Posts: 380
Joined: Sat Dec 11, 2004 2:11 am
Location: San Francisco Bay Area, CA USA
Contact:

Post by dcsoft »

To uninject the hook DLL, I EnumWindows() and do a PostMessage(WM_NULL) to each one. This forces Windows to uninject the DLL. I sit in a loop and wait until the DLL has been uninjected from all processes. How to know when this is? If you can open the DLL file so that it can be deleted, you know the DLL is no longer busy and you can get out of the loop.

If you only need to be notified of when a window is created, you can use either a WH_SHELL hook, which is lower impact than WH_CBT, or better yet, use SetWinEventHook, part of Active Accessibility, available in Win98 or later. And you can get EVENT_OBJECT_CREATE events (I think that's what it's called) when a window is created. Better still, you can get this event in your .exe and there is no need to create a DLL.

-- David
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Post by iconic »

Sounds like a plan, nice tips dcsoft :D I've used msaa's SetWinEventHook() myself for similar reasons but I have heard, and personally experienced some problems and actually not been notified about certain events with the "out-of-context" hooks, the one that allows your exe to be notified without a dll of course. I'd definitely suggest your idea with an in-context hook, also it's exponentially faster than out-of-context hooks.

Cheers,
--Iconic
Mazinger
Posts: 33
Joined: Wed Jan 26, 2005 6:26 am

Post by Mazinger »

:shock: I'm amazed dcsoft! With your suggestion (postmessage(WM_NULL) and waiting for a read/write open of the file) the hooked DLL is unloaded.

:crazy: :crazy:

One more question please: Why WH_CBT hook is more heavy than WH_SHELL?

Thanks!!!
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

dcsoft wrote:To uninject the hook DLL, I EnumWindows() and do a PostMessage(WM_NULL) to each one.
I've usually done PostMessage(HWND_BROADCAST, WM_NULL, 0, 0). Shouldn't that do the same thing?
dcsoft
Posts: 380
Joined: Sat Dec 11, 2004 2:11 am
Location: San Francisco Bay Area, CA USA
Contact:

Post by dcsoft »

Yes, PostMessage(HWND_BROADCAST, WM_NULL) is a nice optimization for EnumWindows that I hadn't thought of! :D

WH_SHELL doesn't get called many times since the events occur rarely. I believe Windows Explorer.exe creates a permanent WH_SHELL hook, it is so light. WH_CBT is not bad either, but if you don't need to block a window creation or change it's creation parameters, WH_SHELL gives you all you need.

I have heard SetWinEventHook() with out-of-context hooks has performance issues under Win9x, but I haven't experienced any problems on Win2K/XP. It's much more convenient if you don't have to create a DLL.

Thanks,
David
Post Reply