flat assembler
Message board for the users of flat assembler.
Index
> Windows > dll reference count |
Author |
|
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 |
|||
08 Sep 2006, 09:23 |
|
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.
|
|||
10 Sep 2006, 11:58 |
|
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). |
|||
11 Sep 2006, 12:09 |
|
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
|
|||
11 Sep 2006, 12:50 |
|
HyperVista 11 Sep 2006, 14:17
i recommend using FreeLibraryAndExitThread(hModule, dwExitCode) function instead of FreeLibrary. That way, your dll is "self deleting"
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. Code: if(FreeLibraryAndExitThread(h_your_dll, 0){ (FreeLibraryAndExitThread(h_your_dll, 0) } ........... Warning: code not tested include Winbase.h and Windows.h |
|||
11 Sep 2006, 14:17 |
|
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. |
|||
12 Sep 2006, 13:51 |
|
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. |
|||
12 Sep 2006, 14:11 |
|
Rookie 12 Sep 2006, 15:27
My intentions? I come in peace, I assure you.
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. _________________ This is who I choose to be. |
|||
12 Sep 2006, 15:27 |
|
HyperVista 12 Sep 2006, 15:39
Awesome article Rookie!! Thanks for the link. (your intentions are more clear ... and what i suspected )
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 ... |
|||
12 Sep 2006, 15:39 |
|
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
|
|||
13 Sep 2006, 06:36 |
|
Rookie 13 Sep 2006, 11:06
I don't understand what you mean
|
|||
13 Sep 2006, 11:06 |
|
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
|
|||
13 Sep 2006, 11:08 |
|
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).
|
|||
13 Sep 2006, 11:55 |
|
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". |
|||
14 Sep 2006, 06:17 |
|
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. |
|||
14 Sep 2006, 14:04 |
|
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 |
|||
22 Sep 2006, 18:11 |
|
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. _________________ This is who I choose to be. |
|||
28 Sep 2006, 15:50 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.