When using a DLL based hook procedure I would like to have it unload automatically when my program terminates. This can be accomplished by unhooking in the DLL_PROCESS_DETACH reason of DLLMain. The problem is with a system hook, if another process ends before mine the process sends a detach and will remove the hook. Is there any way from within DLLMain to tell which process is calling it ?

DllMain proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD

mov eax,hInst
mov hInstance,eax

.IF reason== DLL_PROCESS_DETACH
.IF hHook
invoke UnhookWindowsHookEx,hHook
.ENDIF
.ENDIF

mov eax,TRUE
ret
DllMain endp
Posted on 2003-12-01 20:47:19 by donkey
Why don't you make a reference counter?
Posted on 2003-12-01 21:04:25 by comrade
Also, GetCurrentProcess() and GetCurrentProcessId() do not work?
Posted on 2003-12-01 21:05:25 by comrade
Check if this applies.

From the MSDN docs

The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary function (or a function that calls FreeLibrary), because this can result in a DLL being used after the system has executed its termination code.

It is safe to call other functions in Kernel32.dll, because this DLL is guaranteed to be loaded in the process address space when the entry-point function is called. It is common for the entry-point function to create synchronization objects such as critical sections and mutexes, and use TLS. Do not call the registry functions, because they are located in Advapi32.dll. If you are dynamically linking with the C run-time library, do not call malloc; instead, call HeapAlloc.


Calling imported functions other than those located in Kernel32.dll may result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions in their DLLs call LoadLibrary to load other system components. Conversely, calling those functions during termination can cause access violation errors because the corresponding component may already have been unloaded or uninitialized.


Regards,
Art
Posted on 2003-12-01 21:05:29 by art_sands
Hi Art,

Yes, I read the entry in MSDN but if I know that it is my process that is unloading the DLL I can control the order it is unloaded in. If my program exits then the DLL will unload the hook as User32 will not yet be unloaded until I call ExitProcess. If another process detaches there is no call to UnhookWindowsHookEx so there is no problem with dependancies.

Hi comrade,

Should have thought of the current processes, I will try them. The reference count won't work as there can be any number of references when my program exits (every process loads a copy of the DLL), all I know is that there will be 0 when it is installed.
Posted on 2003-12-01 21:15:34 by donkey
so if you get the solution, please post it here.

Regards,
Art
Posted on 2003-12-01 21:25:27 by art_sands
Hi Art,

This works, thanks comrade :alright:

.data

hProcess dd 0
.code
DllMain proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD

.IF reason== DLL_PROCESS_DETACH
invoke GetCurrentProcessId
.IF eax == hProcess
invoke UnhookWindowsHookEx,hHook
.ENDIF

.ELSEIF reason== DLL_PROCESS_ATTACH
.IF !hProcess
invoke GetCurrentProcessId
mov hProcess,eax
.ENDIF

.ENDIF

mov eax,hInst
mov hInstance,eax

mov eax,TRUE
ret
DllMain endp
Posted on 2003-12-01 21:28:01 by donkey
Donkey, are you guaranteed that the first DLL_PROCESS_ATTACH you get is for your main app? I can't see why it shouldn't be, but is this guaranteed?

For my own hooks, I tend to let the main app call a UnregisterMe function in the DLL before it terminates.
Posted on 2003-12-04 07:07:32 by f0dder
Yes, it is guaranteed. I cannot install the hook until my process loads the DLL, since other processes do not load it until the hook is installed there is no possiblilty of another process ID other than mine being the first one passed. The reason behind this was that if my program exits in error before it can unhook, the other processes will still have the hook running in their address space, this solves that problem as even in a gpf I think that Windows performs a cleanup and unloads the dll with the proper process ID. At least that is what it looked like in my tests, I could be wrong about it but better safe than sorry.

For example I installed the hook then did this:

xor eax,eax
jmp eax

to gpf the application and the Unhook still executed from the DLL even though the main application GPFed.
Posted on 2003-12-04 10:26:42 by donkey
Hi :)
Very good snippet, donkey! I'll be adding it to my hooklib. :alright:
Posted on 2003-12-06 11:25:32 by QvasiModo
hoho

nice, tehre's another donkey here. hi donkey, wassup?
Posted on 2003-12-07 06:46:45 by evil__donkey