Uninjected dll not completely released

c++ / delphi package - dll injection and api hooking
JohnStevenson
Posts: 27
Joined: Mon Jun 14, 2004 12:45 pm

Post by JohnStevenson »

That means, if you first start your program and then ZoneAlarm, madCodeHook's kernel mode driver does its job and ZoneAlarm gets your hook dll injected.
But you will then be unable to uninject the dll, due to the built-in protection against uninjecting.

Fortunately I have no desire to hook ZoneAlarm! Thanks for solving the mystery.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

JohnStevenson wrote:But you will then be unable to uninject the dll, due to the built-in protection against uninjecting.
Well, you can kind of work around it. Your dll can during initialization check whether you're running inside of ZoneAlarm. If you do, just let DllEntryPoint fail (in Delphi by setting ExitCode to something <> 0). Then your dll will be unloaded again at once.
fsurfer
Posts: 23
Joined: Thu Jul 08, 2004 9:53 am

DLL uninjection ?

Post by fsurfer »

madshi wrote:
JohnStevenson wrote:But you will then be unable to uninject the dll, due to the built-in protection against uninjecting.
Well, you can kind of work around it. Your dll can during initialization check whether you're running inside of ZoneAlarm. If you do, just let DllEntryPoint fail (in Delphi by setting ExitCode to something <> 0). Then your dll will be unloaded again at once.
Madshi,

Do you mean that, because of internal controls, the DLL, although a uninjection call, can stay in any number of process, if the dll is supposing one of its function is being used ?

I do have a little problem like that :
as you know, my application is built on a client/serveur model. i'd like to send, from the server, to every client an application that updates the client one. but i always have the problem that the injected dll is in use, although the client application recognize the application sent as an update and remove itself from memory.

if any clue or hint,

Thanks

best regards,

Guillaume
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: DLL uninjection ?

Post by madshi »

fsurfer wrote:Do you mean that, because of internal controls, the DLL, although a uninjection call, can stay in any number of process, if the dll is supposing one of its function is being used ?
Yes, but only if the dll is thinking that one of the *hook callback functions* is still in use. You can tell madCodeHook to not behave like that by using the DONT_COUNT flag when calling HookAPI. However, please note that when using that flag you might get crashes while unloading your dll - when the dll gets unloaded while a hook callback function is still in use.
fsurfer wrote:as you know, my application is built on a client/serveur model. i'd like to send, from the server, to every client an application that updates the client one. but i always have the problem that the injected dll is in use, although the client application recognize the application sent as an update and remove itself from memory.
I don't know why this is the case. Do you wait until UninjectLibrary returned? In most cases the dll should be not in use afterwards, anymore. It depends a bit on the APIs you're hooking, though.
fsurfer
Posts: 23
Joined: Thu Jul 08, 2004 9:53 am

Re: DLL uninjection ?

Post by fsurfer »

madshi wrote:
fsurfer wrote:Do you mean that, because of internal controls, the DLL, although a uninjection call, can stay in any number of process, if the dll is supposing one of its function is being used ?
Yes, but only if the dll is thinking that one of the *hook callback functions* is still in use. You can tell madCodeHook to not behave like that by using the DONT_COUNT flag when calling HookAPI. However, please note that when using that flag you might get crashes while unloading your dll - when the dll gets unloaded while a hook callback function is still in use.
hmmm... can't really take the risk to crash one of my pc...
madshi wrote:
fsurfer wrote:as you know, my application is built on a client/serveur model. i'd like to send, from the server, to every client an application that updates the client one. but i always have the problem that the injected dll is in use, although the client application recognize the application sent as an update and remove itself from memory.
I don't know why this is the case. Do you wait until UninjectLibrary returned? In most cases the dll should be not in use afterwards, anymore. It depends a bit on the APIs you're hooking, though.
Well, i've written my own auto-extractible application... at first, i've seen that there's was sometimes a problem with the DLL loaded although i uninjected it... So i did the following :
i wait within a time-based loop that all the modules present in my auto-extractible application to be unloaded. If after the wait time limit, any module is still loaded i send an installation error to the server else i extract the files to overwrite them. because i thought that uninjection has its own process to wait for any hooked function call to be terminated :)

But if it doesn't work like that... the tricky thing is that the module which is injected doesn't always stay loaded... it seems to stay loaded quite randomly... and, above all, all of this has to work from win9x to winXP ;)

but i won't bother you with all that ;) i'll try to find a way...

best regards,

Guillaume
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

If the hook dll doesn't want to get unloaded there's probably not much you can do - except restarting the PC... :(

Well, in the NT family you can perhaps rename the dll to "your.dll.old" and then write the new dll.
JohnStevenson
Posts: 27
Joined: Mon Jun 14, 2004 12:45 pm

Post by JohnStevenson »

madshi wrote:Well, you can kind of work around it. Your dll can during initialization check whether you're running inside of ZoneAlarm. If you do, just let DllEntryPoint fail (in Delphi by setting ExitCode to something <> 0). Then your dll will be unloaded again at once.
Since my hook dll is injected system wide, but is only required by a few known processes, this seems like a great way to inject only into the required processes. I call ProcessIdToFilename then filter against a file-mapped list of programs I want to inject in to.

However, I keep getting access violations when the library unloads from a failed DllEntryPoint call.

In order to debug this problem, I wrote a simple (non-hook) dll that creates an simple object in DLL_PROCESS_ATTACH and frees it in DLL_PROCESS_DETACH. I can then load and unload this library with no errors, as you would expect.

However, if I set the ExitCode to <> 0 in DLL_PROCESS_ATTACH (to mimic my filtering in the hook dll), I get '... raised too many consecutive exceptions...' and a 216 runtime error. Incidentally, if I do not create the object in DLL_PROCESS_ATTACH, I do not get an access violation.

I realize that this is not a madcodeHook problem (perhaps I should be asking this on EE), but I feel that it would be useful if my program only injects into the processes it needs to.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

You should in the first line of your dll project call GetModuleFileName(0) and then check that. If you decide to let DllEntryPoint fail, make sure you free everything. Also you shouldn't call any HookAPI stuff then. Something like this:

Code: Select all

project YourHookDll;

uses madCodeHook, madStrings;

var arrCh : array [0..MAX_PATH] of char;
begin
  GetModuleFileName(0, arrCh, MAX_PATH);
  if not IsTextEqual(arrCh, 'explorer.exe'') then begin
    ExitCode := 1;
    exit;
  end;
  HookAPI(...);
end;
JohnStevenson
Posts: 27
Joined: Mon Jun 14, 2004 12:45 pm

Post by JohnStevenson »

Wow, fast response - thanks.

So I must explicitly free-and-nil any objects before DLL_PROCESS_DETACH has a go? This works, but why does DLL_PROCESS_DETACH cause the AVs.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Don't know... :D
Post Reply