flat assembler
Message board for the users of flat assembler.

Index > Windows > dll reference count

Author
Thread Post new topic Reply to topic
Rookie



Joined: 21 Aug 2003
Posts: 44
Location: Planet Romania
Rookie 08 Sep 2006, 07:23
Does anybody know how could I get the current ref count for a loaded library? I need this to know how many times should I call FreeLibrary to unload a dll (unfortunately I cannot count the number of LoadLibrary calls). Or maybe some other way of unloading the dll, without knowing the reference count?...

_________________
This is who I choose to be.
Post 08 Sep 2006, 07:23
View user's profile Send private message Reply with quote
RedGhost



Joined: 18 May 2005
Posts: 443
Location: BC, Canada
RedGhost 08 Sep 2006, 09:23
I believe this would be located somewhere in the PEB, maybe it is stored multiple times in the module linked lists? Maybe there is a reference count dvar of LDR_MODULE, not sure..

http://undocumented.ntinternals.net/

Good place to start.

_________________
redghost.ca
Post 08 Sep 2006, 09:23
View user's profile Send private message AIM Address MSN Messenger Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 10 Sep 2006, 11:58
When calling LoadLibrary on a dll which was previously loaded, the system returns a handle. It doesn't load it again. Every library is loaded once per process and it has to be unloaded also once.
Post 10 Sep 2006, 11:58
View user's profile Send private message Visit poster's website Reply with quote
Rookie



Joined: 21 Aug 2003
Posts: 44
Location: Planet Romania
Rookie 11 Sep 2006, 12:09
Yes, I know. Each time a call to LoadLibrary is done, a reference count for that certain dll is incremented. This ref count is decremented, in turn, each time a FreeLibrary call is made for that dll. The library is unloaded from memory only when this ref count is 0.
And what I want to do is just that - unload a library from memory. So I was thinking of finding out this ref count and calling FreeLibrary as many times as needed (or finding a similar way to unload a dll without affecting system stability at all, otherwise the issue is trivial).
Post 11 Sep 2006, 12:09
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 11 Sep 2006, 12:50
reverse UnloadLibrary (you will probably have to go deep to system), and there somewhere will be this thing hidden). It's quite possible that they have such thing in kernel
Post 11 Sep 2006, 12:50
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
HyperVista



Joined: 18 Apr 2005
Posts: 691
Location: Virginia, USA
HyperVista 11 Sep 2006, 14:17
i recommend using FreeLibraryAndExitThread(hModule, dwExitCode) function instead of FreeLibrary. That way, your dll is "self deleting" Wink

i suppose you could just use a loop on FreeLibraryAndExitThread until it fails. that way, you don't need to know in advance what the refcount is. the downside is, of course, you could hose up other apps who may have called your dll. Confused

