News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

LoadLibrary, GetProcAddress, FreeLibrary

Started by dedndave, November 06, 2015, 05:20:09 AM

Previous topic - Next topic

dedndave

i have a question - can't find the answer in any MSDN document....

1) LoadLibrary
2) GetProcAddress
3) FreeLibrary

is the proc address still valid after FreeLibrary ?
same question - assuming the reference count is not 0
how would i test the answer, either way ?

jj2007

Good question. A quick test shows that msvcrt works even after FreeLibrary.

ragdog

QuoteGood question. A quick test shows that msvcrt works even after FreeLibrary.

I understand it the handle is not longer valid.

QuoteWhen the reference count reaches zero, the module is unloaded from the address space of the calling process and the handle is no longer valid

I have make a quick test and Jochen has right .




zedd151

It would'nt be very hard to write a small proggy to test whether or not
the handle would still be valid.

BUT you must make certain that no OTHER process (in
the same context as your proggy) is using that handle.

If you try to free the handle while another process is using it, it might not get freed?

That is if I understood my lessons.

Or I could be completely wrong. (Would'nt be the 1st time - lol)

ragdog

My test was wrong my second works with FreeLibrary the module after FreeLibrary is unload
and this secound call does not works.


push chr$ ("printf")
call ebx



invoke LoadLibrary,chr$ ("msvcrt.dll")
mov edi,eax
invoke GetProcAddress,eax,chr$ ("printf")
mov ebx,eax
push chr$ ("printf")
call eax
invoke FreeLibrary,edi
push chr$ ("printf")
call ebx


@ Jochen have you forgot to delete the include msvcrt?

TWell

I test msvcrt.dll and wprintf.

After FreeLibrary() function pointer was not valid anymore (crash).
Debugger shows that module unloading.

But maybe useful for undocumented API functions.

dedndave

Quote from: zedd151 on November 06, 2015, 07:34:47 AM
BUT you must make certain that no OTHER process (in
the same context as your proggy) is using that handle.

the handle is unique to the current process
(the module is loaded into the address space of the current process)

the real question is.....

how do you clear out the address space used by the module to make the test   :biggrin:

hutch--

Dave, it depends on if the library is normally loaded into memory. If its one of the main system libraries, KERNEL, USER, GDI then you can usually get away with it but with individual DLLs it would be unreliable as they would be dumped from memory in lazy write time scales.

dedndave

this takes us to the next step....

back in the old forum, we had a discussion about using LoadLibrary vs GetModuleHandle for kernel32.dll
Hutch insisted that we should use LoadLibrary and FreeLibrary
my argument was that kernel32 is always loaded (functions like ExitProcess, etc)

now, we need to know if ExitProcess clears the reference counter - lol

in other words, if i use LoadLibrary to get functions from kernel32
and - don't use FreeLibrary, in order to insure the proc addresses remain valid
will ExitProcess perform a proper clean-up, or do i have a memory leak ?

hutch--

With the system libraries you can LoadLibrary(), GetProcAddress() then immediately call FreeLibrary() which is safe as the system library is still in memory, GetModuleHandle will do it as well without changing the reference counter but an old warning still applies, when Microsoft upgrade OS versions they only have their own documentation as reference so you may get a nasty surprise if you call a function address this way in a later OS version or after an upgrade. (Having been bitten a number of times with this problem, I err on the side of caution).  :biggrin:

nidud

#10
deleted

hutch--

Like this.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    .data?
      pMessageBox dd ?

    .data
      titl db "Msgbox Call",0
      tmsg db "Howdy from the MessageBox address",0

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main

    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc


    LOCAL pUser :DWORD

    fn LoadLibrary,"user32.dll"
    mov pUser, eax

    fn GetProcAddress,pUser,"MessageBoxA"
    mov pMessageBox, eax

    fn FreeLibrary, pUser

    push 0
    push OFFSET titl
    push OFFSET tmsg
    push 0
    call pMessageBox

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start

Zen

Raymond Chen has a number of blog entries that are ALMOST relevant to this question,...:bgrin:
...Here's one of them that seems to answer your question: What is the point of FreeLibraryAndExitThread?
This one is even MORE OBTUSE: Why can't I use the linker to delay-load a function from kernel32?
...And, if you want to know everything about LoadLibrary, FreeLibrary that nobody realistically cares about: Why are DLLs unloaded in the "wrong" order?
Zen

nidud

#13
deleted

sinsi

Use FreeLibrary more than once to make sure the reference count is 0 and run hutch's code. The degugger gives me

<Unloaded_user32.dll>+0x6fd1e:
7669fd1e ??              ???