Code:
if(FreeLibraryAndExitThread(h_your_dll, 0){
     (FreeLibraryAndExitThread(h_your_dll, 0)
}
...........

Warning:  code not tested

    


include Winbase.h and Windows.h
Post 11 Sep 2006, 14:17
View user's profile Send private message Visit poster's website Reply with quote
Rookie



Joined: 21 Aug 2003
Posts: 44
Location: Planet Romania
Rookie 12 Sep 2006, 13:51
Thought about reversing it, but I feel kinda lazy right now, simply because I would arrive to a pointer, so I'd have to reverse various versions of the kernel, build myself an array of the addresses and call GetVersionEx to know which one to use.

FreeLibraryAndExitThread is not an option, as I just want the module unloaded from memory, with the thread still running afterwards.
Post 12 Sep 2006, 13:51
View user's profile Send private message Reply with quote
HyperVista



Joined: 18 Apr 2005
Posts: 691
Location: Virginia, USA
HyperVista 12 Sep 2006, 14:11
Rookie wrote
Quote:
FreeLibraryAndExitThread is not an option, as I just want the module unloaded from memory, with the thread still running afterwards.


okay then, just loop on FreeLibrary until it fails:

Code:
if(FreeLibrary(h_your_dll{ 
     (FreeLibrary(h_your_dll) 
} 
........... 
Warning:  as usual, code not tested     


It doesn't give you refcount, but with this method you don't need refcount.
It seems you are building a rather fragile system when you don't keep track of refcount in your .dll and you want to kill it in memory but keep the thread alive. asking for trouble, imho. but then again, i don't know your objective and intentions so maybe this design is good for you.
Post 12 Sep 2006, 14:11
View user's profile Send private message Visit poster's website Reply with quote
Rookie



Joined: 21 Aug 2003
Posts: 44
Location: Planet Romania
Rookie 12 Sep 2006, 15:27
My intentions? I come in peace, I assure you. Very Happy
And my objective is just that: learn how to unload a dll from a process memory without affecting system stability or that of my own process... much (preferably at all), so a loop on FreeLibrary or any other function is not too recommended as it might hang the thread and maybe even hog the system.
Starting at the ntinternals link above, I have come across this:
http://www.security-assessment.com/Whitepapers/PreDebug.pdf
I'll try my hand at extracting something to suit my needs from that, and if it doesn't work (or I'm a little to dumb to make something useful out of it), I'll go to reversing the kernel, see what I can come up with.
Meanwhile, if anyone has any other ideas, I'm open to sugestions, as asm is a lot more fun to write than to read. Razz

_________________
This is who I choose to be.
Post 12 Sep 2006, 15:27
View user's profile Send private message Reply with quote
HyperVista



Joined: 18 Apr 2005
Posts: 691
Location: Virginia, USA
HyperVista 12 Sep 2006, 15:39
Awesome article Rookie!! Thanks for the link. (your intentions are more clear ... and what i suspected Laughing )

Sorry I couldn't be more help. I don't think there is an easy way to get refcount on a .dll (it's something not generally done, so no public methods to do it). I'll keep looking and let you know if I find something that will help you.

There should be a table in kernel space that holds the refcount .... i have a book at home and will look it up later ...
Post 12 Sep 2006, 15:39
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 13 Sep 2006, 06:36
or you can load library yourself, if it solves your problem. it's easy, i have done it for ARM recently
Post 13 Sep 2006, 06:36
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Rookie



Joined: 21 Aug 2003
Posts: 44
Location: Planet Romania
Rookie 13 Sep 2006, 11:06
I don't understand what you mean
Post 13 Sep 2006, 11:06
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 13 Sep 2006, 11:08
if you don't want library to be shared, and only you are using library, you can emulate win's loader and load library yourself. eg. allocate mem for it, load image into memory, protect pages, relocate code, import procedures etc. it's easier than it seems
Post 13 Sep 2006, 11:08
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Rookie



Joined: 21 Aug 2003
Posts: 44
Location: Planet Romania
Rookie 13 Sep 2006, 11:55
Maybe you miss-understood the topic. I'm looking for a way to unload it from memory, without knowing the number of calls to LoadLib and without crashing the app that loaded it. As I'm using a test app that just loads a dll a number of times, it's safe to say it won't be missed after I unload it (eg. no Access Violation exceptions).
Post 13 Sep 2006, 11:55
View user's profile Send private message Reply with quote
daluca



Joined: 05 Nov 2005
Posts: 86
daluca 14 Sep 2006, 06:17
Sorry for my ignorance but,can you Free a library that you allready freed?
you can call FreeLibrary to indicate that you don't need that library any more
but in the win32.hlp you can read:

"Calling FreeLibrary does not affect other processes using the same library module"

so the library is unloaded only wen no process needs it.
and what about the parameter: hLibModule ?
calling FreeLibrary doesn't make this handle invalid?

from win32.hlp:

"A call to LoadLibrary by one process does not produce a handle that another process can use". Question
Post 14 Sep 2006, 06:17
View user's profile Send private message Reply with quote
Rookie



Joined: 21 Aug 2003
Posts: 44
Location: Planet Romania
Rookie 14 Sep 2006, 14:04
About FreeLibrary, taken from MSDN:
Quote:
Decrements the reference count of the loaded dynamic-link library (DLL). When the reference count reaches zero, the module is unmapped from the address space of the calling process and the handle is no longer valid.

and
Quote:
Each process maintains a reference count for each loaded library module. This reference count is incremented each time LoadLibrary is called and is decremented each time FreeLibrary is called.


Each process has it's own address space, so each process has its own list of loaded modules, and a reference count for each of these modules. As the address space is generally accesible to only that process, you cannot use the handle for a module loaded in a process in a different process.

Also, as explained above, FreeLibrary decrements the reference count, and unloads the dll from memory for the specified process only when it has reached 0.

As for hLibModule (the value returned by LoadLibrary and GetModuleHandle), as I recall (and hope I'm not mistaking about it) it's actually the address in memory at which the module has been mapped (loaded).

Hope it cleared up things a little for you. If not (or you want further details) MSDN is your new best friend. Smile
Post 14 Sep 2006, 14:04
View user's profile Send private message Reply with quote
HyperVista



Joined: 18 Apr 2005
Posts: 691
Location: Virginia, USA
HyperVista 22 Sep 2006, 18:11
@Rookie - here's a link to an an old MSJ article by Matt Pietrek on .dlls. In the top part of the article there is a link to his source code (sep98hood.exe). It might be of some help to you in determining the refcount of your .dll.

http://www.microsoft.com/msj/0998/hood0998.aspx
Post 22 Sep 2006, 18:11
View user's profile Send private message Visit poster's website Reply with quote
Rookie



Joined: 21 Aug 2003
Posts: 44
Location: Planet Romania
Rookie 28 Sep 2006, 15:50
@HyperVista: thanks for the link

So I went to an NT Kernel Internals seminar the other day, held by Adrian Marinescu (senior developer from the Windows kernel team). It was interesting. I addressed him this issue, and found out there's no easy way to do it. The dll reference count is part of the PEB (Process Environment Block) structure, which is undocumented (and won't be any time soon). As such, it's subject to change at any time without any prior notice. So if I want to do it the ref count way, I'd have to do some lengthy reversing and check version numbers all the time. But this would be useful as it would let me reset the flag for libraries marked as "not unloadable" (ref count set to 0xFFFF).
I'll try thinking of some other solution. Maybe do a FreeLibrary in a loop that checks for the dll still being loaded, but this would mean I first have to pause the process. so as to not enter an infinite loop. Confused

_________________
This is who I choose to be.
Post 28 Sep 2006, 15:50
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.